給定乙個有序的迴圈鍊錶,在其中插入乙個值,保持該迴圈鍊錶依然有序。
首先看下迴圈鍊錶的結構,如下圖所示為乙個迴圈鍊錶,其尾結點指向頭結點,從而形成乙個迴圈。給定的鍊錶結點可以是鍊錶任意乙個結點,這個結點不一定是煉表頭結點,從而這也增加了該題的難度。
此時若是要在鍊錶中插入4,則插入後的鍊錶如下所示:
可以看到插入4後,鍊錶依然有序。
在解決這個問題前,先來看乙個簡化的問題,就是在乙個有序單鏈表中插入結點,仍然保證其有序。這個問題的**相信多數人都很熟悉,一般都是分兩種情況考慮:
1)如果原來鍊錶為空或者插入的結點值最小,則直接插入該結點並設定為頭結點。
2)如果原來鍊錶非空,則找到第乙個大於該結點值的結點,並插入到該結點的前面。如果插入的結點值最大,則插入在尾部。
**如下:
//鍊錶結點定義
struct node ;
typedef struct node node;
void sortedinsert3(struct node** headref, struct node* nd)
else
}
當然也可以把情況1和情況2放到一起考慮,**會更簡潔,如下所示:
void sortedinsert2(struct node** headref, struct node* nd)
nd->next = *current;
*current = nd;
}
上面**很簡潔,注意它是怎麼處理特殊情況的。
1)當鍊表為空或者插入的結點值最小時,則直接跳出迴圈,設定nd->next=null, *headref=nd.
2)其他情況,則current為待插入結點的位置,直接將其插入即可。包括插入到尾部或者任意常規的位置。
解決了乙個輕量級的問題之後再來看原題,該題目與上面不同的地方在於它是乙個迴圈鍊錶,那麼情況會有所不同,設待插入的結點值為x,則至少需要考慮下面三種情況:
1.prev->val ≤ x ≤ current->val:
插入到prev和current之間。
2. x是鍊錶中最小或者最大的值:
插入x到鍊錶頭部的前面。
3.回到起始點:
插入到起始點前面。
第1和2種情況還比較容易考慮到,但是第3種情況往往會被忽略,先給出**,再根據**來分析這些情況為什麼都需要考慮到。
void insert(node *& anode, int x)
node *p = anode;
node *prev = null;
do while (p != anode); // 情況3,回到起始結點,停止.
node *newnode = newnode(x);
newnode->next = p;
prev->next = newnode;
}
1)鍊錶只有乙個結點如果x等於該結點值,則直接在情況1處理。否則情況3處理。
2)鍊錶包含重複值
如果鍊錶為1-*1-1,起始結點為第二個1,則在其中插入2時,由情況3處理,即最終插入到初始結點前面。會變成1-2-1-1.迴圈鍊錶從第二個1開始,照樣是有序的。
迴圈有序鍊錶的插入
給定迴圈公升序列表中的乙個點,寫乙個函式向這個列表中插入乙個新元素,使這個列表仍然是迴圈公升序的。給定的可以是這個列表中任意乙個頂點的指標,並不一定是這個列表中最小元素的指標。如果有多個滿足條件的插入位置,你可以選擇任意乙個位置插入新的值,插入後整個列表仍然保持有序。如果列表為空 給定的節點是 nu...
在有序鍊錶中插入結點,仍保持其有序性
如果在乙個有序陣列中,你想插入乙個資料,還需要把其後所有元素往後移一位。那麼有沒有乙個比較好的資料結構可以實現簡單便捷的插入操作呢?那就是鍊錶,鍊錶由兩個部分組成,前面的部分為資料部分,用來儲存資料,後面的部分為指標部分,用來指向下乙個結點,鍊錶的資料結構就很好地解決了插入麻煩的問題。本文只介紹尾插...
有序鍊錶的插入
已知乙個遞增有序鍊錶l 帶頭結點,元素為整數 編寫程式將乙個新整數插入到l中,並保持l的有序 輸入 輸入分三行 第一行 元素個數 第二行 元素的值,元素間用空格分隔。第三行 待插入的元素值 輸出 開頭有空格 code include include include 函式狀態碼定義 define tr...