[英]Singly Linked List
我有一個來自https://hotfile.com/dl/253309046/133284f/4_SinglyLinkedList.rar.html的項目
函數insertOrdered()
按順序插入分數。
我的問題是:可以在不使用“上一個”變量的情況下重寫此循環嗎?
SinglyNode* current = head;
SinglyNode* previous= NULL;
while (current != NULL)
{
if(newNode->score >= current->score)
previous = current;
else
break;
current = current->next;
}
newNode->next = previous->next;
previous->next = newNode;
獲取另一個變量(例如x)中先前變量的值(例如p),並使用x代替p。
一個簡單的解決方案是首先檢查是否應將其插入頭部。 如果不是,則使用類似於您的循環,但將其與current->next
比較(如果不是NULL
),則當循環結束時,應在current
和current->next
之間插入新節點,即current
用作代碼中的previous
你現在有。 如果current->next
為NULL
則在末尾插入。
無法對此進行測試,但是將新的節點設置代碼移動到if塊中應該可以刪除以前的變量。
SinglyNode* current = head;
while (current != NULL)
{
if(newNode->score >= current->score) {
newNode->next = current->next;
current->next = newNode;
}
else break;
current = current->next;
}
if(current == NULL) { // got to end of list
current->next = newNode;
newNode->next = NULL;
}
這應該工作:
SinglyNode* current = head;
if(current == NULL) {
head = newNode;
}
else if(newNode->score < current->score) {
newNode->next = current;
head = newNode;
}
else {
while (current->next != NULL)
{
if(newNode->score < current->next->score)
break;
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
您不能消除“上一個”變量,但是可以掩飾它; 而且,您可以構造循環,使其成為唯一的迭代變量。
當然要插入新節點,您需要更新前一個節點以指向它。
您可以通過在列表中向前看並處理各種情況從當前節點執行此操作。
另一種方法是將指針保留到上一個節點中的指針字段。
node **ppnode;
for (ppnode = &head;
*ppnode != NULL && (*ppnode)->value >= newnode->value;
ppnode = &(*ppnode)->next)
; /* empty body */
newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;
在這里,我們使用一個ppnode
指針間接指向當前節點,而不是使用current
指針指向當前節點。 它不是指向該節點,而是指向指向該節點的指針(因此必須正確鍵入:它是指向指針:雙星的指針)。
指向第一個節點的指針是列表head
變量,因此ppnode
最初指向該head
變量。 指向此后每個其他節點的指針是上一個節點的next
字段:這些next
字段中的每個字段實際上都像列表其余部分的head
。 因此,使用這個ppnode
變量,我們可以跟蹤必須更新的上一個節點中的位置,而不必跟蹤上一個節點本身。 這使我們能夠處理沒有前一個節點的列表開頭的情況。
讓我們追溯一下head
為null(列表為空)的情況。
ppnode
指向head
。 但是*ppnode
為null,因此循環體從不執行。
由於ppnode
指向head
,因此行:
newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;
具有以下含義:
newnode->next = head ? head->next : NULL;
head = newnode;
這些行中的條件檢查處理了將新節點添加到空列表或非空列表尾部的情況。 如果列表為空,或者列表中的所有值都小於新值,則循環終止, ppnode
指向列表的空終止符,如果列表為空,則終止符為head
,否則為尾節點的next
字段。 由於*ppnode
為null,因此我們無法參考(*ppnode)->next
。 沒有下一個; 新節點是最后一個節點, next
必須為空。
現在,讓我們看一下在存在頭節點的情況下會發生什么,並且其值更大,因此必須在前面插入新節點。 在這種情況下, ppnode
像以前ppnode
指向head
,並且*ppnode != NULL
條件為true。 但是(*ppnode)->value >= newnode->value
條件失敗,因此循環永遠不會執行。
現在,我們再次執行以下代碼:
newnode->next = head ? head->next : NULL;
head = newnode;
但是這次head
不為空,因此newnode->next = head->next
,和以前一樣, newnode
成為新的head
。
所有其他情況都從這兩種情況出發:除了代替head
,該動作使用上next
節點的next
指針進行播放,就像該列表的其余部分的頭一樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.