線性表Linear List-線性表的順序表示和實現

線性表Linear List

線性表:線性表(Linear List)是由n(n≥0)個數據元素(結點)a[0],a[1],a[2]…,a[n-1]組成的有限序列c++

其中:算法

  • 數據元素的個數n定義爲表的長度 = "list".length() ("list".length() = 0(表裏沒有一個元素)時稱爲空表)數組

  • 將非空的線性表(n>=0)記做:(a[0],a[1],a[2],…,a[n-1])數據結構

  • 數據元素a[i](0≤i≤n-1)只是個抽象符號,其具體含義在不一樣狀況下能夠不一樣函數

 

線性表的順序存儲結構

//線性表的順序存儲結構
typedef struct{
    int *elem; //存儲空間基址,即線性表的起始位置,elem指向int的指針
    int length; //當前長度
    int listsize; //當前分配的存儲容量
}SqList;

 

線性表的順序表示和實現

線性表的順序表示指的是一組地址連續的存儲單元依次存儲線性表的數據元素。spa

線性表的順序存儲結構是一種隨機存儲的存儲結構。指針

由於內存中的地址空間是線性的,所以,用物理上的相鄰實現數據元素之間的邏輯相鄰關係是既簡單,又天然的。code

因爲數組類型也有隨機存儲的特性,所以一般用數組來描述數據結構中的順序存儲結構。內存

因爲線性表的長度可變,且所需最大存儲空間隨問題不一樣而不一樣,則在C語言中可用動態分配的一維數組。input

線性表的起始位置=基地址,每一個數據元素佔1個存儲地址

線性表的順序表示和實現:

//Sequence List
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

#define LIST_INIT_SIZE 10
#define LISTINCREMENT 2
#define OVERFLOW -2
#define OK 1
#define ERROR 0

//爲內置類型int建立兩個別名,新的名字
typedef int Status;
typedef int ElemType;

//線性表的順序存儲結構
typedef struct{
    int *elem; //存儲空間基址,即線性表的起始位置
    int length; //當前長度
    int listsize; //當前分配的存儲容量
}SqList;

//初始化順序表
Status InitList_Sq(SqList* L);
//順序表中插入元素
Status ListInsert_Sq(SqList* L,int i,ElemType e);
//順序表的合併
Status MergeList_Sq(SqList La,SqList Lb,SqList* Lc);
//順序表元素的輸出
Status ListPrint_Sq(SqList* L);
//順序表元素的刪除
//刪除第i個位置上的元素,並用e返回其值
Status ListDelete_Sq(SqList* L,int i,ElemType *e);

int main()
{
    SqList La,Lb,Lc;
    int i = 1;
    ElemType num = 0;
    //初始化順序表La
    InitList_Sq(&La);
    //初始化順序表Lb
    InitList_Sq(&Lb);

    printf("Please input the number(end by -1):\n");
    while(1)
    {
        scanf("%d",&num);
        if(num == -1)
            break;
        ListInsert_Sq(&La,i,num);
        i++;
    }
    ListPrint_Sq(&La);

    i = 1;
    printf("Please input the number(end by -1):\n");
    while(1)
    {
        scanf("%d",&num);
        if(num == -1)
            break;
        ListInsert_Sq(&Lb,i,num);
        i++;
    }
    ListPrint_Sq(&Lb);

    //順序表合併的算法函數
    MergeList_Sq(La,Lb,&Lc);

    printf("MergeList OK\n");
    ListPrint_Sq(&Lc);\
    int dl=0;
    ListDelete_Sq(&Lc,4,&dl);
    printf("Delete OK  %d\n",dl);
    ListPrint_Sq(&Lc);
}

Status MergeList_Sq(SqList La,SqList Lb,SqList* Lc)
{
    ElemType *pa=La.elem,*pb=Lb.elem,*pc;
    ElemType *pa_last,*pb_last;
    Lc->listsize = Lc->length = La.length+Lb.length;
    pc= Lc->elem = (ElemType*)malloc(Lc->listsize*sizeof(ElemType));//爲pc順序表分配內存空間
    if(!Lc->elem)
        exit(OVERFLOW);
    pa_last = La.elem + La.length - 1;
    pb_last = Lb.elem + Lb.length - 1;
    while(pa<=pa_last&&pb<=pb_last) //歸併
    {
        if(*pa<=*pb){
            *pc++ = *pa++;
        }else{
            *pc++ = *pb++;
        }
    }
    while(pa<=pa_last){ //插入La的剩餘元素
        *pc++ = *pa++;  //====>>*pc=*pa;pc++;pa++;//真的不推薦寫成*pc++ = *pa++;
    }
    while(pb<=pb_last) //插入Lb的剩餘元素
    {
        *pc++ = *pb++;
    }
    return OK;
}

/*
順序表的初始化操做就是爲順序表分配一個預約義大小的數組空間,並將線性表的當前長度設爲0
malloc分配指定的字節,並返回指向這塊內存的指針。若是分配失敗,則返回一個空指針(NULL)
*/
Status InitList_Sq(SqList* L)
{
    //
    L->elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L->elem) //若是順序表分配失敗
        exit(OVERFLOW);
    L->length = 0;//順序表的當前長度爲零
    L->listsize = LIST_INIT_SIZE;
    return OK;
}

/*
(ElemType*)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(ElemType));
realloc函數的做用:第一參數是指針,指向現有的一塊內存區域,第二個參數爲新的內存區域的大小
若是從新分配成功則返回指向被分配內存的指針,不然返回空指針NULL
該函數功能:在順序表L第i個位置插入元素e
*/
Status ListInsert_Sq(SqList* L,int i,ElemType e)
{
    ElemType *newbase,*p,*q;
    if(i<1 || i> L->length+1)
        return ERROR;
    if(L->length >= L->listsize)
    {
        newbase = (ElemType*)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(ElemType));
        if(!newbase)
            exit(OVERFLOW);
        L->elem = newbase;
        L->listsize += LISTINCREMENT;
    }
    q = &(L->elem[i-1]); //q爲元素的插入位置,是一個指針
    //&(L->elem[L->length-1])獲取線性表中最後一個元素的指針
    for(p=&(L->elem[L->length-1]);p>=q;--p)
    {
        *(p+1) = *p; //元素的位置右移
    }
    *q = e; //把元素e插入位置q
    ++L->length; //把當前順序表的長度加一

    return OK;
}



Status ListPrint_Sq(SqList* L)
{
    int i = 0;
    ElemType num = 0;
    for(i=0;i<L->length;i++)
    {
        num = L->elem[i];
        printf("No.%d\t%d\n",i,num);
    }

    return OK;
}

//在順序表L中刪除第i個元素,並用e返回其值
Status ListDelete_Sq(SqList* L,int i,ElemType *e)
{
    ElemType *p,*q;
    if(i<0||i>L->length){
        return ERROR;
    }
    p = &(L->elem[i-1]); //刪除元素的位置
    *e = *p;  //刪除元素的值

    q = L->elem+L->length-1;  //順序表中最後一個元素的位置
    for(++p;p<=q;++p)
    {
        *(p-1)=*p; //刪除元素以後的元素左移
    }
    --L->length; //順序表的長度減一
    return OK;
}

 

運行結果:

Please input the number(end by -1):
1
2
3
4
-1
No.0    1
No.1    2
No.2    3
No.3    4
Please input the number(end by -1):
5
6
7
8
-1
No.0    5
No.1    6
No.2    7
No.3    8
MergeList OK
No.0    1
No.1    2
No.2    3
No.3    4
No.4    5
No.5    6
No.6    7
No.7    8
Delete OK  4
No.0    1
No.1    2
No.2    3
No.3    5
No.4    6
No.5    7
No.6    8

Process returned 1 (0x1)   execution time : 11.704 s
Press any key to continue.

====END====

相關文章
相關標籤/搜索