• 线性表的顺序存储(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
    ",L.length);
    
            /*插入数据*/
        for(j=1;j<=5;j++)
            ListInsert(&L,1,j);
        printf("在L的表头依次插入1~5后:L.data=");
        ListTraverse(&L);  //遍历输出
        printf("
    ");
    
        printf("L.length=%d 
    ",L.length);
        i = ListEmpty(&L); //判断是否为空
        printf("L 是否为空:i=%d(1:是 0:否)
    ",i); 
    
        i =ClearList(&L); //清空线性表
        printf("清空L后:L.length=%d
    ",L.length);
        i = ListEmpty(&L);//判断是否为空
        printf("L 是否为空:i=%d(1:是 0:否)
    ",i); 
    
        for(j=1;j<=10;j++)  /*插入数据*/
            ListInsert(&L,j,j);
        printf("在L的表尾依次插入1~10后:L.data=");
        ListTraverse(&L);
        printf("
    ");
        printf("L.length=%d
    ",L.length);
    
    
        GetElem(&L,5,&e); //取得5号元素
        printf("L中第五个元素=%d
    ",e);
    
        for(j=7;j<9;j++){
        k=LocalElem(&L,j);    //判断是否存在元素
        if(k)
            printf("存在%d号元素=%d
     ",j,k);
        else
            printf("No存在%d号元素
    ");
        }
    
        k=ListLength(&L);
        for(j=k+1;j>=k;j--){    
            i=ListDelete(&L,j,&e); //删除第j个元素
        if(i == ERROR)
            printf("删除第%d个数据失败
    ",j);
        else
            printf("删除第%d个的元素值为:%d
    ",j,e);
        }    
        printf("依次输出L的元素:");
        ListTraverse(&L);
    
        j=8; 
        ListDelete(&L,j,&e);  //删除8号元素
        printf("删除第%d个的元素值为:%d
    ",j,e);
        printf("依次输出L的元素:");
        ListTraverse(&L);
        printf("
    ");
    
        /*合并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代码实现见下一篇。

  • 相关阅读:
    C# 递归查找树状目录
    C#递归计算树形菜单
    使用StringBuilder写XML遭遇UTF-16问题
    Error: 'The service did not respond in a timely fashion'
    no suitable method found to override
    Could not load file or assembly "win32_x86dotnet1crdb_adoplus.dll' or one of its dependencies.
    Unable to find the requested .Net Framework Data Provider
    Call JMS Web Service
    Remove Mapping
    卸载windows服务
  • 原文地址:https://www.cnblogs.com/liuzeyu12a/p/10293766.html
Copyright © 2020-2023  润新知