zoukankan      html  css  js  c++  java
  • 线性表-顺序存储结构(即数组)

    1、定义

    线性表:零个或多个元素组成的有限序列。第一个无前驱,最后一个无后继,其余元素都有一个前驱和后继。元素的个数为n。

    数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。例如,编程语言中的整型,浮点型等。

    抽象数据类型ADT:对数据类型进行抽象,抽取出事务具有的普遍性的本质,是特征的概括,而不是细节。(数据类型和相关的操作捆绑在一起)

       线性表抽象数据类型(List):

       Data:线性表的数据对象集合为{a,b,c...},每一个元素的数据类型为DataType

       Operation: InitList(*L),初始化,判断,取值,返回,插入...

    ADT: 
        线性表List
    Data:
        线性表的数据对象集合为{a1,a2,...,an},每个元素类型为DataType。除了第一个无前驱,最后一个无后继,
        其他每个元素都有一个字节前驱和直接后继结点。数据元素间关系一对一。
    Operation:
        InitList(*L);//初始线性表,创建空表
        ClearList(*L);//清空线性表数据
        ListEmpty(L);//判断列表是否为空
        ListLength(L);//获取线性表的长度
        GetElem(L,i,* e);//获取指定位置的元素,返回在指针元素中
        LocateElem(L,e);//查找元素在线性表中的位置
        ListInsert(*L,i,e);//向线性表中指定位置插入元素
        ListDelete(*L, i, *e);//删除指定位置处的元素

    2、线性表的顺序存储结构

    类似于数组,元素依次排放。顺序结构封装的三个属性:数据起始地址,线性表最大长度,当前线性表长度。线性表是从1开始,而数组是从0开始。

       插入:首先判断插入删除的位置是否合理,然后从表尾至插入位置依次向后移动一位,完成后插入元素。表长加1。

       删除:首先去除需要删除的元素,然后删除位置后面的元素开始依次向前移动一位。此时,最后一位元素清零。表长减1。

       线性表的查找读取为0(1),插入和删除都是0(n)。

       查找:由于时顺序存储,所以可以根据地址运算查找元素,复杂度为O(1)。

       假设类型数据占用C个字节存储单元,那每个元素相隔C个  字节Loc(ai+1)=Loc(ai)+C。

       优点:无需为表示表中的元素之间的逻辑关系而增加额外的存储空间,可以快速的存取表中的任意位置的元素。

       缺点:插入和删除时需要移动大量元素,当线性表长度变化较大时,难以确定存储空间的容量。可能造成存储空间碎片。

    3、顺序线性表的实现

    #include <stdio.h>
    #include <stdlib.h>
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    #define MAZSIZE 20  //线性表的最大存储空间,使用数组实现
    
    typedef int STATUS;  //用STATUS来表示函数返回状态码,是上面定义的OK等数据状态
    typedef int ELEMTYPE;  //ELEMTYPE是表示我们存储数据的类型,根据情况而定,这里设置为int
    
    typedef struct {
        ELEMTYPE data[MAZSIZE];   //数组存储数据元素
        int length;               //线性表的当前长度
    }SqList;                      //表名
    
    //四个基本操作:初始,清空,判断是否为空,获取长度(形参的类型与是否需要修改有关)
    STATUS InitList(SqList* L);   //需要改变线性表
    STATUS ClearList(SqList* L);  //需要改变线性表
    STATUS ListEmpty(SqList L);   //只需要读取
    int ListLength(SqList L);     //只需要读取
    
    //四个元素操作,获取指定位置元素,获取指定元素的位置,插入,删除
    STATUS GetElem(SqList L, int i, ELEMTYPE* e);
    int GetLocate(SqList L, ELEMTYPE e);
    STATUS ListInsert(SqList* L, int i, ELEMTYPE e);
    STATUS ListDelete(SqList* L, int i, ELEMTYPE* e);
    
    void PrintList(SqList L);
    
    //四个基本操作:初始,清空,判断是否为空,获取长度
    //初始化
    STATUS InitList(SqList* L)
    {
        L->length = 0;
        for (int i = 0; i < MAZSIZE; i++)
        {
            L->data[i] = 0;
        }
        return OK;
    }
    
    //清空
    STATUS  ClearList(SqList* L)
    {
        L->length = 0;
        for (int i = 0; i < MAZSIZE; i++)
        {
            L->data[i] = 0;
        }
        return OK;
    }
    
    //判断列表是否为空
    STATUS ListEmpty(SqList L)
    {
        if (L.length > 0)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    
    //获取线性表的长度
    int ListLength(SqList L)
    {
        return L.length;
    }
    
    
    //获取指定位置元素
    STATUS GetElem(SqList L, int i, ELEMTYPE* e)
    {
        if (L.length == 0 || i < 1 || L.length < i)
            return ERROR;
        *e = L.data[i - 1];  //线性表中的数据和正常一样,从1开始,而数组是从0开始
        return OK;
    }
    
    //获取指定元素的位置
    int GetLocate(SqList L, ELEMTYPE e)
    {
        if (L.length == 0)
            return ERROR;
        int i = 0;
        for (; i < MAZSIZE; i++)
            if (L.data == e)
                break;
        if (i >= MAZSIZE)
            return ERROR;
    
        return (i + 1);
    }
    
    //插入
    STATUS ListInsert(SqList* L, int i, ELEMTYPE e)
    {
        if (i<1 || i>L->length+1||L->length==MAZSIZE)
            return ERROR;
        for (int k =L->length; k >= i; k--)
        {
            L->data[k] = L->data[k-1];
        }
        L->data[i - 1] = e;
        L->length++;
        return OK;
    }
    
    //删除
    STATUS ListDelete(SqList* L, int i, ELEMTYPE* e)
    {
        if (L->length == 0 || i<1 || i>L->length)
            return ERROR;
        *e = L->data[i - 1];
        for(; i < L->Length ;i++ )
        {
            L->data[i - 1] = L->data[i];
        }
        L->data[L->length - 1] = 0;
        L->length--;
        return OK;
    }
    
    //打印
    void PrintList(SqList L)
    {
        printf_s("print the List
    ");
        for (int i = 0; i < L.length; i++)
        {
            printf_s("%d ", L.data[i]);
        }
        printf_s("
    ");
    }
    
    int main()
    {
        SqList L;
        ELEMTYPE e;
        printf_s("1.Initial List
    ");
        InitList(&L);
    
        printf_s("2. Insert Element 1-10
    ");
        for(int i = 1; i <= 10; i++)
            ListInsert(&L,i,i);
    
        printf_s("3. Insert 7 at the Location of 5
    ");
        ListInsert(&L, 5, 7);
    
        PrintList(L);
    
        printf("3.ListDelete the first:
    ");
        ListDelete(&L, 1, &e);
        printf("%d 
    ", e);
    
        printf("4.ListDelete the end:");
        ListDelete(&L, ListLength(L), &e);
        printf("%d 
    ", e);
    
        PrintList(L);
    
        printf("5.1 find element use GetElem by index(6): ");
        GetElem(L, 6, &e);
        printf("%d 
    ", e);
    
        printf("5.1 find element:256 index by LocateElem:");
        printf("%d 
    ", GetLocate(L, 256));
    
        printf("6.Get List length:%d
    ", ListLength(L));
    
        printf("7.ClearList
    ");
        ClearList(&L);
        if (ListEmpty(L) == OK)
            printf("8.ListEmpty
    ");
    
        system("pause");
        return 0;
    }

  • 相关阅读:
    SpringBoot页面访问处理
    体验SpringBoot
    体验SpringBoot
    Scala基础
    修改容器配置使其永久生效
    [徐培成系列实战课程]docker篇
    v1.0.2-2017.04.26
    修改容器的hosts文件
    配置spark集群
    配置docker容器上ssh无密登录
  • 原文地址:https://www.cnblogs.com/lemonzhang/p/12313049.html
Copyright © 2011-2022 走看看