任務描述
本關要求按照數據輸入,通過按升序插入節點的方法,構建一個升序線性表。即如果輸入的3
個結點數據分別為2
、3
、1
,則構建的線性表包含3
個結點,且從前往后的結點數據分別為1
、2
、3
。
編程要求
本關的編程任務是補全step3/insertSort.h
文件中的insertSort
函數,以實現按升序排序方式構建線性表的要求。具體要求如下:
insertSort函數的實現可以分為兩個步驟:
- 一是找到插入點;
- 二是插入結點。
(1)如何找到插入點 插入點的定位可以使用兩個指針(p
和q
),定位步驟如下圖所示:
上圖中鏈表有4
個結點,則共有5
個可能的插入點。用兩個指針首先定位第一個插入點(step1
,p
為NULL
,q
指向第一個結點),如果插入結點的data
小於q
指向結點的data
,則就是該插入點(兩個指針指向的結點之間),否則兩個指針一起往后移動(step2
);定位第二個插入點,判斷條件依然是插入結點的data
是否小於q
指向的結點的data
,是則就是該插入點,否則兩個指針往后平移(step3
);定位第三個插入點……直到最后當q
指針為NULL
時,說明插入結點的data
比鏈表中所有數據都大,則插入點應該是鏈尾(第5
個插入點)。插入點的定位操作可以很容易地用循環實現。
定位好插入點后,當p
為NULL
時,插入點是鏈表頭部;當q
為NULL
時,插入點是鏈表尾部;否則,插入點為p
和q
指向的兩個結點之間。
(2)如何插入結點 上述定位好插入點后,接下來是插入結點。對於頭部插入和尾部插入的內容前兩關已做過介紹,本關只介紹中間插入的情況,即將t
指向的結點插入到p
和q
指向的兩個結點之間。這種情況只需要讓p
指向結點的指針域指向t
指向的結點,t
指向結點的指針域指向q
指向的結點即可。具體參見下面代碼:
p->next = t;
t->next = q;
評測說明
本關中包含三個文件分別是: step3/insertSort.h :此文件為學員文件,包含向鏈表升序插入元素函數實現。 step3/linkList.h:此文件包含鏈表常見操作的說明與實現,引用了insertSort.h step3/test.cpp:此文件為評測文件(含main函數),引用“linkList.h”。 (上述三個文件可通過點擊在代碼取的右上角文件夾中的step3文件夾中查看) (注意:本關所實現鏈式線性表為帶頭結點的單鏈表)
輸入輸出說明
輸入n(1<=n<=100),再輸入n個整數,按所輸入整數的升序順序輸出這n個整數,如下所示:(注意:鏈表的輸出函數已經實現,詳情請閱讀step3文件夾中的文件。) 測試輸入: 5
6 5 7 4 8
預期輸出: List: 4 5 6 7 8
測試輸入: 7
9 8 7 2 3 4 0
預期輸出: List: 0 2 3 4 7 8 9
insertSort.h
// 函數insertSort:鏈表升序插入 // 參數:h-鏈表頭指針,t-指向要插入的結點 // 返回值:插入結點后鏈表的首結點地址 node* insertSort(struct node* h, struct node* t) { // 請在此添加代碼,補全函數insertSort /********** Begin *********/ struct node* current; if(h == NULL || h->data>=t->data){ t->next = h; h= t; } else{ current=h; while (current->next!=NULL && current->next->data < t->data) { current = current->next; } t->next = current->next; current->next = t; } return h; /********** End **********/ }
linkList.h
#include <iostream> using namespace std; // 定義結點結構 struct node { int data; // 數據域 node* next; // 指針域,指向下一個結點 }; // 函數insertSort:鏈表升序插入 // 參數:h-鏈表頭指針,t-指向要插入的結點 // 返回值:插入結點后鏈表的首結點地址 node* insertSort(node* h, node* t); // 函數printList:輸出鏈表,每個數據之間用一個空格隔開 // 參數:h-鏈表頭指針 void printList(node* h); // 函數delList:刪除鏈表,釋放空間 // 參數:h-鏈表頭指針 void delList(node* h); #include"insertSort.h" //包含node* insertHead(node* h, node* t)函數的實現 void delList(node* h) { node* p = h; //指針p指向頭結點,第一個要刪除的結點 while (p) //這個結點是存在的 { h = h->next; //頭指針h指向下一個結點(下一個結點的地址存在當前結點的指針域中,即h->next中 delete p; //刪除p指向的結點 p = h; //p指向當前的頭結點,即下一個要刪除的結點 } } //函數printList:輸出鏈表,每個數據之間用一個空格隔開 //參數:h-鏈表頭指針 void printList(node* h) { cout << "List:"; if (h->next != NULL) h = h->next; while (h) {// h為真,即h指向的結點存在,則輸出該結點的數據 cout << " " << h->data; // 輸出結點數據 h = h->next; // 將該結點的指針域賦值給h,h就指向了下一個結點 } cout << endl; // 輸出換行符 }
test.cpp
#include "linkList.h" int main() { int n, i; node* t; node* head = new node;// 帶頭結點單鏈表,頭結點指針head head->next = NULL; // 頭結點head->next==NULL,鏈表為空 //輸入結點數 cin >> n; for (i = 0; i < n; i++) { //為新節點動態分配空間 t = new node; cin >> t->data; //輸入結點數據 t->next = NULL; //結點指針域值為空 //調用函數插入結點到鏈表頭部 head = insertSort(head, t); } //輸出鏈表 printList(head); //刪除結點,釋放空間 delList(head); return 0; }