鏈表的鏈接:
將第二條鏈表的所有內容鏈接到第一條鏈表之後, 其完整實現代碼與解析如下:
//鏈表的鏈接 templatevoid MyList ::concatenate(const MyList &list) { if (isEmpty())//如果自己的鏈表為空 { first = list.first; return ; } else if (list.isEmpty()) //如果第二條鏈表為空 { return ; } Node *endNode = first->next; //找到第一條鏈表的末尾節點 while (endNode->next != NULL) { endNode = endNode->next; } //找到第二條鏈表的第一個真實元素 Node *secondListNode = (list.first)->next; //注意: 需要將第二個鏈表中的元素值copy出來 //不能直接將第二條鏈表的表頭鏈接到第一條鏈表的表尾 //不然在析構函數回收內存時會發生錯誤(即:同一段內存釋放兩次) while (secondListNode != NULL) { Node *newNode = new Node (secondListNode->data); newNode->next = NULL; endNode->next = newNode; //兩條鏈表同時前進 endNode = endNode->next; secondListNode = secondListNode->next; } }
鏈表的反轉:
基本思想:
遍歷一遍鏈表,利用一個輔助指針(此處為指針r),存儲遍歷過程中當前指針指向的下一個元素,然後將當前節點元素的指針反轉後,利用已經存儲的指針往後面繼續遍歷。
//鏈表的反轉 templatevoid MyList ::invort() { if (!isEmpty()) { //p指向正向鏈表的第一個真實節點 //隨後, p也會沿正方向遍歷到鏈表末尾 Node *p = first->next; //q會成為倒向的第一個真實節點 //首先將q設置為NULL: 保證反向之後 //最後一個元素的指針域指向NULL, 以表示鏈表結束 Node *q = NULL; while (p != NULL) { Node *r = q; //暫存q當前指向的節點 //q後退(沿著正向後退) q = p; //p前進(沿著正向前進), 保證p能夠始終領先q一個位置 p = p -> next; //將指針逆向反轉 //注意:一點要保證這條語句在p指針移動之後運行, //不然p就走不了了...(因為q改變了指針的朝向) q -> next = r; } //此時q成為反向鏈表的第一個真實元素 //但是為了維護像以前一樣的first指針指向一個無用的節點(以使前面的操作不會出錯) //於是我們需要將first的指針域指向q first->next = q; } }
鏈表打印:
重載MyList的<<運算符, 輸出鏈表所有元素, 以供測試之用
//顯示鏈表中的所有數據(測試用) templateostream &operator<<(ostream &os, const MyList &list) { for (Node *searchNode = list.first -> next; searchNode != NULL; searchNode = searchNode -> next) { os << searchNode -> data; if (searchNode -> next != NULL) //尚未達到鏈表的結尾 cout << " -> "; } return os; }
附-測試代碼:
int main() { cout << "------------ 1 ------------" << endl; MyListfirst; for (int i = 0; i < 5; ++i) { first.insert(i+1, i+1); } first.remove(5); MyList second; for (int i = 0; i < 5; ++i) { second.insert(i+6, i+1); } second.insertFront(5); second.insert(88, 7); cout << "Before concatenate..." << endl; cout << "first: " << first << endl; cout << "second: " << second << endl; cout << "After concatenate..." << endl; first.concatenate(second); cout << "first: " << first << endl; cout << "second: " << second << endl; cout << "\n------------ 2 ------------" << endl; MyList chList; for (char ch = '0'; ch <= '9'; ++ ch) { chList.insertFront(ch); } cout << "Before invort..." << endl; cout << chList << endl; cout << "After invort..." << endl; chList.invort(); cout << chList << endl; cout << "After remove('5')..." << endl; chList.remove('5'); cout << chList << endl; cout << "\n------------ 3 ------------" << endl; MyList dList; dList.insert(1.1, 1); dList.insertFront(2.2); cout << dList << endl; return 0; }