在C語言中實現鏈表的逆序,使用哨兵頭節點是一種常見的做法。哨兵頭節點可以簡化代碼邏輯,特別是當鏈表為空時,可以避免空指針異常。下面是一個使用哨兵頭節點逆序單鏈表的C語言實現
示例:
#include <stdio.h>
#include <stdlib.h>// 定義鏈表節點結構體
typedef struct ListNode {int val;struct ListNode *next;
} ListNode;// 創建新節點
ListNode* createNode(int value) {ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (!newNode) {exit(-1); // 分配內存失敗,退出程序}newNode->val = value;newNode->next = NULL;return newNode;
}// 逆序鏈表,使用哨兵頭節點
void reverseList(ListNode** headRef) {ListNode* prev = NULL;ListNode* current = *headRef;ListNode* next = NULL;while (current != NULL) {next = current->next; // 保存下一個節點current->next = prev; // 當前節點指向前一個節點,實現逆序prev = current; // 前一個節點移動到當前節點current = next; // 當前節點移動到下一個節點}*headRef = prev; // 更新頭節點
}// 打印鏈表
void printList(ListNode* head) {ListNode* temp = head;while (temp != NULL) {printf("%d ", temp->val);temp = temp->next;}printf("\n");
}// 主函數,測試逆序鏈表功能
int main() {ListNode* head = createNode(1);head->next = createNode(2);head->next->next = createNode(3);head->next->next->next = createNode(4);printf("原始鏈表:");printList(head);reverseList(&head);printf("逆序后鏈表:");printList(head);// 釋放鏈表內存ListNode* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}return 0;
}
在這個代碼中,我們首先定義了鏈表節點的結構體ListNode
,然后提供了創建新節點的函數createNode
。reverseList
函數用來逆序鏈表,它使用了一個哨兵頭節點,即第一個節點作為prev指針的初始位置,最后將頭節點更新為prev指針所指向的節點。printList
函數用來打印鏈表的節點值。
在main
函數中,我們創建了一個簡單的鏈表,并調用reverseList
函數進行逆序,然后打印出逆序后的結果。最后,我們釋放了鏈表占用的內存。
請注意,在實際的項目開發中,還需要對代碼進行適當的錯誤處理和邊界條件檢查,以確保程序的健壯性。
在C語言中,使用哨兵位頭節點(dummy head)來逆序鏈表是一種常見的技巧,因為它可以簡化邊界條件的處理。以下是一個使用哨兵位頭節點逆序單鏈表的示例代碼:
// 鏈表節點的結構體定義
typedef struct ListNode {int val;struct ListNode *next;
} ListNode;
// 創建一個新的鏈表節點
ListNode* createNode(int value) {ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (!newNode) {exit(-1); // 分配內存失敗,退出程序}newNode->val = value;newNode->next = NULL;return newNode;
}
// 在鏈表的末尾添加一個新節點
void appendNode(ListNode** headRef, int value) {ListNode* newNode = createNode(value);ListNode* temp = *headRef;if (temp == NULL) {*headRef = newNode;return;}while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}
// 逆序鏈表,使用哨兵位頭節點
void reverseList(ListNode** headRef) {ListNode* prev = NULL;ListNode* current = *headRef;ListNode* next = NULL;while (current != NULL) {next = current->next; // 保存下一個節點current->next = prev; // 當前節點指向前一個節點prev = current; // 前一個節點移動到當前節點current = next; // 當前節點移動到下一個節點}*headRef = prev; // 更新頭節點
}
// 打印鏈表
void printList(ListNode* head) {ListNode* temp = head;while (temp != NULL) {printf("%d ", temp->val);temp = temp->next;}printf("\n");
}
// 主函數,測試逆序鏈表功能
int main() {ListNode* head = NULL; // 哨兵位頭節點// 向鏈表中添加元素appendNode(&head, 1);appendNode(&head, 2);appendNode(&head, 3);appendNode(&head, 4);printf("原始鏈表:");printList(head);// 逆序鏈表reverseList(&head);printf("逆序后鏈表:");printList(head);// 釋放鏈表內存ListNode* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}return 0;
}
總代碼
#include <stdio.h>
#include <stdlib.h>// 鏈表節點的結構體定義
typedef struct ListNode {int val;struct ListNode *next;
} ListNode;// 創建一個新的鏈表節點
ListNode* createNode(int value) {ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (!newNode) {exit(-1); // 分配內存失敗,退出程序}newNode->val = value;newNode->next = NULL;return newNode;
}// 在鏈表的末尾添加一個新節點
void appendNode(ListNode** headRef, int value) {ListNode* newNode = createNode(value);ListNode* temp = *headRef;if (temp == NULL) {*headRef = newNode;return;}while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}// 逆序鏈表,使用哨兵位頭節點
void reverseList(ListNode** headRef) {ListNode* prev = NULL;ListNode* current = *headRef;ListNode* next = NULL;while (current != NULL) {next = current->next; // 保存下一個節點current->next = prev; // 當前節點指向前一個節點prev = current; // 前一個節點移動到當前節點current = next; // 當前節點移動到下一個節點}*headRef = prev; // 更新頭節點
}// 打印鏈表
void printList(ListNode* head) {ListNode* temp = head;while (temp != NULL) {printf("%d ", temp->val);temp = temp->next;}printf("\n");
}// 主函數,測試逆序鏈表功能
int main() {ListNode* head = NULL; // 哨兵位頭節點// 向鏈表中添加元素appendNode(&head, 1);appendNode(&head, 2);appendNode(&head, 3);appendNode(&head, 4);printf("原始鏈表:");printList(head);// 逆序鏈表reverseList(&head);printf("逆序后鏈表:");printList(head);// 釋放鏈表內存ListNode* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}return 0;
}
在這個代碼中,我們首先定義了鏈表節點的結構體ListNode
。然后,我們提供了創建新節點和向鏈表末尾添加新節點的函數createNode
和appendNode
。reverseList
函數用來逆序鏈表,它使用了一個哨兵頭節點prev
,并最終將頭節點更新為prev
指針所指向的節點。printList
函數用來打印鏈表的節點值。
在main
函數中,我們創建了一個鏈表,并調用reverseList
函數進行逆序,然后打印出逆序后的結果。最后,我們釋放了鏈表占用的內存。
請注意,在實際的項目開發中,還需要對代碼進行適當的錯誤處理和邊界條件檢查,以確保程序的健壯性。