資料結構(c語言)——線性單鏈表基本操作
阿新 • • 發佈:2019-02-12
#include <stdio.h> #include <stdlib.h> typedef int Element; typedef char(*Status)[10]; #define ERROR "error" #define OK "ok"; // 定義一個線性單鏈表結構 typedef struct Node{ Element data; struct Node *next; }Node,*LinkedList; // 初始化一個線性單鏈表 LinkedList init(){ Node *l; l = (Node *)malloc(sizeof(Node)); l->next = NULL; return l; } // 建立一個線性單鏈表 void create(LinkedList l){ for(int i = 2; i < 5; i++){ LinkedList p; p = (LinkedList)malloc(sizeof(Node)); p->data = i; p->next = l->next; l->next = p; } } // 插入資料到線性單鏈表中(頭插法) void insertHead(LinkedList l,Element e){ LinkedList p; p = (LinkedList)malloc(sizeof(Node)); p->data = e; p->next = l->next; l->next = p; } // 插入資料到線性單鏈表中(尾插法) void insertTail(LinkedList L,Element e){ LinkedList p,r; //r始終指向終端結點,開始時指向頭結點 r = L; //就是將這個尾指標指向最後一個元素 while(r->next){ r = r->next; } //申請新的結點 p = (LinkedList)malloc(sizeof(Node)); p->data = e; // 將表尾終端節點的指標指向新節點 r->next = p; // 將當前的新節點定義為表尾終端節點 r = p; //表示當前連結串列結束 r->next = NULL; } // 從線性單鏈表中取出指定位置的資料(位置從0開始) Status LinkedListGet(LinkedList l,int i,Element *e){ LinkedList p = l->next; int j = 0; while(p&&j<i){ p = p->next; j++; } if(!p||j>i){ return ERROR; } *e = p->data; return OK; } // 線性單鏈表的指定位置插入資料 Status LinkedListInsert(LinkedList L,int index,Element e){ LinkedList pre,p; //pre為前驅結點 pre = L->next; int tempi = 1; while(pre&&tempi<index){ // 就是再尋找第i-1個節點 pre = pre->next; ++tempi; } if(!pre||tempi>index){ // 第index個節點不存在 return ERROR; } p = (LinkedList)malloc(sizeof(Node)); p->data = e; p->next = pre->next; pre->next = p; return OK; } // 刪除線性單鏈表的指定位置元素 Status LinkedListRemove(LinkedList L,int index,Element *e){ LinkedList pre,p; //pre為頭指標 pre = L->next; int tempi = 1; // 就是在尋找第i-1個節點 while(pre&&tempi<index){ pre = pre->next; ++tempi; } if(!(pre->next)||tempi>index){ // 第index個節點不存在 return ERROR; } p = pre->next; pre->next = p->next; *e = p->data; //將p的記憶體進行釋放 free(p); return OK; } // 查詢線性單鏈表的指定元素,存在則返回這個元素的地址(不是所在的位置哦),不存在返回NULL; Node * LinkedListIndexOf(LinkedList L,Element e){ LinkedList p; if(!L){ return ERROR; } p = L; while(p&&p->data!=e){ p = p->next; } return p; } // 清空線性表 Status LinkedListClear(LinkedList L){ LinkedList p,q; p = L->next; while(p){ q = p->next; free(p); p = q; } // 將頭節點的指標域置為空。 L->next = NULL; return OK; } // 打印出線性單鏈表的所有資料元素 void toString(LinkedList l){ printf("["); l = l->next; while(l){ printf("%d",l->data); l=l->next; if(l){ printf(","); } } printf("]\n"); } int main(){ LinkedList L = init(); create(L); //insertHead(L,5); insertTail(L,1); Element a = -1; // Element *a = &1;不要幹這麼傻逼的事情,常數的地址賦值給指標變數沒有任何意義,c語言不允許這麼做。 // Element *a = 1;表示*a所儲存的地址值為1。 // 指標是用來存放地址的!地址就是個常數!雖然這樣是能編譯通過的!(準確地說,只能賦值0,其他的都不合法)。 // 但是,這樣執行會出錯(段錯誤)的!因為指標本來是存放地址的,而你卻存放了一個常數(即一個不合法的地址), // 這樣就會使指標指向不確定的記憶體單元(非法訪問),從而出現錯誤! Element *intPoint=&a; // *intPoint=a;等同於:int *intPoint; *intPoint = a; // 這個指標都沒指向任何地址,也就不存在值,取也就會出錯 // 取出連結串列中第0個數據元素(下標從0開始) Status res = LinkedListGet(L,0,intPoint); printf("Get() res is :%s,element is %d\n",res,*intPoint); LinkedListInsert(L,2,5); res = LinkedListRemove(L,3,intPoint); printf("remove status :%s,remove Element is %d\n",res,*intPoint); Node *indexRes = LinkedListIndexOf(L,7); printf("..index Memory address :%d\n",indexRes); //LinkedListClear(L); toString(L); return 0; }
不足和錯誤之處還請多多指正,謝謝!