簡體   English   中英

交換鏈表中的節點

[英]Swapping nodes in a linked list

我正在嘗試交換鏈表中的兩個相鄰節點,我想我理解如何使用臨時節點來實現它。

這是我的struct swap函數

struct part {
   char* name;
   float price;
   int quantity;
   struct part *next;
};
typedef struct part partType;

partType *swap_node(partType **item) {

  partType *temp;
  temp = *item;
  *item = (*item)->next;
  temp->next = (*item)->next;
  (*item)->next = temp;
  return *item;
}

我不能想到如何使列表中的前一個節點指向新的交換節點。 我需要另一個臨時變量嗎? 另外,如何解釋要交換的兩個節點是列表中的前兩個節點的情況。

從代碼中,看起來您想要交換項目和項目 - >下一步。

如果您沒有雙向鏈表,則需要將linkPtr設置為head,然后迭代直到linkPtr-> next == * item。 從那里,您可以開始在linkPtr,linkPtr-> next和linkPtr-> next-> next之間切換。

你還需要一個單獨的條件來比較linkPtr到head,如果是這樣,那么你需要設置head到new head。

忽略有關雙向鏈表的答案。 要回答您的問題,您需要考慮如何調用您的函數。

現在,你有一個帶指針指針的函數。 它當前指向一個節點(節點A),該節點又指向另一個節點(節點B)。 想象一下這種情況:

partType a, b, c, d;
a->next = &b;
b->next = &c;
c->next = &d;
d->next = NULL;

現在,您想要使用您的函數交換B和C的順序以使A-> C-> B-> D. 好吧,你做的:

swap_node(&a->next);

A指着B; 現在它指向C.正如您所看到的,“前一個”節點已經指向C,正如您所期望的那樣。 換句話說,你已經完成了目標。 干杯!

注意:您的交換功能究竟發生了什么? 讓我們分解吧。 首先,您給它的參數是指向指針的指針 由於措辭的原因,這些都是一個想法的婊子 - 不要讓措辭欺騙你。 就像“變化率的變化率”是一個值得思考的婊子,但“加速”更容易。 您希望通過記住參數首先是指向某些數據的指針來解析它,並且您的函數將修改它指向的數據。

所以你的函數得到一個指向這個'p'的指針,它指向鏈表中的一個點(你假設,見PS)指向兩個節點(稱為X和Y)。 圖:

[p] --> X[next] --> Y[next] --> Z[next]

你的算法做了:

  1. 將[p]指向Y:* item =(* item) - > next
  2. 使X [next]指向Z:temp-> next =(* item) - > next
  3. 使Y [next]指向X:(* item) - > next = temp

所以,如果您現在考慮我的A,B,C,D示例,鏈表是:

A[next] --> B[next] --> C[next] --> D[next] --> NULL

你可以更清楚地看到我傳遞的指針。 它是存儲器中的位置(讀取:指針),其中存儲了A [next],您的函數需要進行交換。

順便提一下,另一種編碼方式是:

a->next = swap_node(&a->next);

但不要這樣做。 這是多余的。

PS你有沒有想過當你要求交換系列中的最后一個節點時會發生什么? 現在,事情爆發了:P

對於這么小的數據,您可能只需交換除next指針之外的所有內容:

partType tmp = *item;
memcpy(item, item->next, offsetof(item, next));
memcpy(item->next, &tmp, offsetof(item, next));

如果您的數據太大而無法執行此操作,則需要所需的兩個節點之前指向節點。 好的部分是你修復prevnext指針作為臨時變量,讓你不需要一個。

prev->next = item->next;
item->next = item->next->next;
prev->next->next = item;

交換到節點的簡單方法......我不是在編寫實際的代碼。 我只是給你一個交換節點的提示。

[1]->[2]->[3]->[4]

假設這是你的鏈表,你想交換[2][3]

  1. 使用循環達到[2] 所以你的temp[2]
  2. 現在temp1 = temp->next; 因此temp1[3]
  3. temp->next = temp1->next;

    temp1->next = temp;

所以現在temp->next = [4]temp1->next = [2]

四個簡單的選擇:

第一個選項:跟蹤指向prev的指針(可能是指向預期的方向)。

第二個選項:實現雙向鏈表,以便始終可以找到上一個節點。

第三個選項:實現單鏈表(如你的任務可能要求的那樣),但給每個節點兩個指針:一個指向'next',一個指向數據有效負載(可能幾乎任何東西;一個結構,一個數組或普通舊數據類型)。 然后你只需交換有效負載指針指向的位置,而不必擔心'next'和'prev'。

第四種選擇:交換數據本身(可能是預期分配的方向)。

上面的每一個都有用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM