數組對應著一個連續存儲的內存塊, 實際上還可以利用指針便量的指針把一系列的變量組織起來, 形成一種新的資料結構, 稱為鏈表.
鏈表元素稱為鏈表節點, 每個節點包含兩個區域: 數據域與指針域, 數據域負責儲存數據而指針域負責連接該節點到下一個節點. 可以看出節點數據是一種複合類型結構, 每一個節點占用一塊存儲單位, 如下是三個節點互相鏈結的示意圖 :
每個鏈表都有一個頭指針Head, 存放鏈表首結點的位置, 可以透過鏈表的首指針找到鏈表的的首結點. 要注意最終結點的指針域為NULL, 據此可判斷一個鏈表是否結束. 如果結點數為0, 我們稱為空表, 此時head指針為NULL.
創建鏈表範例代碼:
輸出結果:
Ps. 鏈表中的先後是邏輯上的關係, 不代表節點在內存的先後順序.
鏈表的結構相對比較特殊, 在鏈表中的節點進行訪問和查找時, 必須從鏈表的頭部結點開始, 並按照指針域所指順序查找, 直到找到為止. 而循環的中止條件就是判斷next的指針是否為NULL.
鏈表的遍歷與查找範例代碼:
鏈表結點插入範例:
Ps. 將結點插入鏈表頭或刪除首結點時, 要記得對head指針重新賦值.
鏈表結點刪除範例代碼:
鏈表元素稱為鏈表節點, 每個節點包含兩個區域: 數據域與指針域, 數據域負責儲存數據而指針域負責連接該節點到下一個節點. 可以看出節點數據是一種複合類型結構, 每一個節點占用一塊存儲單位, 如下是三個節點互相鏈結的示意圖 :
每個鏈表都有一個頭指針Head, 存放鏈表首結點的位置, 可以透過鏈表的首指針找到鏈表的的首結點. 要注意最終結點的指針域為NULL, 據此可判斷一個鏈表是否結束. 如果結點數為0, 我們稱為空表, 此時head指針為NULL.
創建鏈表範例代碼:
- struct student_link{
- char name[20];
- int age;
- student_link* next;
- };
- /*
- * @ 同質鏈表創建 (P107)
- * 鏈表創建有兩個步驟
- * 1. 在數據結構中增加一個指針next, 以便指向邏輯上的下一個節點
- * 2. 設置一個指向首節點的指針, 將最後節點的指針設為NULL
- */
- void example508(){
- student_link c = {"Kaka",23,NULL};
- student_link b = {"Deco",27,&c};
- student_link a = {"Terry",30,&b};
- student_link* head = &a;
- student_link* pointer = head;
- cout << "Head->";
- while(pointer){
- cout << pointer->name << ": " << pointer->age << "->";
- pointer = pointer->next;
- }
- cout << "End" << endl;
- }
輸出結果:
Ps. 鏈表中的先後是邏輯上的關係, 不代表節點在內存的先後順序.
鏈表的結構相對比較特殊, 在鏈表中的節點進行訪問和查找時, 必須從鏈表的頭部結點開始, 並按照指針域所指順序查找, 直到找到為止. 而循環的中止條件就是判斷next的指針是否為NULL.
鏈表的遍歷與查找範例代碼:
- struct student_link{
- char name[20];
- int age;
- student_link* next;
- };
- /*
- * @ 鏈表的遍尋與查找 (P108)
- */
- void example509(){
- student_link c = {"Kaka",23,NULL};
- student_link b = {"Deco",27,&c};
- student_link a = {"Terry",30,&b};
- student_link* head = &a;
- student_link* pointer = head;
- bool isFound = false;
- for(;pointer;pointer=pointer->next){
- if(strcmp("Deco",pointer->name)==0){
- cout << "Deco's age: " << pointer->age << endl;
- isFound = true;
- break;
- }
- }
- if(!isFound){
- cout << "沒有找到!" << endl;
- }
- }
鏈表結點插入範例:
- struct student_link{
- char name[20];
- int age;
- student_link* next;
- };
- /*
- * @ 鏈表節點的插入 (P110)
- */
- void example510(){
- student_link c = {"Kaka",30,NULL};
- student_link b = {"Deco",27,&c};
- student_link a = {"Terry",23,&b};
- student_link* head = &a;
- student_link* pointer = head;
- int age;
- cout << "請輸入link年齡: "<
- cin >> age;
- student_link link = {"Link",age,NULL};
- student_link* before=NULL;
- student_link* prev = NULL;
- int i=0;
- while(pointer){
- if(link.age>pointer->age){
- prev = pointer;
- pointer = pointer->next;
- i++;
- continue;
- }else{
- before = pointer;
- break;
- }
- }
- cout << "Rank: " << i << endl;
- if(before!=NULL){ //有人比我大
- cout << "有人比我大" << endl;
- link.next = before;
- if(!prev){
- head = &link;
- }else{
- prev->next = &link;
- }
- }else{ //沒人比我大
- cout << "沒人比我大" << endl;
- prev->next = &link;
- link.next = NULL;
- }
- student_link* cpointer = head;
- show_student_link(cpointer);
- }
Ps. 將結點插入鏈表頭或刪除首結點時, 要記得對head指針重新賦值.
鏈表結點刪除範例代碼:
- struct student_link{
- char name[20];
- int age;
- student_link* next;
- };
- /*
- * @ 鏈表節點的刪除 (P111)
- */
- void example511(){
- char deleteName[20];
- cout << "請輸入要刪除的節點姓名(Kaka,Deco 或 Terry): " << endl;
- cin >> deleteName;
- cout << "刪除: " << deleteName << "... " <
- student_link c = {"Kaka",30,NULL};
- student_link b = {"Deco",27,&c};
- student_link a = {"Terry",23,&b};
- student_link* head = &a;
- student_link* pointer = head;
- student_link* before = NULL;
- bool isFound = false;
- while(pointer){
- if(strcmp(deleteName,pointer->name)==0){
- isFound = true;
- break;
- }
- before = pointer;
- pointer = pointer->next;
- }
- if(isFound){
- if(before==NULL){
- cout << "Kill First!" << endl;
- head = pointer->next;
- }else{
- before->next = pointer->next;
- }
- }else{
- cout << "未找到!" <
- }
- student_link* cpointer = head;
- show_student_link(cpointer);
- }
This message was edited 2 times. Last update was at 05/02/2010 16:55:29
沒有留言:
張貼留言