1 / 31

鏈結串列 (Linked List)

鏈結串列 (Linked List). 指 標. 在指標類型中,兩種重要的運算子: &amp; : 位 址運算子,用來取得變數的記憶體位址。 * : 取值運算子,用來取得指標所指向變數的內容 null 指標代表此指標不指向任何物件或函數 可用 0 來表示 null 指標。. 例如: if (pi == NULL) printf(“It’s a empty pointer<br>”); 可寫成 if (!pi)

rae
Download Presentation

鏈結串列 (Linked List)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 鏈結串列(Linked List)

  2. 指 標 • 在指標類型中,兩種重要的運算子: • & :位址運算子,用來取得變數的記憶體位址。 • * :取值運算子,用來取得指標所指向變數的內容 • null 指標代表此指標不指向任何物件或函數 • 可用 0來表示null指標。 例如: if (pi == NULL) printf(“It’s a empty pointer\n”); 可寫成 if (!pi) printf(“It’s a empty pointer\n”); /* pi=0(false),!pi=1(true),所以執行printf */

  3. 動態記憶體配置---malloc函數 • 動態記憶體配置指的是在執行階段才向作業系統要求配置記憶體空間。 • 在C語言中,每次呼叫 malloc()函數,就會取得一塊可用的記憶體空間。 • malloc函數配置失敗時會傳回一個空指標。 • 用法: fp = (資料型態*) malloc(sizeof(資料型態)); 算出所需的記憶體空間大小 型別轉換,將malloc函數傳回的 指標轉成符合配置的資料型態 fp = (float*)malloc(sizeof(float)); 配置一塊 float 的記憶體空間,指標 fp 指向此空間

  4. 動態記憶體配置---malloc函數 • 範例: #include<stdio.h> int main() { float *fp; fp=(float *)malloc(sizeof(float)); if(fp!=NULL) { *fp=3.14; printf(“數字=%f\n”,*fp); } else printf(“記憶體配置失敗!\n”); }

  5. 動態記憶體配置---free函數 • free函數可將已配置的記憶體空間歸還。 • 用法: • 範例: free(fp); int main() { float *fp; fp=(float *)malloc(sizeof(float)); if(fp==NULL) printf(“記憶體配置失敗\n”); free(fp); }

  6. ptr bat ‧ sat NULL vat ‧ cat ‧ Link Data 單向鏈結串列 • 單向鏈結串列是由節點(node)所串成的串列,如下圖所示。 • 指向第ㄧ個節點的指標名稱(ptr)為此鏈結串列的名稱。 • 在單向鏈結串列中每個節點都包含兩個欄位: • 資料欄位:存放資料的地方 • 鏈結欄位:指向下一個 node 單向鏈結串列的節點結構

  7. data link ptr 單向鏈結串列 • 可使用自我參考結構(self-referential structure)來定義節點結構,如下: typedef struct node { int data; structnode *link; } nodes; nodes *ptr; 定義節點結構 ptr為node結構的指標 • 可使用malloc函數來建立新節點,如下: 為指標,指向另ㄧ個node結構 ptr=(nodes *)malloc(sizeof(nodes)); 配置一塊記憶體空間

  8. data link ptr 練習 #include<stdio.h> int main() { typedef struct node { int data; struct node *link; }nodes; nodes *ptr; ptr =(nodes *)malloc(sizeof(nodes)); ptr->data=10; ptr->link=NULL; printf("第一個數= %d\n",ptr->data); } 10 null

  9. data link data link ptr first 練習2 #include<stdio.h> int main() { typedef struct node { int data; struct node *link; }nodes; nodes *ptr, *first; ptr =(nodes *)malloc(sizeof(nodes)); first =(nodes *)malloc(sizeof(nodes)); ptr->data=10; ptr->link=NULL; first->data=20; first->link=NULL; printf("第一個數= %d\n",ptr->data); printf(“第二個數= %d\n",first->data); } 10 null 20 null

  10. data link data link ptr 單向鏈結串列 • 程式範例: #include<stdio.h> int main() { typedef struct node { int data; struct node *link; }nodes; nodes *ptr, *first; ptr =(nodes *)malloc(sizeof(nodes)); first = (nodes *)malloc(sizeof(nodes)); ptr->data=10; first->data=20; ptr->link=first; printf("第一個數= %d\n",ptr->data); printf("第二個數= %d\n",ptr->link->data); } first 20 10

  11. ptr 單向鏈結串列-加入串列前端 • 加入於串列的前端 NULL x • typedef struct node { • int data; • struct node *link; • }nodes; • nodes *x; • 步驟如下: • (1)x=(nodes *) malloc (sizeof(nodes));/*配置記憶體空間*/ • (2)x→link=ptr;/*將x節點的point指到剛head的地方*/ • (3)ptr=x;/*head換指到x節點(前端變成x節點)*/

  12. data link data link data link data link data link ptr ptr x 練習3-加入節點於串列前端 • 請將下方(1)鏈結串列,改成(2)鏈結串列。 first (1) (2) 20 10 first 20 10 5

  13. x next null 單向鏈結串列-加入串列尾端 • 加入於串列的尾端 head NULL 步驟如下: (1)x=(nodes *) malloc (sizeof(nodes)); x->link=NULL; (2)next=head while(next->link!=NULL) next=next->link; next->link=x;

  14. data link data link data link data link data link data link data link ptr ptr 練習4-加入節點於串列尾端 • 請將下方(1)鏈結串列,改成(2)鏈結串列。 (1) (2) 20 10 5 y 20 30 10 5

  15. x 單向鏈結串列-加入某一節點之後 • 加入在串列某一特定節點(add節點)的後面 add ptr NULL 步驟如下: (1)x=(nodes *) malloc (sizeof(nodes)); (2)x→link=add→link; (3)add→link=x;

  16. ptr ptr temp 單向鏈結串列-刪除串列前端 • 刪除串列前端的節點 NULL 步驟如下: (1)temp=ptr; (2)ptr=ptr->link; (3)free(temp);

  17. data link data link data link data link data link data link data link ptr ptr 練習5-刪除前端節點 • 請將下方(1)鏈結串列,改成(2)鏈結串列。 (1) (2) 20 30 10 5 20 30 10

  18. prev temp 單向鏈結串列-刪除串列最後節點 • 刪除串列的最後節點 ptr NULL NULL 步驟如下: (1) temp=ptr; while(temp->link!=NULL) { prev=temp; temp=temp->link; } (2) prev->link=NULL; (3) free(temp);

  19. this 單向鏈結串列-刪除某一節點 • 刪除某一特定的節點 prev ptr NULL 步驟如下: (1)必須先用兩個指標this和prev,分別指到即將被刪除節點及前一節點。 (2)prev->link=this->link; (3) free(this);

  20. 計算單向鏈結串列之長度 int length (struct node *ptr ) { struct node *this; this=ptr; int leng=0; while (this != NULL) { leng ++; this=this->link; } return leng ; }  串列長度指的是此串列共有多少個節點,只要指標指到的節點非NULL,則利用一變數做累加,直到指標到NULL為止。

  21. 二、環狀串列 • 定義:將單向鏈結串列最後一個node的指標指回第一個node。 • 特色:不論從哪一節點開始尋找,都能夠經過串列中所有節點。

  22. DATA RLINk LLINK 三、雙向鏈結串列 1.每個節點皆有三個欄位,一為左鏈結(LLINK),二為資料(DATA),三為右鏈結(RLINK),其中LLINK指向前一個節點,而RLINK指向後一個節點。 2.通常在雙向鏈結串列中會加上一個串列首。 此串列首的資料欄不存任何資料。 串列首

  23. 雙向鏈結串列的優缺點 優點: • 加入/刪除任何一個節點時,無需知道其前一節點的位址 • 可由任何一個節點立即找到前一個或後一個節點 • 從任何ㄧ個節點開始,必可經過串列中所有nodes 缺點: • 增加一個指標空間,需要更多記憶體 • 新加入ㄧ個節點時需改變四個指標,而單向鏈節串列只需改變兩個指標 • 刪除時需改變兩個指標,而單向只要改變一個指標

  24. LINK COEF EXP 23 3 四、多項式的表示 利用鏈結串列來表示多項式: Ex: 用鏈結串列來表示 , • 其中COEF表示變數的係數 • EXP表示變數的指數 • LINK為指到下一節點的指標 11 12 0 1 NULL

  25. 多項式的相加 • 假設兩個多項式 與 相加 • 以單向鏈結串列方式呈現,C語言片段程式如下: void poly_add(struct poly *eql, struct poly *eq2, struct poly *ans_h, struct poly *ptr) { struct poly *thisl, *this2, *prev; this1 = eq1; this2 = eq2; prev = NULL; while(this1 != NULL || this2 != NULL) { ptr = (struct poly*) malloc(sizeof(struct poly)); ptr ->link = NULL;

  26. if (this1 != NULL && (this2 = = NULL | | this1->exp > this2 ->exp)) { ptr->coef = this1->coef; ptr->exp = this1->exp; this1 = this1->next; } else if (this1 == NULL || this1->exp < this2 ->exp) { ptr->coef = this2->coef; ptr->exp = this2->exp; this2 = this2->link; } else { ptr->coef = this1->coef + this2->coef; ptr->exp = this1->exp; if (this1 != NULL) this1 = this1->link; if (this1 != NULL) this2 = this2->link; } 第ㄧ個多項式指數大於第二個多項式 第ㄧ個多項式指數小於第二個多項式 兩個多項式指數相等,進行相加

  27. if (ptr->coef != 0) { if (ans_h = = NULL) ans_h = ptr; else prev -> link = ptr; prev = ptr; } else free (ptr); } }

  28. 五、使用鏈結串列製作堆疊 堆疊加入演算法 void push(int num , nodes *ptr , nodes *top) { ptr = (nodes *)malloc(sizeof(nodes)); ptr->data=num; ptr->link=top; top=ptr; } 加入一個節點於堆疊中,由於堆疊的運作都在同一端,因此可將它視為將節點加入於串列的前端。 ptr top num null

  29. top 刪除資料的演算法 void pop(int num , nodes *top) { nodes *clear; if(top==NULL) { printf(“stack is empty”); return; } clear=top; num=top->data; top=top->link; free(clear); } 刪除堆疊頂端的頂點:其運作類似刪除串列的前端節點。 top clear

  30. rear 六、使用鏈結串列製作佇列 佇列的加入 void AddQ(int num , nodes *front , nodes *rear) { nodes *ptr; ptr = (nodes *)malloc(sizeof(nodes)); ptr->data=num; ptr->next=NULL; if(rear==NULL) front=rear=ptr; else { rear->link=ptr; rear=ptr; } } front ptr null num null rear

  31. clear front rear 六、使用鏈結串列製作佇列 佇列的刪除 void DeleteQ(int num , nodes *front) { nodes *clear; if (front==NULL) { printf(“queue empty”); return; } num=front->data; clear=front; front=front->link; free(clear); } null

More Related