线性表-顺序存储结构(即数组)

Posted lemonzhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表-顺序存储结构(即数组)相关的知识,希望对你有一定的参考价值。

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)。

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

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

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;
}

技术图片

 

以上是关于线性表-顺序存储结构(即数组)的主要内容,如果未能解决你的问题,请参考以下文章

java算法--稀疏数组

数据结构之顺序表(数组)和链表

线性表和顺序表的区别

线性表的顺序存储结构

线性表

线性表的简单应用