1. 程式人生 > >(一)線性表的鏈式儲存結構

(一)線性表的鏈式儲存結構

2.3.1 線性表的鏈式儲存結構——連結串列
連結串列
1.每個節點中除資料域外,設定了一個指標域,用以指向其後繼節點,這樣構成的連結表稱為線性單向連結串列,簡稱單鏈表
2.每個節點中除資料域外,設定兩個指標域,分別用以指向其前驅節點和後繼節點,這樣構成的連結串列稱為線性雙向連結表,簡稱雙鏈表
線上性表的鏈式儲存中,為了便於插入和刪除演算法的實現,每個連結串列帶有一個頭節點,並通過頭節點的指標唯一標識該連結串列。
單鏈表LinkList型別定義如下:

typedef struct LNode//定義單鏈表節點型別
{
    ElemType data;//存放元素值
struct LNode *Next;//指向後繼節點 }

雙鏈表DNode型別的定義如下:

typedef struct DNode
{
    ElemType data;
    struct DNode *prior;
    struct DNode *next;
}

所謂儲存密度是指節點資料本身所佔的儲存量和整個節點結構中所佔儲存量之比,即:
儲存密度=節點資料本身所佔的儲存量/節點結構所佔的儲存總量
一、線性表基本運算在單鏈表中的實現:
需要注意的幾個問題
1、頭節點的序號為0,且頭節點不計入單鏈表的長度中;
2、開始節點的序號為1;
頭插法建立單鏈表 :

void CreateListF(LinkList *&L, ElemType a[], int n)//頭插法建立單鏈表
{
    LinkList *s;
    int i;
    L->next = NULL;
    L = (LinkList *)malloc(sizeof(LinkList));
    for (i = 0;i < n;i++)
    {
        s = (LinkList *)malloc(sizeof(LinkList));
        s->data = a[i];
        s->next = L->next;
        L->next = s;
    }
}

尾插法建立單鏈表

void CreateListR(LinkList *&L, ElemType a[], int n)//尾插法建立單鏈表
{
    LinkList *s,*r;
    int i;
    L = (LinkList *)malloc(sizeof(LinkList));
    r = L;
    for (i = 0;i < n;i++)
    {
        s = (LinkList *)malloc(sizeof(LinkList));
        s->data = a[i];
        r->next = s;
        r = s;
    }
    r->next = NULL;
}

二、實踐
1.在VS中建立VC++解決方案,並給方案命名為:單鏈表
2.在彈出對話方塊中選擇“下一步”,其他為預設,選擇“空專案”,然後點選“完成”
3.在資源管理器中,選擇解決方案,點選右鍵,新增新建項,給新建項命名為:LNode.cpp
在檔案中輸入如下程式碼:

#include <stdio.h>
#include <malloc.h>
//----------線性表的動態分配鏈儲存結構-------------  
#define LIST_INT_SIZE 100
#define LISTINCREATMENT 10
#define OVERFLOW - 2
#define OK 1
#define ERROR 0
typedef int status;
typedef int ElemType;
typedef struct LNode {
    ElemType data;  //儲存的元素;
    struct LNode *next;  //指向下一個節點;
}LNode, *LinkList;

status GetElem_L(LinkList L, int i, ElemType &e) {
    //L為帶頭結點的單鏈表的頭指標;
    //當第i個元素存在時,其值賦給e並返回OK,否則返回ERROR
    LNode *p = L->next; //初始化,p指向第一個結點,j為計數器;
    int j = 1;   
    while (p&&j < i) {//順指標向後查詢,直到p指向第i個元素或p為空
        p = p->next;
        ++j;
    }
    if (!p || j>i) return ERROR;//第i個元素不存在
    e = p->data;//取第i個元素
    return OK;
}
status ListInsert_L(LinkList &L, int i, ElemType e) {
    //在帶頭結點的單鏈線性表L中第i個位置之前插入元素e
    LinkList p = L;
    int j = 0;
    while (p&&j < i - 1) {//尋找第i-1個結點
        p = p->next;
        ++j;
    }
    if(!p||j>i-1) return ERROR;
    LinkList s = (LinkList)malloc(sizeof(LNode));//生成新結點
    s->data = e;
    s->next = p->next;//插入L中
    p->next = s;
    return OK;
}
status ListDelete_L(LinkList &L, int i, ElemType &e) {
    //在帶頭結點的單鏈表L總,刪除第i個元素,並由e返回其值。
    LinkList p = L;
    int j = 0;
    while (p->next&&j < i - 1) {//尋找第i個結點,並令p指向其前驅
        p = p->next;
        ++j;
    }
    if (!(p->next) || j>i - 1) return OK;
    LinkList q = p->next;//刪除並釋放結點
    p->next = q->next;
    e = q->data;free(q);
    return OK;
}
void CreateList_L(LinkList &L, int n) {
    //逆位序輸入n個元素的值,建立帶表頭結點的單鏈表L
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;//先建立一個帶頭結點的單鏈表。
    LinkList p;
    for (int i = n;i > 0; --i) {
        p = (LinkList)malloc(sizeof(LNode));//生成新結點
        scanf_s("%d",&p->data);//輸入元素值
        p->next = L->next;//插入到表頭
        L->next = p;
    }
}
void DisplayList(LinkList L) {
    while (L->next) {
        printf("%3d", L->next->data);
        L = L->next;
    }
}

void main() {
    LinkList L;
    CreateList_L(L, 5);
    DisplayList(L);
}