前言 :
單向鏈結串列 (Single Linked List) 是串列中最常用的一種, 它就像是火車一般, 所有結點串成一列, 而且指標所指方向一樣. 也就是串列中每筆資料除了要儲存原本的資料外, 還必須儲存下一筆資料的儲存位址. 所以在程式語言中, 一個串列結點由兩個欄位組成, 即資料欄與鏈結欄. 至於串列的組成要件為結點 (Node) , 而且每一個節點不必儲存於連續的記憶體位址. 在 "單向鏈結串列" 中第一個節點是 "串列指標首" , 指向最後一個節點的鏈結欄位設為 NULL, 表示它是 "串列指標尾", 例如串列 A={a,b,c,d,x}, 其單向串列資料結構如下 :
單向鏈結串列的建立 :
考慮嘗試使用C++ 語言的鏈結串列處理學生的成績問題, 其中學生為一個含 座號, 姓名 與成績 欄位的資料結構, 因為鏈結串列中的節點不只記錄單一數值, 因此結點的資料欄實際可以為某一資料結構或類別, 而該資料列構或類別包含指標指向另一個相同類型的資料結構或類別而形成單向鏈結串列, 並使所有資料能夠被串在一起而形成一個串列結構. 根據以上要求可以建立結點資料型態宣告如下 :
* 學生類別 代碼 :
範例代碼 :
* Student.h 代碼 :
* ch03.h 代碼 :
* ch03.cpp 代碼 :
執行結果 :
結點刪除 :
在單向鏈結型態的資料結構中, 若要在鏈結中刪除一個節點, 依據所刪除結點位置會有三種不同的情形 :
1. 刪除節點在 head
2. 刪除節點在 middle
3. 刪除節點在 tail
範例代碼 :
* ch03.h 代碼 :
* ch03.cpp 代碼 :
執行結果 :
單向鏈結串列 (Single Linked List) 是串列中最常用的一種, 它就像是火車一般, 所有結點串成一列, 而且指標所指方向一樣. 也就是串列中每筆資料除了要儲存原本的資料外, 還必須儲存下一筆資料的儲存位址. 所以在程式語言中, 一個串列結點由兩個欄位組成, 即資料欄與鏈結欄. 至於串列的組成要件為結點 (Node) , 而且每一個節點不必儲存於連續的記憶體位址. 在 "單向鏈結串列" 中第一個節點是 "串列指標首" , 指向最後一個節點的鏈結欄位設為 NULL, 表示它是 "串列指標尾", 例如串列 A={a,b,c,d,x}, 其單向串列資料結構如下 :
單向鏈結串列的建立 :
考慮嘗試使用C++ 語言的鏈結串列處理學生的成績問題, 其中學生為一個含 座號, 姓名 與成績 欄位的資料結構, 因為鏈結串列中的節點不只記錄單一數值, 因此結點的資料欄實際可以為某一資料結構或類別, 而該資料列構或類別包含指標指向另一個相同類型的資料結構或類別而形成單向鏈結串列, 並使所有資料能夠被串在一起而形成一個串列結構. 根據以上要求可以建立結點資料型態宣告如下 :
* 學生類別 代碼 :
- class Student{
- public:
- int num; // 座號
- int score; // 成績
- char name[10]; //姓名
- Student* next; //指標, 指向下一個節點
- };
範例代碼 :
* Student.h 代碼 :
- #include "main.h"
- class Student{
- public:
- int num; // 座號
- int score; // 成績
- char name[10]; //姓名
- Student* next; //指標, 指向下一個節點
- };
- typedef Student node;
- typedef node *link;
- #include
- using namespace std;
- /*
- * As ch03_03.cpp
- * 單向鏈結串列範例
- */
- void singleDirectLinkedListExam();
- #include "ch03.h"
- #include "Student.h"
- void singleDirectLinkedListExam() {
- link newnode, ptr, delptr; //宣告三個串列結構指標
- cout << "請輸入 5 筆學生資料: " << endl;
- delptr = new node;
- if(!delptr) {
- cout << "[ Error!!配置記憶體失敗! ]" << endl;
- exit(1);
- }
- cout << "請輸入座號: ";
- cin >> delptr->num;
- cout << "請輸入姓名: ";
- cin >> delptr->name;
- cout << "請輸入成績: ";
- cin >> delptr->score;
- ptr = delptr; //保留串列首, 以ptr 為目前節點指標
- for(int i=1; i<5; i++) {
- newnode = new node;
- if(!newnode) {
- cout << "[ Error!!配置記憶體失敗! ]" << endl;
- exit(1);
- }
- cout << "請輸入座號: ";
- cin >> newnode->num;
- cout << "請輸入姓名: ";
- cin >> newnode->name;
- cout << "請輸入成績: ";
- cin >> newnode->score;
- ptr->next = newnode;
- newnode->next = NULL;
- ptr= ptr->next;
- }
- cout << "\n學 生 成 績" << endl;
- cout << "座號\t姓名\t成績\n=================================" << endl;
- ptr = delptr; // 讓 ptr 回到串列首
- while(ptr!=NULL) {
- cout << ptr->name << "\t" << ptr->name << "\t" << ptr->score << endl;
- delptr = ptr;
- ptr = ptr->next; //往後走訪串列
- delete delptr; //釋回記憶體空間
- }
- }
執行結果 :
結點刪除 :
在單向鏈結型態的資料結構中, 若要在鏈結中刪除一個節點, 依據所刪除結點位置會有三種不同的情形 :
1. 刪除節點在 head
2. 刪除節點在 middle
3. 刪除節點在 tail
範例代碼 :
* ch03.h 代碼 :
- #include
- #include
- #include
- using namespace std;
- /*
- * As ch03_04.cpp
- * 刪除單向鏈結結點範例
- */
- void singleDirectLinkedListDelExam();
- #include "ch03.h"
- #include "Student.h"
- /*
- * 刪除節點副程式
- */
- link _del_Ptr(link head, link ptr) {
- link top;
- if(ptr == head) { // [情形一] : 刪除點在串列首
- top = head->next ;
- cout << "刪除第 " <
name << " 號學生, 姓名: " << head->name << " 成功!" << endl; - delete head;
- } else {
- top = head;
- link prevPtr = head;
- link curPtr = head->next;
- while(curPtr) {
- if(curPtr == ptr) {
- cout << "刪除第 " <
num << " 號學生, 姓名: " << curPtr->name << " 成功!" << endl; - if(curPtr->next == NULL) { // [情形二] : 刪除點在串列尾
- prevPtr->next = NULL;
- delete curPtr;
- curPtr = NULL;
- } else { //[情形三] : 刪除結點在串列中
- prevPtr->next = curPtr->next;
- delete curPtr;
- curPtr = prevPtr->next;
- }
- } else {
- prevPtr = curPtr;
- curPtr = curPtr->next;
- }
- }
- }
- return top;
- }
- /*
- * 顯示鏈結串列內容
- */
- void _showStudentList(link head) {
- link ptr = head;
- cout << "座號\t姓名\t成績" << endl; // 列印串列內容
- cout << "======================" << endl;
- while(ptr!=NULL) {
- cout << ptr->num << "\t" << ptr->name << "\t" << ptr->score;
- cout << endl;
- ptr = ptr->next;
- }
- }
- void singleDirectLinkedListDelExam() {
- int findword=0, find, data[12][2];
- char namedata[12][10] = {{"Allen"},
- {"Moko"}, {"Lean"}, {"Melissa"}, {"Angel"}, {"Sabrina"},
- {"Joyce"}, {"Jasica"}, {"Hanson"}, {"Amy"}, {"Bob"},{"Jack"}};
- srand((unsigned)time(NULL)); // 以時間為亂數的種子
- cout << "座號\t成績\t座號\t成績\t座號\t成績\t座號\t成績" << endl;
- cout << "=============================================================" << endl;
- for(int i=0; i<12 ;i++) {
- data[i][0] = i+1;
- data[i][1] = rand() % 50 + 51;
- }
- for(int i=0; i<3; i++) {
- for(int j=0; j<4; j++)
- cout << "[" << data[i*4 +j][0] << "]\t[" << data[i*4 +j][1] << "]\t";
- cout << endl;
- }
- link newnode = NULL;
- link head;
- for(int i=0; i<12; i++) {
- if(newnode==NULL) {
- newnode = new node;
- head = newnode;
- for(int k=0;k<10;k++)
- newnode->name[k] = namedata[i][k];
- newnode->num = data[i][0];
- newnode->score = data[i][1];
- }else {
- newnode->next = new node;
- newnode->next->next = NULL;
- for(int k=0;k<10;k++)
- newnode->next->name[k] = namedata[i][k];
- newnode->next->num = data[i][0];
- newnode->next->score = data[i][1];
- newnode = newnode->next;
- }
- }
- while(1){
- cout << "請輸入要刪除的成績, 結束輸入-1: ";
- cin >> findword;
- if(findword == -1) {
- break;
- } else {
- link ptr = head;
- find = 0;
- while(ptr!=NULL) {
- if(ptr->score == findword) {
- link delPtr = ptr;
- ptr = ptr->next;
- head = _del_Ptr(head, delPtr);
- find++;
- continue;
- }
- ptr = ptr->next;
- }
- _showStudentList(head);
- }
- }
- }
執行結果 :
This message was edited 7 times. Last update was at 12/09/2010 00:28:20
沒有留言:
張貼留言