链表操作是程序设计中最常见的一类操作。在我们项目或面试中经常会用到,我们可以大致总结下链表操作的常见技巧。其实也没有什么难点,主要是操作列表时,注意异常边界值的考虑。一般在修改链表时,会用到辅助链表指针,其目的在我看来主要有2个作用:一是将当前结点保存起来,好让此时结点的指针指向下一结点(这里可以类似看做一个游标,向前或向后的结点移动。二是利用辅助链表指针的位置来实现特定的目的)。我们主要看到这里数据域则为该结点保存的值,而指针域可以看作一个游标,通过它来指向下一个结点(pList->next),也可以指向下一个结点的结点(pList->next->next),。。。。。。这样就可以遍历整个链表了。
下面是某一类常见的链表操作,代码都比较简练,熟悉了操作步骤,写这些代码应该是不难的!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct ListNode
{
int data; //---------------数据域
ListNode *next; //--------------指针域
};
unsigned int getListLength(ListNode *pList)
{
if (pList == NULL)
{
return 0;
}
unsigned len = 0;
ListNode *pCur = pList;
while (pCur != NULL)
{
len++;
pCur = pCur->next;
}
return len;
}
ListNode *createList(int n)
{
if (n <= 0)
{
return NULL;
}
ListNode *pCurrent = NULL;
ListNode *pHead = NULL;
for(int i = 0; i < n; i++)
{
pCurrent = (ListNode*)malloc(sizeof(struct ListNode));
pCurrent->data = i + 1;
pCurrent->next = pHead;
pHead = pCurrent;
}
return pHead;
}
void traverseList(ListNode *pList) //遍历链表
{
while (pList != NULL)
{
printf("%d\n", pList->data);
pList = pList->next;
}
}
void freeList(ListNode *pList)
{
while(pList != NULL)
{
ListNode *pTemp = pList;
pList = pList->next;
free(pTemp);
}
}
ListNode *reverseList(ListNode *pList)
{
if (pList == NULL || pList->next == NULL)
{
return pList;
}
ListNode *pHead = NULL;
ListNode *pCur = pList;
while (pCur != NULL)
{
ListNode *pTemp = pCur;
pCur = pCur->next;
pTemp->next = pHead;
pHead = pTemp;
}
return pHead;
}
ListNode *getRightKthNode(ListNode *pList, int k)
{
if (k <=0 || pList == NULL)
{
return NULL;
}
ListNode *pAhead = pList;
ListNode *pBehind = pList;
while (k > 1 && pAhead != NULL)
{
pAhead = pAhead->next;
k--;
}
if (k > 1 || pAhead == NULL)
{
return NULL;
}
while (pAhead->next != NULL)
{
pBehind = pBehind->next;
pAhead = pAhead->next;
}
return pBehind;
}
ListNode *getMiddleNode(ListNode *pList)
{
if (pList == NULL || pList->next == NULL)
{
return pList;
}
ListNode *pAhead = pList;
ListNode *pBehind = pList;
while (pAhead->next != NULL)
{
pBehind = pBehind->next;
pAhead = pAhead->next;
if (pAhead->next != NULL)
{
pAhead = pAhead->next;
}
}
return pBehind;
}
void reversePrintList(const ListNode *pList)
{
if (pList == NULL)
{
return;
}
else
{
reversePrintList(pList->next);
printf("%d\n", pList->data);
}
}
void reversePrintStr(const char *str)
{
if(*str == '\0')
{
return;
}
else
{
reversePrintStr(str+1);
printf("%c", *str);
}
}
int main()
{
ListNode *pList = NULL;
pList = createList(10);
printf("********reversePrintList***********\n");
reversePrintList(pList);
printf("********getListLength***********\n");
printf("%d\n", getListLength(pList));
printf("********traverseList***********\n");
traverseList(pList);
printf("********reverseList***********\n");
pList = reverseList(pList);
traverseList(pList);
printf("*********getRightKthNode**********\n");
ListNode *pHead = getRightKthNode(pList, 6);
printf("%d\n", pHead->data);
printf("********getMiddleNode***********\n");
pHead = getMiddleNode(pList);
printf("%d\n", pHead->data);
freeList(pList);
reversePrintStr("abcde");
return 0;
}
打印结果如下:
====================补充==========================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
int data; //数据域
struct node *next; //指针域
} SList;
SList * createList(int n) //创建单链表
{
SList *pHead = NULL;
for (int i = 0; i < n; i++)
{
SList *pNode = (SList*)malloc(sizeof(SList));
pNode->data = i + 1;
pNode->next = pHead;
pHead = pNode;
}
return pHead;
}
void printList(SList *pList) //遍历单链表
{
while(pList != NULL)
{
fprintf(stdout, "%d\n", pList->data);
pList = pList->next;
}
printf("******************\n");
}
SList *addNodeToTail(SList *pList, int data) //结点加入链表尾
{
SList *pHead = pList;
SList *pNode = (SList*)malloc(sizeof(SList));
pNode->data = data;
pNode->next = NULL;
if(pHead == NULL)
{
pHead = pNode;
return pHead;
}
while (pHead->next != NULL)
{
pHead = pHead->next;
}
pHead->next = pNode;
return pList;
}
SList *deleteNode(SList *pList, int data) //删除指定元素的值
{
if (pList == NULL)
{
return pList;
}
SList *pHead = pList;
SList *preHead = NULL;
while(pHead != NULL)
{
if (pHead->data == data)
{
SList *deNode = pHead;
pHead = pHead->next;
if (NULL != preHead)
{
preHead->next = pHead;
}
else
{
pList = pHead;
}
free(deNode);
}
else
{
preHead = pHead;
pHead = pHead->next;
}
}
return pList;
}
int main()
{
SList *pList = createList(5);
printList(pList);
pList = deleteNode(pList, 5);
printList(pList);
pList = addNodeToTail(pList, 1);
printList(pList);
pList = deleteNode(pList, 1);
printList(pList);
return 0;
}

本文介绍了链表的基本操作,包括创建、遍历、反转等,并提供了详细的C语言代码示例。同时,文章还探讨了如何获取链表的长度、中间节点及指定位置的节点等内容。
2277

被折叠的 条评论
为什么被折叠?



