1. 程式人生 > >SDUTOJ 2116 資料結構實驗之連結串列一:順序建立連結串列

SDUTOJ 2116 資料結構實驗之連結串列一:順序建立連結串列

最近資料結構和c++相結合的實訓正在進行,鑑於一些同學還不是太懂連結串列,寫一篇部落格講解一下,若是哪裡有問題,請不吝支出,在此謝過,若是過路的大神看見了,求輕噴。。。。

說白了,連結串列就是個特殊的結構體陣列,只不過陣列是用下標找到某個節點的後繼節點,而連結串列使用一個指向他身型別的指標來記錄下一個節點的地址,就比如你進入了一個村莊,你發現這裡住的樓的樓號(1,2,3,4,等)都是連著的,這就是結構體陣列,而連結串列就是你從第一樓開始,看到的是本樓的標號,然後標號下面還有一行字:下一個樓是XXX,他在某某某地方,當你找到XXX後,XXX的樓的標號下面也有一行字:下一個樓是YYY,他在另一個某某某地方,你每次都能從這個樓的標號上找到下一個樓在哪,直到最後一棟樓上標號下面沒有下一個樓的資訊,只有一個NULL,那麼,你走到樓的最後了。。。連結串列遍歷完了。。。。。

這裡以SDUTOJ的2116題為例,講解一下連結串列,另外,連結串列是寫出來的,練出來的,不寫,不編譯執行,不除錯,永遠學不會連結串列,所以不要光看,要用編譯器寫,然後提交到OJ上去判,才能學會,這是這個題的連結:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2116

資料結構實驗之連結串列一:順序建立連結串列

Time Limit: 1000ms   Memory limit: 65536K  有疑問?點這裡^_^

題目描述

輸入N個整數,按照輸入的順序建立單鏈表儲存,並遍歷所建立的單鏈表,輸出這些資料。

輸入

第一行輸入整數的個數N;
第二行依次輸入每個整數。

輸出

輸出這組整數。

示例輸入

8
12 56 4 6 55 15 33 62

示例輸出

12 56 4 6 55 15 33 62

提示

不得使用陣列!

來源

示例程式

#include <iostream>

using namespace std;

class List
{
    public:
    int data;//資料域,用來記錄資料
    List *next;//指著域,用來記錄它下一個節點的地址
               //訪問這個變數能找到它的下一個節點
};

void del(List *p)//遞迴釋放記憶體
{
    if(p == NULL)//p為NULL說明p訪問到連結串列結尾了
        return ;//訪問到結尾返回
    del(p->next);//如果沒訪問到結尾,會在這裡一直呼叫函式本身遞迴,直到遇見NULL
    delete p;//遇到NULL返回到head的時候,從後向前刪除節點,釋放記憶體
             //如果從前面刪除的話就會把本節點的next值也給刪除了,就沒辦法訪問到下一個節點了
            //如果定義一個臨時變數先記錄下一個節點地址然後再刪除本節點也是可以解決這個問題的
}
//void del(List *head)
//{
//    List *p = head,*q;
//    while(p)
//    {
//        q = p;
//        p = p->next;
//        delete q;
//    }
//}//這樣釋放記憶體也是可以的
int main()
{
    List *head = new List;//new開闢記憶體,地址賦給head,head代表這個
                          //連結串列的頭,訪問head能找到這個連結串列
    head->next = NULL;//初始狀態下只有head鏈節,他沒有後繼結點,所以他的next值為NULL(空)
    List *p,*q;//p是遊動指標,建立連結串列的時候永遠指向最後一個鏈節
               //q是開新記憶體用的,也就是增加一個新的鏈節
    int n;//輸入數的個數
    cin>>n;
    p = head;//初始狀態下只有head一個鏈節,那麼最後一個鏈節也是head,讓p指向head
    for(int i = 0;i < n;i++)
    {
        q = new List;//增加新的鏈節q
        cin>>q->data;//給新鏈節的data賦值
        p->next = q;//把q掛在p(初始值是head)的後面
        q->next = NULL;//新鏈節是連結串列的最後一個鏈節,後面沒有後繼,那麼,就把他的next值設為NULL(空)
        p = q;//q成為p的後繼之後,q就是最後一個節點,我們規定p指向最後一個節點,這裡就把q賦給p
    }//迴圈完成後,連結串列就建立完了,head是他們的頭
    p = head->next;//p在上面是指向最後一個元素,以便於增加新的鏈節後能很快的放在它的後面,達到新增鏈節的目的
                   //現在我們就發動他的遊動特點,來訪問整個連結串列,從上面看來,我們輸入的第一個整數放在q->data
                   //裡面了,並沒有放在head裡面,那麼,我們訪問的話,head的下一個節點才是第一個儲存節點,用p
                   //訪問head的next,判就指向了連結串列中的第一個儲存輸入數的節點(真正第一個節點是head,因為head
                   //因為head的data沒有值,所以,我們說head的後面第一個節點為有效節點)
    while(p != NULL)//當p訪問不到NULL的時候,就會一直迴圈,NULL是連結串列結束的標誌
    {
        cout<<p->data;//輸出p訪問到的每個節點的data值
        if(p->next != NULL)
            cout<<" ";//這兩行是調格式的,為了能在最後不多輸出空格,其實只是為了在OJ上AC
        p = p->next;//p訪問把本節點的next值,p就指向下一個節點,相當於向後移動一個節點
    }
    cout<<endl;
    del(head);//釋放記憶體
    return 0;
}