線性表的順序存儲(C代碼實現)


線性表的順序存儲--

線性表是最基本、最簡單、也是最常用的一種數據結構。線性表(linear list)數據結構的一種,一個線性表是n個具有相同特性的數據元素的有限序列。

線性表示什么?借助網上大佬的一個例子

 

小學生放學都是要按順序排隊的,一個接一個,每個小學生的前后位置是固定的,這樣便於迅速清點。

 

其實這就是一個線性表,從這件事里我們就可以找到很多關於線性表的特性,如

 

1、線性表是一個序列,它是有順序的(排隊)

 

2、第一個元素無前驅,最后一個無后繼,其他每個元素都有一個前驅和后繼(一個接一個)

 

3、元素是有限的(小學生的個數是有限的)

 

4、數據類型都相同(都是小學生在排隊)

那么我們如何定義一個節點呢?

 /*定義線性表類型*/
  typedef struct{
    ElemType data[MAXSIZE];
     int length;
}sqList;

  

結構較簡單,一個數組用於存放元素信息 和一個長度用於下面操作

 

代碼實現的功能包括線性表的初始化,判斷是否為空、清空、增加元素、刪除元素、合並線性表等操作。

 

#include <stdio.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20   /*初始化存儲空間*/

/*取別名,便以操作*/
typedef int Status;
typedef int ElemType;

/*定義線性表類型*/
typedef struct{
    ElemType data[MAXSIZE];
    int length;
}sqList;

/*初始化順序線性表*/
Status InitList(sqList *L){
    L->length=0;
    return OK;
}

/*初始條件:順序表已存在,操作結果:若L為空,則返回TRUE,否則返回FALSE*/
Status ListEmpty(sqList* L){
    if(L->length==0)
        return TRUE;
    else
    return FALSE;
}

/* 初始條件:順序線性表L已存在。操作結果:將L重置為空表 */
Status ClearList(sqList* L){
    L->length=0;
    return OK;
}

/*初始條件:順序線性表L已存在。操作結果:獲取線性表的長度*/
Status ListLength(sqList* L){
    return L->length;
}

/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */
/* 操作結果:用e返回L中第i個數據元素的值,注意i是指位置,第1個位置的數組是從0開始 */
Status GetElem(sqList* L,int i, ElemType* e){
    if(i<1 || i>L->length)
        return ERROR;
    else
        *e = L->data[i-1];
        return OK;
} 

/* 初始條件:順序線性表L已存在 */
/* 操作結果:返回L中第1個與e滿足關系的數據元素的位序。 */
/* 若這樣的數據元素不存在,則返回值為0 */
Status LocalElem(sqList* L,ElemType e){
    int i;
    if(L->length==0)
        return ERROR;
    for(i=0;i<L->length;i++)
            if(e==L->data[i])
                break;

    if(i>=L->length)   //沒有找到相匹配的元素
        return 0;
        return i+1;
}

/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L), */
/* 操作結果:在L中第i個位置之前插入新的數據元素e,L的長度加1 */
Status ListInsert(sqList* L,int i,ElemType e){

    int k;
    if(L->length == MAXSIZE) return ERROR;
    if(i<1 || i>L->length+1) return ERROR;
    for(k=L->length-1;k>=i-1;k--)
        L->data[k+1]=L->data[k];
    L->length++;
    L->data[i-1]=e ;
    return OK;
}

/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */
/* 操作結果:刪除L的第i個數據元素,並用e返回其值,L的長度減1 */
Status ListDelete(sqList* L,int i,ElemType* e){

    int k;
    if(i<1 || i>L->length) return ERROR;
    else
        *e = L->data[i-1];
    for(k=L->length-1;k>i;k--)
        L->data[k]=L->data[k+1];
    L->length--;
    return OK;
}

/* 初始條件:順序線性表L已存在 */
/* 操作結果:依次對L的每個數據元素輸出 */
Status ListTraverse(sqList* L){
    int i;
    for(i=0;i<L->length;i++)
        printf("%d ",L->data[i]);
    return OK;
}

/*求並集*/
void unioList(sqList* La,sqList* Lb){

    int La_len,Lb_len,i;
    ElemType e;
    La_len = La->length;
    Lb_len = Lb->length;

    for(i=1;i<=Lb_len;i++){
    /*用e來獲取Lb線性表中的值*/
    GetElem(Lb,i,&e);
    if(!LocalElem(La,e))
        ListInsert(La,++La_len,e);
    }
}

int main(){

    //構造一個有10個數的Lb
    sqList Lb;
    sqList L;
    ElemType e;
    int i,j,k;

    InitList(&L); //初始化
    printf("初始化L后:L.length=%d\n",L.length);

        /*插入數據*/
    for(j=1;j<=5;j++)
        ListInsert(&L,1,j);
    printf("在L的表頭依次插入1~5后:L.data=");
    ListTraverse(&L);  //遍歷輸出
    printf("\n");

    printf("L.length=%d \n",L.length);
    i = ListEmpty(&L); //判斷是否為空
    printf("L 是否為空:i=%d(1:是 0:否)\n",i); 

    i =ClearList(&L); //清空線性表
    printf("清空L后:L.length=%d\n",L.length);
    i = ListEmpty(&L);//判斷是否為空
    printf("L 是否為空:i=%d(1:是 0:否)\n",i); 

    for(j=1;j<=10;j++)  /*插入數據*/
        ListInsert(&L,j,j);
    printf("在L的表尾依次插入1~10后:L.data=");
    ListTraverse(&L);
    printf("\n");
    printf("L.length=%d\n",L.length);


    GetElem(&L,5,&e); //取得5號元素
    printf("L中第五個元素=%d\n",e);

    for(j=7;j<9;j++){
    k=LocalElem(&L,j);    //判斷是否存在元素
    if(k)
        printf("存在%d號元素=%d\n ",j,k);
    else
        printf("No存在%d號元素\n");
    }

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

    j=8; 
    ListDelete(&L,j,&e);  //刪除8號元素
    printf("刪除第%d個的元素值為:%d\n",j,e);
    printf("依次輸出L的元素:");
    ListTraverse(&L);
    printf("\n");

    /*合並La ,Lb*/
    InitList(&Lb);
    /*插入數據*/
    for(j=10;j<=100;j+=10){
        ListInsert(&Lb,1,j);
    }
    unioList(&L,&Lb);   //合並
    printf("依次輸出合並了Lb的L的元素:");
    ListTraverse(&L);

    return 0;
}

 

  

 

 

注意點:

1、線性表其實可以理解是數組的一種特殊表示,但線性表的數據是從1開始的,數組的元素是從0開始的。

2、線性表的順序存儲結構,在存、讀哪個數據的時候,不管在哪個位置,時間復雜度都是O(1),而在插入和刪除時,時間復雜度時O(n)。

3、線性表的優點:無需為表示表中元素之間的邏輯關系而增加額外的存儲空間;可以快速的存取表中的任意一個位置的元素。

4、線性表的缺點:插入和刪除數據時需要移動大量的數據;當線性表長度變化較大時,難以確定存儲空間的容量;容易造成存儲空間的 ”碎片“

Java代碼實現見下一篇。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM