数据结构学习笔记(1):顺序表

一.前言

如果一个数据结构的逻辑结构是线性表,而物理结构是顺序存储,那么这个数据结构就是一个顺序表。换而言之,使用顺序存储的线性表就是顺序表。

二.顺序表

2.1顺序表的可视化

如下图为顺序表在内存空间中的存储结构:

·顺序表将所有元素按照顺序存放在相邻位置,所以可以随时找到第i个位置的元素,所以顺序表支持随机存取。

2.2顺序表的定义

2.2.1静态分配

       顺序表的存储有静态分配和动态分配两种方式。静态分配是用一个数组来表示顺序表,因为数组的大小不变,所以叫静态分配。定义代码如下:

#define MaxSize 10

typedef struct

{

Elemtype data[MaxSize];

int Length;

}SqList;

       代码直接向计算机申请了长度为Maxsize*sizeof(Elemtype)的内存的数组作为顺序表的元素存储空间,同时申请了一个整型变量Length来记录当前顺序表长度。(PS:Elemtype指的是你想要使用的元素类型,可以是整型变量、浮点型等)。

2.2.2动态分配

       动态分配相比静态分配,能够更好的适应项目所需的内存大小,不需要一开始就分配好所需的全部内存。它的定义代码如下:

#define InitSize 100

typedef struct

{

Elemtype *data;

int Length,MaxSize;

}SeqList;

       动态分配定义了Length来记录当前顺序表的长度,MaxSize来记录当前设定的顺序表最大长度。并且申请了一个指针来指向顺序表的数据域表头。

2.3顺序表的初始化

2.3.1静态分配的初始化

       下面是静态分配的初始化代码:

void InitList(SqList &L)

{

/* for(int i=0;i<MaxSize;i++)

{

L.data[i]=0;

}*/

L.Length=0;

}

       先将顺序表L传入函数中,然后将顺序表中所有元素设为0(表示为空,还有一个目的是防止有脏数据,这一步可做可不做),随后将Length设为0表示为空表即可。

2.3.2动态分配的初始化

       下面是动态分配初始化代码:

void InitList(SeqList &L)

{

L.data=(Elemtype*)malloc(sizeof(Elemtype)*InitSize);

L.Length=0;

L.MaxSize=InitSize;

}

       这段代码首先申请了一段连续的内存,内存大小为InitSize个Elemtype的大小,malloc函数的能够申请内存,而前面的(Elemtype*)是为了将空间强转为元素所需的空间类型。

       随后将MaxSize设置为InitSize,将Length设置为0就结束了。

2.4顺序表的销毁

       如果我们不再使用一个顺序表,那么我们会将其销毁。当然,如果是使用数组的静态分配,计算机会自动释放其内存空间。但是如果是动态分配申请的内存,那么计算机将无法自动释放空间。下面是销毁的代码:

void DestroyList(SeqList &L)

{

L.Length=0;

Free(L.data);

}

2.5顺序表的扩容

       在这里静态表不做讨论,因为它的大小固定无法改变。下面是对动态分配顺序表扩容的代码:

void AddSize(SeqList &L, int n)

{

Elemtype *a=L.data;

L.data=(Elemtype*)malloc((n+L.MaxSize)*sizeof(Elemtype));

L.MaxSize=n+L.MaxSize;

for(int i=0;i<L.Length;i++)

{

L.data[i]=a[i];

}

free(a);

}

       这里我们重新申请一片内存空间,然后把数据搬到新空间中,再释放原空间即可。

2.6顺序表查询对应元素

       如果我们要在顺序表中查询一个特定的元素,并返回它的位置,代码如下:

int LocateElem(SeqList L, Elemtype e)

{

for(int i=0;i<L.Length;i++)

{

if(L.data[i]==e)

{

return i;

}

}

printf(“没有找到”);

return -1;

}

2.7查询第i个位置顺序表的元素

       因为顺序表支持随机存取,所以这个算法时间复杂度为O(1):

Elemtype GetElem(SeqList L, int i)

{

if(i<0||i>L.Length-1)

{

printf(“位次不合法”);

return  ;

}

return L.data[i];

}

2.8在顺序表中插入元素

       如果要在顺序表中插入一个元素,代码如下:

bool ListInsert(SeqList &L, Elemtype e, int i)

{

if(L.Length==L.MaxSize)

{

printf(“顺序表满,无法插入”);

return false;

}

for(int j=L.Length-1;j>=i;j--)

{

L.data[j+1]=L.data[j];

}

L.data[i]=e;

L.Length+=1;

return true;

}

       这个算法的最好情况是插在表尾,只需要执行一次代码;最差是插在表头,需要执行n次。因此它的时间复杂度为O(n)。

2.9删除顺序表中元素

       如果我们要删除顺序表中指定位置的元素,并返回其值,代码为:

bool ListDelet(SeqList &L, Elemtype &e, int i)

{

if(i>L.Length-1||i<0)

{

printf(“位次非法”);

return false;

}

e=L.data[i];

for(int j=i;j<L.Length-1;j++)

{

L.data[j]=L.data[j+1];

}

L.Length-=1;

return true;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值