1. 程式人生 > 實用技巧 >資料結構--線性表的鏈式儲存(3)

資料結構--線性表的鏈式儲存(3)

一、什麼是連結串列

  線性表的鏈式儲存又稱之為單鏈表,他是通過記憶體中任意一塊區域來儲存資料元素的,為了讓每一塊的元素建立邏輯關係,我們把每一塊的資料儲存單元分為兩個部分,第一個部分為資料部分,第二個部分為指向下一個節點的指標,所以在插入和刪除的時候,連結串列不需要對元素大量的進行移動,只需修改指標即可。

二、連結串列的特點

  1.解決了順序表在儲存資料時需要大量連續的空間,屬於非隨機儲存。

  2.由於存在指標域,連結串列消耗的空間會比較大。

  3.連結串列進行刪除和插入時候時間複雜度為O(1),因為只需修改指標的指向而已。

  4.查詢時消耗比較大,需要從頭開始遍歷,時間複雜度為O(n)。

  本人覺得順序表和連結串列是一個互補的出現,往往某些場合需要兩者結合才能完成。

三、單鏈表的頭插法和尾插法

  頭插法時元素始終插入頭節點後面,比如說插入的元素為1,2,3,4,5,所以在輸出的時候為5,4,3,2,1

頭插法程式碼如下

LinkList InsertHead(LinkList L) {        //頭插法
    LinkNode *s;
    int n;
    scanf("%d", &n);
    while (n != -1) {        //輸入為-1時表示終止輸入
        s = (LinkNode*)malloc(sizeof
(LinkNode)); s->data = n; s->next = L->next; L->next = s; scanf("%d", &n); } return L; }

  尾插法在插入元素時候每次都在節點最後插入,所以元素的順序不會變。

尾插法程式碼如下

LinkList InsertTail(LinkList L) {        //尾插法
    int n;
    LinkNode *s;
    LinkNode *end = L;        //尾指標
    scanf("
%d", &n); while (n != -1) { //輸入-1時退出 s = (LinkNode*)malloc(sizeof(LinkNode)); s->data = n; end->next = s; end = s; //end指向新的尾節點 scanf("%d", &n); } end->next = NULL; //尾節點指標置為空 return L; }

四、單鏈表的增、刪、改、查操作

  linkList.h標頭檔案

#include<stdio.h>

typedef int Status; /* Status是函式的型別,其值是函式結果狀-1為出現錯誤1為正常態程式碼,如OK等 */
typedef int Boolean; /* Boolean是布林型別,其值是TRUE或FALSE 其中1為TRUE 0為FALSE */

typedef int ElemType; /*ElemType是資料的型別,我們這裡用int型別表示*/

typedef struct {  //定義單鏈表的節點型別
    ElemType data;    //資料
    struct LinkNode *next;  //指標域
}LinkNode, *LinkList;

LinkList InitLinkList(LinkList L); //初始化單鏈表
int LengthLink(LinkList L);//返回單鏈表的長度
int LocateElemLink(LinkList L, ElemType e);//查詢元素e在表中的位置
ElemType GetElemLink(LinkList L, int i);//獲取表中第i個位置的元素,並返回
Status InsertLinkList(LinkList L, int i, ElemType e);//在表L中第i個位置插入元素e
Status DeleteElemLink(LinkList L, int i, ElemType *e);//刪除表中第i個元素,並用e返回其值
void PrintLinkList(LinkList L);//輸出單鏈表的所有元素
Boolean IsEmptyLink(LinkList L);//判斷單鏈表是否為空
Status DestroyLinkList(LinkList L);//銷燬單鏈表,並釋放所佔用的空間

  linkList.c函式檔案

#include<stdio.h>
#include"linkList.h"

LinkList InitLinkList(LinkList L) {  //初始化單鏈表
    LinkNode *s;
    s = (LinkList)malloc(sizeof(LinkNode));
    s->next = NULL;
    L = s;
    return L;
}

Status InsertLinkList(LinkList L, int i, ElemType e) { //在表L中第i個位置插入元素e,頭插法
    
    LinkList p = L;

    int j = 0;
    while (j < i-1) {
        p = p->next;
        j++;
    }

    LinkNode *newNode = (LinkNode*)malloc(sizeof(LinkNode));
    newNode->data = e;
    newNode->next = p->next;        //新節點指向原來位置節點的下一個
    p->next = newNode;        //原來位置節點指向新節點
    return 1;

}


void PrintLinkList(LinkList L) {  //輸出單鏈表的所有元素
    LinkList p = L;

    p = p->next;
    if (p == NULL)
        printf("連結串列為空");
    else {
        while (p != NULL) {
            printf(" %d ", p->data);
            p = p->next;
        }
    }
}

int LengthLink(LinkList L) {  //返回單鏈表的長度
    int i = 0;
    LinkList p = L;

    p = p->next;

    while (p != NULL) {
        i++;
        p = p->next;
    }
    return i;
}

int LocateElemLink(LinkList L, ElemType e) {        //查詢元素e在表中的位置
    LinkList p = L;
    int i = 0;

    while (p->next != NULL) {
        p = p->next;
        if (p->data == e)
            return i + 1;
        i++;
    }

    return -1;
    
}

ElemType GetElemLink(LinkList L, int i) {        //獲取表中第i個位置的元素,並返回
    LinkList p = L;
    int j = 0;
    
    if (i <= 0 || i > LengthLink(L))
        return NULL;
    
        while (p != NULL) {
        p = p->next;
        j++;
        if (j == i)
            return p->data;
    }
}

Status DeleteElemLink(LinkList L, int i, ElemType *e) {  //刪除表中第i個元素,並用e返回其值

    LinkList p = L;
    LinkNode *n;
    ElemType *temp;
    int j = 0;
    if (i <= 0 || i > LengthLink(L))
        return -1;

    while (p != NULL) {
        if (j == i-1) {
            n = p->next;
            p->next = n->next;
            *e = n->data;
            free(n);
            return 1;
        }
        p = p->next;
        j++;
    }
    return 1;
}

Boolean IsEmptyLink(LinkList L) {  //判斷單鏈表是否為空
    if (L->next == NULL)
        return 1;
    else
        return 0;

}

Status DestroyLinkList(LinkList L) {  //銷燬單鏈表,並釋放所佔用的空間
    L->next = NULL;
    free(L);
    return 1;
}

main.c主函式檔案

#include<stdio.h>
#include"linkList.h"

int main() {
    int i;
    int array[] = { 0,1,2,3,4,5 };
    ElemType e;
    LinkList L = InitLinkList(&L);
    
    for (i = 1; i < 6; i++) {
        InsertLinkList(L, i, array[i]);
    }

    PrintLinkList(L);
    printf("\n");
    printf("連結串列長度為%d\n",LengthLink(L));
    printf("5在連結串列中第%d個位置\n", LocateElemLink(L, 5));
    printf("第五個位置的元素為%d\n",GetElemLink(L, 5));
    DeleteElemLink(L, 5, &e);
    printf("刪除第二個元素,刪除的元素為%d,列印刪除之後的表\n",e);
    PrintLinkList(L);
    printf("\n");
    if (IsEmptyLink(L) == 1)
        printf("此表為空\n");
    else
        printf("此表不為空\n");
    printf("銷燬線性表");
    if (DestroyLinkList(L) == 1)
        printf("銷燬成功!\n");
    else
        printf("銷燬失敗");
}