大話數據結構學習(2)線性表的鏈式存儲結構

1、線性表的鏈式存儲結構:n個結點(結點存數據元素和後繼元素的指針),鏈接爲一個鏈表,即爲線性表(a1,a2,……,an)的鏈式存儲結構。
2、鏈式存儲結構的頭指針①頭指針是鏈表的必要元素!!無論鏈表是否爲空,頭指針均不爲空。②頭指針有標識作用,通常用來標識鏈表名。③頭指針指向鏈表的第一個結點(頭結點或第一個結點)。
3、頭結點:①頭結點不是必須的。②頭結點是爲了第一個元素前的插入或刪除和後面元素一樣,而設立的。放在第一個結點之前。數據域一般無意義,不過也可以存放鏈表長度。
4線性表的順序存儲結構鏈式存儲結構的對比:
這裏寫圖片描述
5、鏈式存儲結構代碼(以單鏈表爲例)

/************************************************************************/
/*                  (2)線性鏈式存儲                                     */
/************************************************************************/


#include <stdio.h>
#include <time.h>
#include <iostream>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MaxSize 30  //存儲空間初始分配量
typedef int Status;
typedef int ElemType;

extern Status visit(ElemType c);


/*  線性表的單鏈表存儲結構     */
typedef struct Node         //①定義Node結點:數據域+後繼結點地址的指針域;
{
    ElemType data;
    struct Node *next;
}Node;                                      //②typedef struct Node Node:Node可替換爲 struct Node

typedef struct Node *LinkList;      //定義LinkList鏈表,LinkList 可替換爲 struct Node *

//初始化順序線性表
Status InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node));      //產生頭結點,並使L指向此頭結點
    if(!(*L))                                               //存儲分配失敗
        return ERROR;                       
    (*L)->next =NULL;                           //令頭結點的指針域爲空
    return OK;
}


/*  初始條件:順序線性表L已經存在 */
/*  操作結果:若L爲空表,則返回TRUE,否則返回FALSE    */
Status ListEmpty(LinkList L)
{
    if (L->next == NULL)
        return TRUE;
    else
        return FALSE;
}

/*  初始條件:順序線性表L已經存在 */
/*  操作結果:將L重置爲空表    */
Status ClearList(LinkList L)
{
    LinkList p,q;
    p=(*L).next;        //p指向第一個節點
    while(p)                //若p不爲空,表示還沒到表尾,一直while循環
    {
        q=p->next;
        free(p);            //釋放每一個結點所佔的內存空間
        p=q;
    }
    (*L).next = NULL;   //  將頭結點指針域置爲空
    return OK;
}

/*  初始條件:順序線性表L已經存在 */
/*  操作結果:返回L中數據元素的個數*/
int ListLength(LinkList L)
{
    int k=0;
    LinkList p=L->next; //p指向L表的第一個結點
    while(p)
    {
        k++;
        p=p->next;
    }
    return k;
}



/*  初始條件:順序線性表已經存在,且1<=i<=LineList(L)   */
/*  操作結果:用e返回L中第i個數據元素的值    */
Status GetElem(LinkList L, int i,ElemType *e)
{
    int j;
    LinkList p;     //聲明一個結點p
    p=L->next;  //p指向鏈表的第一個結點
    j=1;
    while(p && j<i)
    {
        p=p->next;
        j++;
    }
    if (!p || j>i)          //如果p爲空,或j>i,則第i個元素不存在
        return ERROR;
    *e = p->data;       //否則,第i個數據存在,取出即可
    return OK;

}


/*  初始條件:順序線性表L已經存在 */
/*  操作結果:返回L中第1個與e滿足關係的數據元素的位序*/
int LocateElem(LinkList L,ElemType e)
{
    int i=0;
    LinkList p=L->next;
    while(p)
    {
        i++;
        if (e==p->data)
            return i;
        else
            p=p->next;

    }
    return 0;
}

/*  初始條件:順序線性表L已經存在 */
/*  操作結果:在L中第i個位置之前插入新的數據元素e,L的長度加1 */
Status ListInsert(LinkList *L,int i,ElemType e)
{
    int j;
    LinkList p,s;
    p=*L;
    j=1;
    while(p && j<i)
    {
        j++;
        p=p->next;
    }

    if (!p || j>i)
        return ERROR;   //第i個元素不存在
    s = (LinkList) malloc(sizeof(Node));    //生成新結點
    s->data =e;
    s->next=p->next;
    p->next =s;
    return OK;

}


/*  初始條件:線性順序表L已經存在     */
/*  操作結果:刪除L的第i個位置的數據元素,並用e返回其值,L的長度減1*/
Status ListDelete(LinkList *L,int i,ElemType *e)
{
    int j;
    LinkList p,q;
    p=*L;
    j=1;
    while(p->next && j<i)
    {
        j++;
        p=p->next;
    }
    if (!(p->next) || j>i)
        return ERROR;
    q=p->next;
    p->next=q->next;
    *e=q->data;
    free(q);    //系統回收該結點,釋放內存
    return OK;
}


/*  初始條件:順序線性表L已經存在 */
/*  操作結果:依次對L的每個元素輸出*/
Status ListTraverse(LinkList L)
{
    LinkList p=L->next; //p指向第一個結點
    while(p)
    {
        visit(p->data);
        p=p->next;
    }
    printf("\n");
    return OK;

}


/*隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(頭插法)*/
void CreateListHead(LinkList *L,int n)
{
    LinkList p;
    int i;
    srand(time(0)); //srand:產生隨機數,初始化隨機數種子
    *L=(LinkList) malloc(sizeof(Node));     //這句和下句,是生成一個新結點表示頭結點,指向NULL表示只有頭結點
    (*L)->next=NULL;    //先建立一個帶頭結點的單鏈表
    for (i=0;i<n;i++)
    {
        p=(LinkList)malloc(sizeof(Node));   //生成新的結點
        p->data=rand()%100+1;
        p->next=(*L)->next; //令p->next=NULL,從表頭插入
        (*L)->next = p;     //插入到表頭

    }

}
/*      尾插法     */
void CreateListTail(LinkList *L,int n)
{
    LinkList p,r;
    srand(time(0));
    *L = (LinkList)malloc(sizeof(Node));
    r=(*L);
    for(int i=0;i<n;i++)
    {
        p=(LinkList)malloc(sizeof(Node));
        p->data=rand()%100+1;
        r->next=p;
        r=p;    //將當前新結點定義爲表最終端的結點

    }
    r->next=NULL;

}

int main()
{
    LinkList L;
    ElemType e;
    Status i;
    int j,k;
    i=InitList(&L);
    printf("初始化鏈表L後,ListLength(L)=%d\n",ListLength(L));

    for (j=1;j<=5;j++)
    {
        i=ListInsert(&L,1,j);
    }
    printf("在表頭依次插入1~5之後:L.data=");
    ListTraverse(L);

    printf("ListLength(L)=%d\n",ListLength(L));
    i=ListEmpty(L);
    printf("L是否爲空:i=%d(1:是;0:否)",i);
    printf("\n");

    i=ClearList(L);
    i=ListEmpty(L);
    printf("ClearList之後,L是否爲空:i=%d(1:是;0:否)",i);

    printf("\n");
    for (j=1;j<=10;j++)
    {
        ListInsert(&L,j,j);
    }
    printf("在L的表尾依次插入1~10之後,L.data=");
    ListTraverse(L);
    printf("ListLength(L)=%d",ListLength(L));

    GetElem(L,5,&e);
    printf("第5個元素爲:%d\n",e);


    for(j=3;j<=4;j++)
    {
        k=LocateElem(L,j);
        if(k)
            printf("第%d個元素值爲%d\n",k,j);
        else
            printf("沒有值爲%d的元素\n",j);
    }


    k=ListLength(L);
    printf("k=ListLength(L)=%d\n",k);

    for(j=k+1;j>=k;j--)
    {
        i=ListDelete(&L,j,&e);      //刪除第j個數
        if (i == ERROR)
            printf("刪除第%d個數據失敗\n",j);
        else
            printf("要刪除的第%d個數據爲:%d",j,e);
    }
    printf("依次輸出L中的元素:");
    ListTraverse(L);

    j=5;
    ListDelete(&L,j,&e);
    printf("要刪除的第%d個數據爲%d",j,e);
    printf("依次輸出L中的元素:");
    ListTraverse(L);


    i=ClearList(L);
    printf("\n清空L後:ListLength(L)=%d\n",ListLength(L));
    CreateListHead(&L,5);
    printf("頭插法:");
    ListTraverse(L);

    i=ClearList(L);
    printf("\n清空L後:ListLength(L)=%d\n",ListLength(L));
    CreateListTail(&L,5);
    printf("尾插法:");
    ListTraverse(L);


    getchar();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章