簡體   English   中英

單鏈表

[英]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 ),則當循環結束時,應在currentcurrent->next之間插入新節點,即current用作代碼中的previous你現在有。 如果current->nextNULL則在末尾插入。

無法對此進行測試,但是將新的節點設置代碼移動到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.

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