資料結構--線性表的鏈式儲存(3)
阿新 • • 發佈:2020-07-11
一、什麼是連結串列
線性表的鏈式儲存又稱之為單鏈表,他是通過記憶體中任意一塊區域來儲存資料元素的,為了讓每一塊的元素建立邏輯關係,我們把每一塊的資料儲存單元分為兩個部分,第一個部分為資料部分,第二個部分為指向下一個節點的指標,所以在插入和刪除的時候,連結串列不需要對元素大量的進行移動,只需修改指標即可。
二、連結串列的特點
1.解決了順序表在儲存資料時需要大量連續的空間,屬於非隨機儲存。
2.由於存在指標域,連結串列消耗的空間會比較大。
3.連結串列進行刪除和插入時候時間複雜度為O(1),因為只需修改指標的指向而已。
4.查詢時消耗比較大,需要從頭開始遍歷,時間複雜度為O(n)。
本人覺得順序表和連結串列是一個互補的出現,往往某些場合需要兩者結合才能完成。
三、單鏈表的頭插法和尾插法
頭插法時元素始終插入頭節點後面,比如說插入的元素為1,2,3,4,5,所以在輸出的時候為5,4,3,2,1
頭插法程式碼如下
LinkList InsertHead(LinkList L) { //頭插法 LinkNode *s; int n; scanf("%d", &n); while (n != -1) { //輸入為-1時表示終止輸入 s = (LinkNode*)malloc(sizeof(LinkNode)); s->data = n; s->next = L->next; L->next = s; scanf("%d", &n); } return L; }
尾插法在插入元素時候每次都在節點最後插入,所以元素的順序不會變。
尾插法程式碼如下
LinkList InsertTail(LinkList L) { //尾插法 int n; LinkNode *s; LinkNode *end = L; //尾指標 scanf("%d", &n); while (n != -1) { //輸入-1時退出 s = (LinkNode*)malloc(sizeof(LinkNode)); s->data = n; end->next = s; end = s; //end指向新的尾節點 scanf("%d", &n); } end->next = NULL; //尾節點指標置為空 return L; }
四、單鏈表的增、刪、改、查操作
linkList.h標頭檔案
#include<stdio.h> typedef int Status; /* Status是函式的型別,其值是函式結果狀-1為出現錯誤1為正常態程式碼,如OK等 */ typedef int Boolean; /* Boolean是布林型別,其值是TRUE或FALSE 其中1為TRUE 0為FALSE */ typedef int ElemType; /*ElemType是資料的型別,我們這裡用int型別表示*/ typedef struct { //定義單鏈表的節點型別 ElemType data; //資料 struct LinkNode *next; //指標域 }LinkNode, *LinkList; LinkList InitLinkList(LinkList L); //初始化單鏈表 int LengthLink(LinkList L);//返回單鏈表的長度 int LocateElemLink(LinkList L, ElemType e);//查詢元素e在表中的位置 ElemType GetElemLink(LinkList L, int i);//獲取表中第i個位置的元素,並返回 Status InsertLinkList(LinkList L, int i, ElemType e);//在表L中第i個位置插入元素e Status DeleteElemLink(LinkList L, int i, ElemType *e);//刪除表中第i個元素,並用e返回其值 void PrintLinkList(LinkList L);//輸出單鏈表的所有元素 Boolean IsEmptyLink(LinkList L);//判斷單鏈表是否為空 Status DestroyLinkList(LinkList L);//銷燬單鏈表,並釋放所佔用的空間
linkList.c函式檔案
#include<stdio.h> #include"linkList.h" LinkList InitLinkList(LinkList L) { //初始化單鏈表 LinkNode *s; s = (LinkList)malloc(sizeof(LinkNode)); s->next = NULL; L = s; return L; } Status InsertLinkList(LinkList L, int i, ElemType e) { //在表L中第i個位置插入元素e,頭插法 LinkList p = L; int j = 0; while (j < i-1) { p = p->next; j++; } LinkNode *newNode = (LinkNode*)malloc(sizeof(LinkNode)); newNode->data = e; newNode->next = p->next; //新節點指向原來位置節點的下一個 p->next = newNode; //原來位置節點指向新節點 return 1; } void PrintLinkList(LinkList L) { //輸出單鏈表的所有元素 LinkList p = L; p = p->next; if (p == NULL) printf("連結串列為空"); else { while (p != NULL) { printf(" %d ", p->data); p = p->next; } } } int LengthLink(LinkList L) { //返回單鏈表的長度 int i = 0; LinkList p = L; p = p->next; while (p != NULL) { i++; p = p->next; } return i; } int LocateElemLink(LinkList L, ElemType e) { //查詢元素e在表中的位置 LinkList p = L; int i = 0; while (p->next != NULL) { p = p->next; if (p->data == e) return i + 1; i++; } return -1; } ElemType GetElemLink(LinkList L, int i) { //獲取表中第i個位置的元素,並返回 LinkList p = L; int j = 0; if (i <= 0 || i > LengthLink(L)) return NULL; while (p != NULL) { p = p->next; j++; if (j == i) return p->data; } } Status DeleteElemLink(LinkList L, int i, ElemType *e) { //刪除表中第i個元素,並用e返回其值 LinkList p = L; LinkNode *n; ElemType *temp; int j = 0; if (i <= 0 || i > LengthLink(L)) return -1; while (p != NULL) { if (j == i-1) { n = p->next; p->next = n->next; *e = n->data; free(n); return 1; } p = p->next; j++; } return 1; } Boolean IsEmptyLink(LinkList L) { //判斷單鏈表是否為空 if (L->next == NULL) return 1; else return 0; } Status DestroyLinkList(LinkList L) { //銷燬單鏈表,並釋放所佔用的空間 L->next = NULL; free(L); return 1; }
main.c主函式檔案
#include<stdio.h> #include"linkList.h" int main() { int i; int array[] = { 0,1,2,3,4,5 }; ElemType e; LinkList L = InitLinkList(&L); for (i = 1; i < 6; i++) { InsertLinkList(L, i, array[i]); } PrintLinkList(L); printf("\n"); printf("連結串列長度為%d\n",LengthLink(L)); printf("5在連結串列中第%d個位置\n", LocateElemLink(L, 5)); printf("第五個位置的元素為%d\n",GetElemLink(L, 5)); DeleteElemLink(L, 5, &e); printf("刪除第二個元素,刪除的元素為%d,列印刪除之後的表\n",e); PrintLinkList(L); printf("\n"); if (IsEmptyLink(L) == 1) printf("此表為空\n"); else printf("此表不為空\n"); printf("銷燬線性表"); if (DestroyLinkList(L) == 1) printf("銷燬成功!\n"); else printf("銷燬失敗"); }