[英]C: Removing a node from singly-LinkedList1 and inserting it at the head of singly-LinkedList2
我正在做一個模擬操作系統進程調度程序的計算機科學項目。 我有多個單鏈表 ,需要在它們之間移動節點 。 我正在嘗試編寫一個通用函數來實現這一目標,但我認為使用指針的弱點正在阻礙我。
如何實現所需的功能? 到目前為止,我有以下內容:
typedef struct process_list_struct ProcessList;
struct process_list_struct
{
Process proc;
ProcessList* next;
};
void change_lists(ProcessList* node, ProcessList* newlist)
{
ProcessList* temp = NULL;
debug_printf("change_lists reached\n");
temp = node;
if(!node)
{
debug_printf("Error: change_lists failed!\n");
return;
}
node = node->next;
temp->next = newlist;
newlist = temp;
return;
}
其結果是奇怪......我最終只包含我想移動節點和其他一切失蹤(幾乎比我想要的東西相反的效果),以及newlist(如測試開始是空的)第一個列表為空。
我已經在單個列表中查找了節點交換的實現,並且看到人們使用雙指針 ,但這讓我感到困惑。 有人可以告訴我如何在這種情況下應用它們嗎? 我嘗試使用它們,但它們結合引用結構的指針元素真的令人困惑。
非常感謝幫助!
您將以下四個步驟錯誤地將節點從一個列表轉移到另一個列表:
temp = node
node = node->next;
temp->next = newlist;
newlist = temp;
見下圖我用圖表顯示:
假設您在鏈表列表1中有節點:
+---+----+----+ +----+----+----+ +---+----+----+
->| zero |----->| one |----->| two |--
+---+----+----+ +----+----+----+ +---+---+-----+
^ ^
| |
| node
after temp=node temp
之后: node = node->next;
事情變得像:
+---+----+----+ +----+----+----+ +---+----+----+
->| zero |----->| one |----->| two |--
+---+----+----+ +----+----+----+ +---+---+-----+
^ ^
| |
temp node
在temp->next = newlist;
這個 ?
+---+----+----+ +----+----+----+ +---+----+----+
->| zero |----->| one | | two |--
+---+----+----+ +----+----+----+ +---+---+-----+
^ | ^
| | |
temp | node
|
|
| "head node"
| +---+----+----+ +---+----+---+
"This is your list-2" |-->| FIVE |-->| SIX |--
+---+---+-----+ +---+----+---+
newlist
你的步驟newlist = temp;
?
newlist
|
▼ "head node"
+---+----+----+ +----+----+----+ +---+----+----+
->| zero |----->| one | | two |--
+---+----+----+ +----+----+----+ +---+---+-----+
^ | ^
| | |
temp | node
|
|
| +---+----+----+ +---+----+---+
"This is your list-2" |-->| FIVE |-->| SIX |--
+---+---+-----+ +---+----+---+
這是你做的。 但它不是你想要的?
你將算法從一個列表轉移到另一個列表的算法是錯誤的另外你做了技術錯誤,你是通過值傳遞指針(你需要指針指向反映調用函數的變化)
因為你想將節點從一個列表轉移到另一個列表,並在一個列表和其他列表的頭部傳遞node
指針,你需要傳遞指針的指針以反映調用函數的變化,因此你的聲明在我看來是錯誤的:
void change_lists(ProcessList* node, ProcessList* newlist)
我認為它應該是:
void change_lists(ProcessList** node, ProcessList** newlist)
使用此原型將代碼寫入shift節點。
編輯 :(建議)
代碼中的基本問題是在列表1中移位節點( 例如一個 ),而不是將指針更改為前一個節點( 圖中的零節點 ),您需要制作
[zero] ---> [two]
@CodeRat在他的列表中犯了類似錯誤: 在單鏈表中交換節點
我給了他一個答案,我認為這將有助於您實現代碼。
老答案:
我能找到一個錯誤:而不是
*temp = *node;
你應該寫
temp = node;
解決不是價值觀
做*temp = *node;
是未定義的行為,因為您沒有為temp分配內存,您需要在temp中分配地址。 (temp指向NULL)因為你想將節點從一個列表轉移到另一個列表,這就是你需要temp = node;
我相信你的原型是錯的,它太簡單了。
如果不能以某種方式更改哪個節點被視為列表的開頭,則無法移動單鏈表的節點。
否則,如果移動第一個節點會發生什么? 周圍的代碼將保留指針,但該節點現在邏輯上是移動的目標列表的一部分,並且所有節點都被破壞。
此外,同樣適用於目的地列表:如果在移動之前它是空的怎么辦?
這段代碼中明顯錯誤的一件事是做*temp = *node;
當temp
= NULL
。 您不能取消引用NULL指針。
此外,如果node
屬於單鏈接列表,如果只有指向node
的指針,則無法將其從列表中刪除。 要刪除它,您需要更改指向node
,使其不再指向node
,而是指向NULL
或指向節點后面的node
。 如果您使用的雙向鏈表,你會發現鄰居節點到node
只給出一個指向node
。
要從單個鏈接列表中刪除節點,需要其上一個節點。 前一個節點必須鏈接到下一個節點。
如果該功能可以使用上一個節點,那么很好,但如果沒有,則必須從頭部開始查看。 因此,頭部是必需的。
兩個列表的頭部都是必需的。 由於刪除或添加操作可以更改頭指針,因此將它們作為指針指針傳遞是很自然的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.