程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 數據結構基礎(9) --單鏈表的設計與實現(2)之高級操作

數據結構基礎(9) --單鏈表的設計與實現(2)之高級操作

編輯:C++入門知識

數據結構基礎(9) --單鏈表的設計與實現(2)之高級操作


鏈表的鏈接:

將第二條鏈表的所有內容鏈接到第一條鏈表之後, 其完整實現代碼與解析如下:

 

//鏈表的鏈接
template 
void MyList::concatenate(const MyList &list)
{
    if (isEmpty())//如果自己的鏈表為空
    {
        first = list.first;
        return ;
    }
    else if (list.isEmpty())    //如果第二條鏈表為空
    {
        return ;
    }

    Node *endNode = first->next;
    //找到第一條鏈表的末尾節點
    while (endNode->next != NULL)
    {
        endNode = endNode->next;
    }

    //找到第二條鏈表的第一個真實元素
    Node *secondListNode = (list.first)->next;
    //注意: 需要將第二個鏈表中的元素值copy出來
    //不能直接將第二條鏈表的表頭鏈接到第一條鏈表的表尾
    //不然在析構函數回收內存時會發生錯誤(即:同一段內存釋放兩次)
    while (secondListNode != NULL)
    {
        Node *newNode = new Node(secondListNode->data);
        newNode->next = NULL;
        endNode->next = newNode;

        //兩條鏈表同時前進
        endNode = endNode->next;
        secondListNode = secondListNode->next;
    }
}

 

鏈表的反轉:

基本思想:

遍歷一遍鏈表,利用一個輔助指針(此處為指針r),存儲遍歷過程中當前指針指向的下一個元素,然後將當前節點元素的指針反轉後,利用已經存儲的指針往後面繼續遍歷。

//鏈表的反轉
template 
void MyList::invort()
{
    if (!isEmpty())
    {
        //p指向正向鏈表的第一個真實節點
        //隨後, p也會沿正方向遍歷到鏈表末尾
        Node *p = first->next;

        //q會成為倒向的第一個真實節點
        //首先將q設置為NULL: 保證反向之後
        //最後一個元素的指針域指向NULL, 以表示鏈表結束
        Node *q = NULL;
        while (p != NULL)
        {
            Node *r = q;  //暫存q當前指向的節點
            //q後退(沿著正向後退)
            q = p;
            //p前進(沿著正向前進), 保證p能夠始終領先q一個位置
            p = p -> next;
            //將指針逆向反轉
            //注意:一點要保證這條語句在p指針移動之後運行,
            //不然p就走不了了...(因為q改變了指針的朝向)
            q -> next = r;
        }

        //此時q成為反向鏈表的第一個真實元素
        //但是為了維護像以前一樣的first指針指向一個無用的節點(以使前面的操作不會出錯)
        //於是我們需要將first的指針域指向q
        first->next = q;
    }
}

鏈表打印:

重載MyList的<<運算符, 輸出鏈表所有元素, 以供測試之用

//顯示鏈表中的所有數據(測試用)
template 
ostream &operator<<(ostream &os, const MyList &list)
{
    for (Node *searchNode = list.first -> next;
            searchNode != NULL;
            searchNode = searchNode -> next)
    {
        os << searchNode -> data;
        if (searchNode -> next != NULL) //尚未達到鏈表的結尾
            cout << " -> ";
    }

    return os;
}

附-測試代碼:

int main()
{
    cout << "------------ 1 ------------" << endl;
    MyList first;
    for (int i = 0; i < 5; ++i)
    {
        first.insert(i+1, i+1);
    }
    first.remove(5);

    MyList second;
    for (int i = 0; i < 5; ++i)
    {
        second.insert(i+6, i+1);
    }
    second.insertFront(5);
    second.insert(88, 7);

    cout << "Before concatenate..." << endl;
    cout << "first: " << first << endl;
    cout << "second: " << second << endl;

    cout << "After concatenate..." << endl;
    first.concatenate(second);
    cout << "first: " << first << endl;
    cout << "second: " << second << endl;


    cout << "\n------------ 2 ------------" << endl;
    MyList chList;
    for (char ch = '0'; ch <= '9'; ++ ch)
    {
        chList.insertFront(ch);
    }
    cout << "Before invort..." << endl;
    cout << chList << endl;

    cout << "After invort..." << endl;
    chList.invort();
    cout << chList << endl;

    cout << "After remove('5')..." << endl;
    chList.remove('5');
    cout << chList << endl;

    cout << "\n------------ 3 ------------" << endl;
    MyList dList;
    dList.insert(1.1, 1);
    dList.insertFront(2.2);
    cout << dList << endl;

    return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved