百度首页 | 百度空间
 
查看文章
 
单向链表的部分C语言实现
2008-06-23 12:35

在前一家公司的时候在写一个项目的时候要使用到链表,为了熟悉先写了个简单测试程序,后来项目停止后就没有继续了,先把那部分简单的代码放上来,找个空闲的时间写个使用链表的应用。只是不知道空闲的时间什么时候会找到。

/*****************************************************************************************
***
*** 单向链表部分
***
******************************************************************************************/
typedef struct SqListNode
{
int data;
struct SqListNode *next;
}SqListNode;

SqListNode *GetSqListNode(const int& item, SqListNode *nextPtr)
{
SqListNode * newNode;

//为新结点分配内存空间,然后将item和nextPtr返回
newNode = new SqListNode;
if (newNode == NULL)
{
   printf("Memory allocation failure!\n");
   exit(1);
}
else
{
   newNode->data = item;
   newNode->next = nextPtr;
}
return newNode;
}

void PrintSqList(SqListNode *head, int n)
{
//currPtr初始指向表头结点,用于遍历链表
SqListNode *currPtr = head;
//curr_i用于记录当前输出到第几个结点
int curr_i = 0;

//输出结点数据,直到链表结束
while (currPtr != NULL)
{
   //如果已经输出了n个结点数据,则输出换行符
   if (curr_i < n)
   {
    cout << currPtr->data << " ";
    curr_i++;
   }
   else
   {
    cout << currPtr->data << endl;
    curr_i = 0;
   }

   //使currPtr指向下一个结点
   currPtr = currPtr->next;
}
}

bool FindSqNode(SqListNode *head, int item, SqListNode *prevPtr)
{
//currPtr初始指向表头结点,从第一个结点开始遍历
SqListNode *currPtr = head;
prevPtr = NULL;

//通过循环遍历链表,直到表尾
while (currPtr != NULL)
{
   //将item与结点的数据比较,如果相等,则返回,否则继续处理下一个结点
   if (currPtr->data == item)
   {
    return true;
   }
   prevPtr = currPtr; //记录下当前结点的地址
   currPtr = currPtr->next;
}

return false; //找不到时返回false
}

void InsertSqFront(SqListNode **head, int item)
{
//建立新结点,使其指针域指向原链表头结点head,然后更新head
*head = GetSqListNode(item, *head);
}

void InsertSqRear(SqListNode **head, int item)
{
SqListNode *newNode = NULL;
SqListNode *currPtr = *head;

//如果链表为空,则插入在表头
if (currPtr == NULL)
{
   InsertSqFront(head, item);
}
else
{
   //寻找指针域为NULL的结点
   while (currPtr->next != NULL)
   {
    currPtr = currPtr->next;
   }

   //建立新结点并插入在表尾(在currPtr之后)
   newNode = GetSqListNode(item, NULL);
   newNode->next = NULL;   //将新建立的结点指针域置为NULL作为尾结点
   currPtr->next = newNode; //将建立新结点前的尾结点指针域指向新建立的结点
}
}

void InsertSqOrder(SqListNode **head, int item)
{
//currPtr用于遍历链表,prevPtr跟随其后
SqListNode *currPtr = NULL, *prevPtr = NULL, *newNode = NULL;

//prevPtr == NULL标志着应该插入在表头
prevPtr = NULL;
currPtr = *head;

//通过循环遍历链表,寻找插入点
while (currPtr != NULL)
{
   //如果item小于当前结点数据,则插入点应在当前结点之前
   if (item < currPtr->data)
    break;

   //currPtr前行,prevPtr跟随其后
   prevPtr = currPtr;
   currPtr = currPtr->next;
}

//完成插入
if (prevPtr == NULL) //判读插入点是否在表头
{
   InsertSqFront(head, item);
}
else
{
   //在precPtr指向的结点之后插入新结点
   newNode = GetSqListNode(item, NULL);
   prevPtr->next = newNode; //将currPtr的指针域指向新插入的结点
   newNode->next = currPtr; //将新建立的结点的指针域指向currPtr结点
}
}

void DeleteSqFront(SqListNode **head)
{
SqListNode *p = *head;   //用于取得将被删除结点的地址

if (head != NULL)
{
   *head = p->next; //将表头指针head移向第二个结点
   delete p;     //删除原第一个结点
}
}

void DeleteSqLast(SqListNode **head)
{
SqListNode *prevPtr = NULL;   //记录当前结点的前一个结点
SqListNode *currPtr = *head;

if (currPtr == NULL)   //如果链表为空则返回错误
{
   cout << "The List is empty!!" << endl;
}
else
{
   //寻找指针域为NULL的结点
   while (currPtr->next != NULL)
   {
    //currPtr前行,prevPtr跟随其后
    prevPtr = currPtr;
    currPtr = currPtr->next;
   }
   //完成删除最后的结点
   prevPtr->next = NULL;
   delete currPtr;
}
}

void Delete(SqListNode **head, int key)
{
//currPtr用于遍历链表,precPtr跟随其后
SqListNode *currPtr = *head;
SqListNode *prevPtr = NULL;

//如果链表为空,则返回
if (currPtr == NULL)
{
   return;
}

//通过循环遍历链表,直到找到数据域为key的结点或达到表尾
while (currPtr != NULL && currPtr->data != key)
{
   //currPtr前行,prevPtr跟随其后
   prevPtr = currPtr;
   currPtr = currPtr->next;
}

//若currPtr!=NULL,则currPtr指向的结点数据域为key
if (currPtr != NULL)
{
   if (prevPtr == NULL) //找到的是链表第一个结点
   {
    *head = currPtr->next;
   }
   else
   {
    //如果找到的是第二个以后的结点,进行如下处理删除。
    if (currPtr->next == NULL) //如果当前结点为尾结点,则需将prevPtr结点指针域置为NULL
    {
     prevPtr->next = NULL;
    }
    else
    {
     //使前趋结点prevPtr的指针域指向currPtr的后继结点。
     prevPtr->next = currPtr->next;
    }
   }

   //删除currPtr结点
   delete currPtr;
}
}

void ClearSqList(SqListNode **head)
{
SqListNode *currPtr, *nextPtr;

//边遍历边删除结点
currPtr = *head;
while (currPtr != NULL)
{
   //记录下一个结点的地址,删除当前结点
   nextPtr = currPtr->next;
   delete currPtr;
   currPtr = nextPtr; //使指针currPtr指向下一个结点
}

*head = NULL; //将头结点置为NULL,标志着链表为空
}

void SortSqList(SqListNode **head, bool mode)
{
//currPtr用于遍历链表
SqListNode *currPtr = *head;
SqListNode *tempPtr = NULL;

//如果链表为空,则返回
if (currPtr == NULL)
{
   return;
}

while (currPtr != NULL)
{
   InsertSqOrder(&tempPtr, currPtr->data);
   currPtr = currPtr->next;
}

*head = tempPtr;

}

//从给定的链表中找出第m个结点。规定当m=0时,返回链表的最后一个结点(尾结点)
SqListNode *FindMFromLastNode(SqListNode *head, int m)
{
SqListNode *curPos, *mBehind;
int i;

curPos = head;

//curPos指针前行到第m个结点时,mBehind指针赋值开始跟随,
//期间要注意判断链表不足m个结点的特殊情况的处理
for (i=0; i<m; i++)
{
   if (curPos->next)
   {
    curPos = curPos->next;
   }
   else
   {
    return NULL;
   }
}

//以上循环执行完后curPos指针已经前行了m个结点了,现在让mBehind指针赋值开始跟随
mBehind = head;
while (curPos->next)
{
   curPos = curPos->next;
   mBehind = mBehind->next;
}

return mBehind;
}


/*****************************************************************************************
***
*** 用单向链表实现堆栈功能部分
***
******************************************************************************************/
int CreateStack(SqListNode **stack)
{
*stack = NULL;
return 1;
}

int Push(SqListNode **stack, int data)
{
SqListNode *newNode;
newNode = (SqListNode *)malloc(sizeof(SqListNode));

if (!newNode)
{
   return 0;   //动态创建结点失败
}

newNode->data = data;
newNode->next = *stack;
*stack = newNode;   //将堆栈栈顶指针指向新建结点

return 1;
}

int Pop(SqListNode **stack, int *data)
{
SqListNode *elem;

//判断堆栈是否为空
if (!(elem = *stack))
{
   return 0;
}

*data = elem->data;
*stack = elem->next; //将栈顶指针指向下一个结点
free(elem);

return 1;
}

int DeleteStack(SqListNode **stack)
{
SqListNode *next;
while (*stack)
{
   next = (*stack)->next;
   free(*stack);
   *stack = next;
}

return 1;
}


类别:c c++ vc evc | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu