鏈表操作是程序設計中最常見的一類操作。在我們項目或面試中經常會用到,我們可以大致總結下鏈表操作的常見技巧。其實也沒有什麼難點,主要是操作列表時,注意異常邊界值的考慮。一般在修改鏈表時,會用到輔助鏈表指針,其目的在我看來主要有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;
}