第三章:線性表(下)

線性表的鏈式存儲結構

線性表的鏈式存儲結構的特點是用一組任意存儲單元存儲線性表的數(shù)據(jù)元素。既然是任意存儲的,那么每個數(shù)據(jù)元素不僅要存儲自身的數(shù)據(jù)元素信息也要存儲它后繼元素的存儲地址。

  • 數(shù)據(jù)域 存儲數(shù)據(jù)元素信息的域
  • 指針域 存儲直接后繼位置的域
    數(shù)據(jù)域和指針域一起組成數(shù)據(jù)元素ai的存儲映像,稱為結點(Node)
    單鏈表即鏈表中的每個結點中只包含一個指針域
    單鏈表

    鏈表中第一個結點的存儲位置叫做頭指針憔儿,最后一個結點指針為空(NULL或^)
    完整的單鏈表

    單鏈表的第一個結點前附設一個結點,稱為頭結點
    帶有頭結點的單鏈表

頭指針與頭結點的異同
頭指針 指鏈表指向第一個結點的指針放可,若鏈表有頭結點則是指向頭結點的指針谒臼。頭指針具有標識作用朝刊,無論鏈表是否為空,頭指針均不為空蜈缤,頭指針是鏈表的必要元素拾氓。
頭結點為了操作的統(tǒng)一和方便而設立的,放在第一元素的結點之前底哥,其數(shù)據(jù)域一般無意義(也可存放鏈表的長度)咙鞍。這樣對在第一元素結點前插入結點和刪除第一結點其操作與其他結點操作統(tǒng)一。頭結點不一定是鏈表必須要素

單鏈表存儲示意圖

帶頭結點的單鏈表

空鏈表

  • 線性表的單鏈表存儲結構定義
typedef struct fact
{
    ElemType  data; //存放數(shù)據(jù)元素的數(shù)據(jù)域
    struct  fact *next; //存放后繼結點地址的指針域
}Node;
Node *LinkList  //定義LinkList

第i個元素與其后繼元素關系

頭插法建立鏈式線性表

  • 定義一個空結點*head = NULL


    準備條件
  • 每次連接新的數(shù)據(jù)元素時都要動態(tài)分配一個node大小的內存空間趾徽,并把這塊空間的首地址傳給一個node指針型的變量s续滋,*s的數(shù)據(jù)域是5。


    生成一個結點s
  • 若head為空時把s結點變?yōu)閔ead結點附较。


    head = p
  • 若head不為空時吃粒,使head結點改成s的后繼結點,代表每次新的元素到來時都是從頭部插入的拒课。


    s->next = head
  • 每次元素插入結束時把s結點變?yōu)閔ead結點徐勃,就是說每次都是從頭部插入的。


    head = p
int main()
{
    node *head=NULL,*p;
    int num;

    printf("Enter some integers: ");
    scanf("%d",&num);
    while(num!=0){
        p=(node *)calloc(1,sizeof(node));
        p->data=num;
        if(head==NULL)
            head=p;
        else
            p->next=head;
        head=p;
        scanf("%d",&num);
    }
    for(p=head;p;p=p->next)
        printf("%-5d",p->data);
    printf("\n");
    return 0;
}

尾插法建立鏈式線性表(無首元)

  • 首先創(chuàng)建兩個空結點head和tail
  • 創(chuàng)建一個p結點(開辟一個node大小的內存空間早像,空間首地址指向p,p結點的數(shù)據(jù)為num)僻肖。
  • 若head為空,則把p結點變?yōu)閔ead結點卢鹦,第一次p結點為head結點并且也是tail結點臀脏。
  • 若head結點不為空,則把tail的下一個結點指向p結點冀自,即第二次是head結點指向p結點揉稚。每次插入元素后p結點變?yōu)閠ail結點。那么第三次插入元素時就是在第二個元素后面插入p結點
int main()
{
    node *head,*tail,*p;
    int num;

    head=tail=NULL;
    printf("Enter num: ");
    scanf("%d",&num);

    while(num!=0){
        p=(node *)calloc(1,sizeof(node));
        p->data=num;
        if(head==NULL)
            head=p;
        else
            tail->next=p;
        tail=p;
        scanf("%d",&num);
    }
    for(p=head;p;p=p->next)
        printf("%-4d",p->data);
    printf("\n");
    return 0;
}

尾插法建立鏈式線性表(有首元)
有一個頭結點熬粗,也就是在while()外面先開辟一個node大小的內存空間搀玖,默認該結點的數(shù)據(jù)為0。還有一點不同是判斷的時候要判斷head結點的下一個結點是否為空驻呐。

int main()
{
    node *head,*tail,*p;
    int num;
    
    printf("Enter some integers: ");
    scanf("%d",&num);
    head=(node *)calloc(1,sizeof(node)); //初始化內存灌诅,設置為0 
    while(num!=0){
        p=(node *)calloc(1,sizeof(node));
        p->data=num;
        if(head->next==NULL) //head如何連接后一個元素 
            head->next=p;
        else
            tail->next=p; //第二個元素和后面元素的連接方式 
        tail=p;
        scanf("%d",&num);
    }
    for(p=head->next;p;p=p->next)
        printf("%-5d",p->data);
    printf("\n");
    return 0;
}

==================================================
題外話
結構體
這種類型是可以將多種數(shù)據(jù)類型組合起來的結構。
聲明方式:

struct 結構體名稱{
      成員1的類型  成員1的名稱含末;
      成員2的類型  成員2的名稱猜拾;
             ............
      成員3的類型  成員3的名稱;
};

舉例:

struct fact{
    int data;
    struct fact *next;
    };

利用typedef定義這個結構體佣盒,即為結構體起別名node

typedef struct fact{
    int data;
    struct fact *next;
    }node;
等價于
typedef struct fact{
    int data;
    struct fact *next;
    };
typedef struct fact node;

malloc挎袜、calloc和realloc區(qū)別
三個函數(shù)的申明分別為:

 void* malloc(unsigned size);
 void* realloc(void* ptr, unsigned newsize);  
void* calloc(size_t numElements, size_t sizeOfElement); 

calloc 在初始化內存時設置初值為0。參數(shù)sizeOfElement為申請地址的單位元素長度 ,numElements為元素個數(shù)宋雏,即在內存中申請numElements*sizeOfElement字節(jié)大小的連續(xù)地址空間

malloc分配內存位于堆中芜飘,并且沒有初始化內存的內容务豺。因此基本上malloc之后磨总,調用函數(shù)memset來初始化這部分的內存空間。在內存的動態(tài)存儲區(qū)中分配一塊長度為size字節(jié)的連續(xù)區(qū)域笼沥,參數(shù)size為需要內存空間的長度蚪燕,返回該區(qū)域的首地址缩举。

realloc對malloc申請的內存進行大小的調整

申請的內存最終需要通過函數(shù)free來釋放
這三個函數(shù)都是在stdlib.h函數(shù)庫中蚤蔓,它們的返回值都是請求系統(tǒng)分配的地址钝域,如果請求失敗就返回NULL屋群。

最后說明一點萝衩,真的是實踐出真理垃你。如果不能完整的靠自己寫出代碼俱两,那就不算自己懂赎线。

============================補充內容===================================
這兩天又把這部分認真看了看舞骆,實現(xiàn)了一下钥弯。并把每種方法封裝成為一個子函數(shù)

頭插法
頭插法傳入參數(shù)是一個指針變量和一個整形數(shù)
返回類型是指針類型,因為通過頭插法建立的鏈表需要由head指針的首地址索引依次遍歷才能找到其他鏈表元素督禽。

Node* CreatLinkListHead(Node *head,int num)
{
    for(int i =0;i<num;i++)
    {
        Node *p = (Node *)malloc(sizeof(Node));
        p ->data = i+1;
        p->next = NULL;
        if(head == NULL)
        {
            head = p;
        }
        else
        {
            p->next = head;
            head = p;
        }
    }
    return head;
}

尾插法(無首元)
思想同頭插法脆霎,但是有一點需要注意的是: tail = p應寫在else的外面,即對head結點也適用狈惫。插入head結點后睛蛛,head結點和tail結點都是p結點代替,這樣當遇到非head結點時胧谈,tail->next才能找到位置否則容易出錯忆肾。

//尾插法
Node* CreatLinkListTail(Node *head,int num)
{
    Node *p,*tail;
    head = tail = NULL;
    for(int i = 0;i<num;i++)
    {
        p = (Node *)malloc(sizeof(Node));
        p ->data = i+1;
        p->next = NULL;
        if(head == NULL)
        {
            head = p;
        }
        else
        {
            tail ->next = p;    
        }
        tail = p;
    }
    return head;
}

輸出函數(shù)Output
從head結點依次遍歷直到null

void Output(Node *head)
{
    Node *p;
    p = head;
    while(p){
        cout << p->data << " ";
        p = p->next;
    }
    cout <<endl;
}

注意事項
在使用malloc分配內存空間時,必須指定p->next = null菱肖。因為malloc函數(shù)不同于calloc函數(shù)會指定初始值為0客冈,malloc函數(shù)的初始值是隨機的,對數(shù)據(jù)的輸出會造成一定的影響蔑滓。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末郊酒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子键袱,更是在濱河造成了極大的恐慌燎窘,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹄咖,死亡現(xiàn)場離奇詭異褐健,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門蚜迅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舵匾,“玉大人,你說我怎么就攤上這事谁不∽荩” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵刹帕,是天一觀的道長吵血。 經常有香客問我,道長偷溺,這世上最難降的妖魔是什么蹋辅? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮挫掏,結果婚禮上侦另,老公的妹妹穿的比我還像新娘。我一直安慰自己尉共,他們只是感情好褒傅,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著爸邢,像睡著了一般樊卓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杠河,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天碌尔,我揣著相機與錄音,去河邊找鬼券敌。 笑死唾戚,一個胖子當著我的面吹牛,可吹牛的內容都是我干的待诅。 我是一名探鬼主播叹坦,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼卑雁!你這毒婦竟也來了募书?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤测蹲,失蹤者是張志新(化名)和其女友劉穎莹捡,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扣甲,經...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡篮赢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片启泣。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡涣脚,死狀恐怖,靈堂內的尸體忽然破棺而出寥茫,到底是詐尸還是另有隱情遣蚀,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布坠敷,位于F島的核電站妙同,受9級特大地震影響射富,放射性物質發(fā)生泄漏膝迎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一胰耗、第九天 我趴在偏房一處隱蔽的房頂上張望限次。 院中可真熱鬧,春花似錦柴灯、人聲如沸卖漫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羊始。三九已至,卻和暖如春查描,著一層夾襖步出監(jiān)牢的瞬間突委,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工冬三, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匀油,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓勾笆,卻偏偏與公主長得像敌蚜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子窝爪,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內容

  • 一些概念 數(shù)據(jù)結構就是研究數(shù)據(jù)的邏輯結構和物理結構以及它們之間相互關系弛车,并對這種結構定義相應的運算,而且確保經過這...
    Winterfell_Z閱讀 5,854評論 0 13
  • 轉自:http://blog.csdn.net/oreo_go/article/details/52116214 ...
    YYT1992閱讀 981評論 0 4
  • 本文內容取自于小甲魚的數(shù)據(jù)結構與算法蒲每。http://www.reibang.com/p/230e6fde9c75 ...
    阿阿阿阿毛閱讀 2,901評論 0 7
  • 大學的時候不好好學習纷跛,老師在講臺上講課,自己在以為老師看不到的座位看小說啃勉,現(xiàn)在用到了老師講的知識忽舟,只能自己看書查資...
    和玨貓閱讀 1,447評論 1 3
  • 今天看的是關于延時函數(shù)的實現(xiàn),其實我可以完全把c代碼解析出來沒有問題!但是解析出來的地址和指導手冊上的對不上叮阅!嚴格...
    Cheer_up閱讀 283評論 0 0