iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0
Software Development

用C++ 設計程式中的系統櫃系列 第 9

[Day 09] 用C++ 設計程式中的系統櫃:linkedList::printAll()

  • 分享至 

  • xImage
  •  

如果我們的物件沒有隨機存取的功能,那該如何取得鏈結串列的內容?

目前來說,我們所擁有的類別屬性只有指標 head ( 和指標 tail),
因此從這裡下手絕對是正確的方向!


迴圈解法

定義類別方法

class SLL {
private:
    SLLNode *head;
public:
    SLL();
    void pushFront(int);
    void printElement();
};

class DLL {
private:
    DLLNode *head, *tail;
public:
    DLL();
    void pushFront(int);
    void printElement();
};

解題邏輯

剛剛說到我們的起點就是鏈結串列的頭部指標,那麼我們就從他開始吧!

  1. 我們需要一個會變動的指標,用來記錄目前的所在記憶體位址,或說當前的節點。(取名:cur 代表 current)
  2. 初始化,將 cur 設為 this -> head
  3. 進入迴圈,直到 cur == NULL,就跳出迴圈

    cur != NULL 意味著這個指標指向的記憶體有存著一個節點,
    因此我們可以讀取 cur -> data
    也可以藉著 cur -> next 找到下一個節點

  4. 輸出的內容可以選擇是否要新增修飾字串,如:"NULL", " -> "

    假設鏈結串列中包含:1, 5, 6, 7
    輸出的結果應為 1 -> 5 -> 6 -> 7 -> NULL

void SLL::printElement() {
    SLLNode *cur = this -> head;
    while (cur != NULL) {
        std::cout << cur -> data << " -> ";
        cur = cur -> next;
    }
    std::cout << "NULL\n";
}
void DLL::printElement() {
    DLLNode *cur = this -> head;
    while (cur != NULL) {
        std::cout << cur -> data << " -> ";
        cur = cur -> next;
    }
    std::cout << "NULL\n";
}

遞迴解法

定義類別方法

class SLL {
private:
    SLLNode *head;
public:
    SLL();
    void pushFront(int);
    void printElement(SLLNode *);
};

class DLL {
private:
    DLLNode *head;
public:
    DLL();
    void pushFront(int);
    void printElement(DLLNode *);
};

解題邏輯

遞迴的想法相對迴圈解法也許相對抽象,但是學會遞迴後,在某些情況下可以少走彎路!

以這題來說,我們根據當前傳入的頭部節點參數來決定輸出的內容:

  1. head != NULL:因為此節點存在,所以輸出節點內容,並呼叫函式本身進行遞迴,參數傳入下一個節點
  2. head == NULL:節點不存在,代表此函式進行到了尾聲,改為輸出字串 "NULL"(作為遞迴的終點)
void SLL::printElement(SLLNode *head) {
    if (head == NULL) {
        std::cout << "NULL\n";
        return ;
    }
    std::cout << head -> data << " -> ";
    printElement(head -> next);
}
void DLL::printElement(DLLNode *head) {
    if (head == NULL) {
        std::cout << "NULL\n";
        return ;
    }
    std::cout << head -> data << " -> ";
    printElement(head -> next);
}

從上述來看,不論是用遞迴解法,或是迴圈解法,「單向鏈結串列」、「雙向鏈結串列」的函式程式碼近乎相同。原因是我們都是從頭不斷呼叫節點的屬性 next,並無使用到 tail 或屬性 prev,因此程式碼的結構是完全相同的。


下一篇,我們就來試著刪除節點吧!


上一篇
[Day 08] 用C++ 設計程式中的系統櫃:linkedList::pushFront()
下一篇
[Day 10] 用C++ 設計程式中的系統櫃:linkedList::popFront()
系列文
用C++ 設計程式中的系統櫃30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言