1. 程式人生 > >單鏈表的基本操作實現

單鏈表的基本操作實現

turn lag 個數 信息 listt 帶頭結點 img 鏈表的基本操作 原因

1、寫這篇博文的原因 C語言有三個重要部分:流程控制、函數、指針。 對於指針,單單了解它的簡單運用是遠遠不夠的,最重要的是學習鏈表。所以這篇文章通過用C語言實現鏈表的一些基本操作和總結,希望對C語言的指針有更新的理解和認識。 2、單鏈表的定義

單鏈表是通過一組任意的存儲單元來存儲線性表中的數據元素,這些存儲單元可以是連續的也可以是不連續的。為了建立起數據元素之間的關系,對於每個數據元素除了存放元素自身的信息外,還必須有包含指向該元素直接後繼元素位置的信息,這兩部分信息組成一個節點,即每個節點都有至少包含兩個域,一個域存儲數據元素信息,稱為數據域,另一個域存儲直接後繼的地址,稱為指針域

typedef struct
ListNode { int data; ListNode *next; }ListNode;
當n 個元素的線性表通過每個節點的指針域連接像一條"鏈子",故形象稱之為鏈表 3、單鏈表的基本操作
  • 鏈表的初始化;
  • 鏈表的插入;
  • 鏈表的創建;
  • 鏈表節點的插入;
  • 鏈表節點的刪除;
  • 鏈表的銷毀;
  • 獲取鏈表的長度;
  • 鏈表的倒置;
  • 鏈表的遍歷;
4、單鏈表的基本操作的完整代碼實現 註:下面代碼實現的所有鏈表均是帶頭結點的鏈表,即頭指針的data為空,初始化時使頭指針->next = NULL,頭指針->data不做處理。 技術分享圖片 網上關於鏈表操作的博文帶頭結點和不帶頭結點的均有,沒有一個統一的標準,其實原理是一樣的,每個函數方法只要稍微修改就能實現響應的功能,看個人喜好,沒有差別。以下代碼帶VS2012編譯器中編譯通過。
#include <iostream>
using
namespace std; typedef struct ListNode { int data; ListNode *next; }ListNode; bool initList(ListNode **head); //初始化鏈表 void insertList(ListNode *head, int data); //尾插法插入函數 ListNode *createList(int *arr, int len); //創建鏈表 bool destroyList(ListNode **head); //摧毀鏈表 bool ListInserLocateNum(ListNode * head, int
i, int data); //在帶頭結點的單鏈表的第i個位置之前插入元素 bool ListDelete(ListNode *head, int i, int *data); //刪除第i個元素,並由data返回其值 int getListLength(ListNode *head); //獲取鏈表的長度 void reverseList(ListNode *head); //鏈表倒置 void ListTraverse(ListNode *head); //遍歷鏈表 //初始化鏈表 bool initList(ListNode **head) { *head = (ListNode *)malloc(sizeof(ListNode)); if(*head == NULL) { return false; } (*head)->next = NULL; return true; } //創建鏈表 ListNode *createList(int *arr, int len) { ListNode *p = NULL; bool flag = initList(&p); if(flag) { for(int i = 0; i < len; ++i) { insertList(p, arr[i]); } return p; } cout << "鏈表初始化失敗" << endl; return NULL; } //尾插法 void insertList(ListNode *head, int data) { ListNode *node = (ListNode *)malloc(sizeof(ListNode)); node->data = data; node->next = NULL; ListNode *p = head; while(p->next != NULL) { p = p->next; } p->next = node; } //摧毀鏈表 bool destroyList(ListNode **head) { ListNode *p; while(*head) { p = (*head)->next; free(*head); *head = p; } return 1; } //在帶頭結點的單鏈表的第i個位置之前插入元素 bool ListInserLocateNum(ListNode * head, int i, int data) { ListNode *p = head; int j = 0; //帶頭結點,故從0開始 while(p != NULL && j < i-1) { j++; p = p->next; } if(p == NULL || j >= i) return false; ListNode *node = (ListNode *)malloc(sizeof(ListNode)); node->data = data; node->next = p->next; p->next = node; return true; } //刪除第i個元素,並由data返回其值 bool ListDelete(ListNode *head, int i, int *data) { ListNode *p = head; int j = 0; while(p != NULL && j < i-1) { j++; p = p->next; } //該方法最多只能定位到最後一個節點 if(p->next == NULL || j > i-1) return false; ListNode *pNext = p->next; *data = pNext->data; p->next = pNext->next; free(pNext); return true; } //獲取鏈表的長度 int getListLength(ListNode *head) { ListNode *p = head->next; int i = 0; while(p != NULL) { i++; p = p->next; } return i; } //鏈表倒置 void reverseList(ListNode *head) { ListNode *p = head->next; ListNode *pReverse = NULL; while(p != NULL) { ListNode *pNext = p->next; p->next = pReverse; pReverse = p; p = pNext; } head->next = pReverse; } //遍歷鏈表 void ListTraverse(ListNode *head) { if(head == NULL) return; ListNode *p = head->next; while(p != NULL) { cout << p->data << ","; p = p->next; } } int main() { int arr[5] = {1, 2, 3, 4, 5}; int len = sizeof(arr) / sizeof(arr[0]); ListNode *node = createList(arr, len); ListTraverse(node); cout << endl; reverseList(node); ListTraverse(node); cout << endl; cout << "length:" << getListLength(node) << endl; int flag = ListInserLocateNum(node, 3, 6); if(flag) { ListTraverse(node); } else { cout << "第i個位置超出鏈表的長度"; } cout << endl; int deleteNum = 0; flag = ListDelete(node, 3, &deleteNum); if(flag) { ListTraverse(node); } else { cout << "你要刪除的節點已超出鏈表的長度"; } cout << endl; cout<< deleteNum << endl; flag = destroyList(&node); if(flag) { cout << "鏈表已銷毀" << endl; ListTraverse(node); } system("pause"); return 0; }

單鏈表的基本操作實現