第二章--线性表之顺序表


一、线性表的定义和基本操作

在这里插入图片描述

1.线性表的定义

在这里插入图片描述
在这里插入图片描述

2.线性表的基本操作

在这里插入图片描述
“带回来”解释:

在这里插入图片描述在main函数中传入x=1,但是在test函数中又改成了1024,实际上在内存中这个等于1024的是另一个x,然后在main函数中再次输出的时候输出的还是1,因为根本就没有改变x=1这个内存中的x的值

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、顺序表的定义

在这里插入图片描述

1.顺序表的定义

在这里插入图片描述

2.顺序表的实现

(1)、静态分配

在这里插入图片描述
在这里插入图片描述
在执行SqList L的时候就会给顺序表分配他所需要的空间

在这里插入图片描述
如果不设置默认值的话后两个数就会出现很奇怪的值

在这里插入图片描述
产生奇怪值的原因是在这个存储空间分配给这个顺序表之前存储了其他数据,所以会有脏数据,但是为什么说考研省略设置默认值的步骤,这是因为我们这里用的fo循环打印全部的内存本来就是违规的,而应该按照顺序表的长度打印。
在这里插入图片描述
在声明顺序表时,刚开始把他的length值设为0是必须做的。
在这里插入图片描述

(2)、动态分配

在这里插入图片描述
*data指针指向了顺序表中第一个数据元素的位置

在这里插入图片描述
malloc函数申请一整片连续的存储空间,free函数用来释放空间。
malloc函数会返回指向这一整片存储空间开始地址的一个指针。

分析动态实现的背后过程:
在这里插入图片描述
声明顺序表的数据元素类型是int类型,data指向数据表中的第一个元素。
然后实现一个InitList函数用于初始化一个动态分配方式实现的顺序表
在这里插入图片描述
然后实现一个函数拥有动态的增加顺序表的长度。

在这里插入图片描述
最后在main函数里调用相关的操作。
在这里插入图片描述执行完这句后计算机会在内存中开辟这样一小块空间。

在这里插入图片描述
执行完第二句代码之后data应该指向了malloc函数申请的空间的第一个位置

之后这里写的main函数省略了将数据填入顺序表的过程
然后执行增加动态数组长度。
在这里插入图片描述
然后开辟了新的空间,现在可以多存五个数据

在这里插入图片描述
因为malloc开辟了新的空间,之前存的数据都不在新的空间,所以需要一个for循环把数据存入新的空间。

在这里插入图片描述
由于增加了五个空间,所以要把最大空间增大5,最后调用free函数把之前创建的已经被新空间代替的p空间释放掉。

在这里插入图片描述
代码演示:

#include<stdio.h>
#include<stdlib.h>//malloc、free函数的头文件
#define InitSize 3 //默认的最大长度
typedef int ElemType;
//动态分配
typedef struct {
	//data是指示动态分配数组的指针,指向了顺序表中第一个元素的位置
	ElemType* data;
	int MaxSize;//顺序表的最大容量
	int length;//顺序表的当前长度
}SeqList;//顺序表的类型定义

//初始化一个动态分配方式实现的顺序表
void InitList(SeqList& L) {
	/*
	  用malloc函数申请一片连续的存储空间
	  malloc函数会返回指向这一整片存储空间开始地址的一个指针
	  这个返回的指针需要强转为你定义的数据元素类型指针
	  malloc函数的参数需要指明分配多大的连续内存空间
	  InitSize等于10时,分配的内存空间为10乘以sizeof(int)=10×4=40
	*/
	L.data = (int*)malloc(InitSize * sizeof(int));
	L.length = 0;
	L.MaxSize = InitSize;
}

/*
 实现一个函数用于动态的增加顺序表的长度
 &L获取L的地址
*/
void IncreaseSize(SeqList& L, int len) {
	int* p = L.data;
	L.data = (int*)malloc((L.MaxSize + len) * sizeof(int));
	for (int i = 0; i < L.length; i++)
	{
		L.data[i] = p[i];//将数据复制到新区域
	}
	L.MaxSize = L.MaxSize + len;//顺序表最大长度增加len
	free(p);//释放原来的内存空间
}

//再main函数里调用相关的操作
int main() {
	SeqList L;//声明一个顺序表
	InitList(L);//初始化顺序表
	//往顺序表里随便加几个元素
	L.data[0] = 1;
	L.data[1] = 2;
	L.data[2] = 3;
	L.length = 3;
	//扩大顺序表的容量
	IncreaseSize(L, 5);
	//遍历顺序表
	for (int i = 0; i < L.length; i++)
	{
		printf("%d\n",L.data[i]);
	}
	return 0;
}



在这里插入图片描述

在这里插入图片描述

3.顺序表的插入删除

在这里插入图片描述

(1)、插入

在这里插入图片描述要把C插入,就要把后边的全都往后移一格。

在这里插入图片描述

在这里插入图片描述当在位置9插入3时,运行代码之后3会插到data[8],但是位置7和8都是空的,
所以这个代码不够健壮

所以插入的比较好的代码应该写成:
在这里插入图片描述
代码演示:

#include<stdio.h>
#define MaxSize 3 //定义最大长度
typedef struct {
	int data[MaxSize]; //用静态“数组”来存数据元素
	int length; //顺序表的当权长度
}SqList; //属性表的类型定义
bool ListInsert(SqList& L, int i, int e) {
	
		if (i<1 || i>L.length+1) {//判断i的范围是否有效
			printf("因为i范围无效插入失败!\n");
			return false;
		}
		if (L.length >= MaxSize) //当前存储空间已满
		{
			printf("因为存储空间已满插入失败!\n");
			return false;
		}
		
		for (int j = L.length; j >= i; j--) //将第i个元素及之后的元素后移
		{
			L.data[j] = L.data[j - 1];
		}
		L.data[i - 1] = e;//再位置i处放e
		L.length++;//长度加1
		return true;
	}
void main() {
	SqList L;
	L.data[0] = 0;
	L.data[1] = 1;
	L.data[2] = 2;
	L.length = 3;

	ListInsert(L,3,8);
	printf("当前顺序表的内容为:\n");
	for (int i = 0; i < L.length; i++)
	{
		printf("L.data[%d]=%d\n",i,L.data[i]);
	}
}

插入操作的时间复杂度:

在这里插入图片描述

(2)、删除

在这里插入图片描述
删除之后需要把后边的全部往前移一位,同时要把length的值减一

在这里插入图片描述
代码实现:

&L:是删除哪个顺序表
i:要删除第几个数据元素
&e:用这个元素把此次删除的数据元素返回
在这里插入图片描述
在这里插入图片描述
代码演示:

#include<stdio.h>
#define MaxSize 10
typedef struct {
	int data[MaxSize];
	int length;
}SqList;
void InitList(SqList &L) {
	L.length = 0;
}
bool ListDelete(SqList& L, int i, int& e) {
	if (i<1||i>L.length) //判断i的范围是否有效
	{
		return false;
	}
	e = L.data[i - 1]; //将被删除的元素赋值给e
	for (int j = i; j < L.length; j++)//将第i个元素前移
	{
		L.data[j - 1] = L.data[j];
	}
	L.length--; //线性表长度减一
	return true;
}
int main() {
	SqList L; //声明一个顺序表
	InitList(L); //初始化顺序表
	//插入几个元素
	L.data[0] = 1;
	L.data[1] = 2;
	L.data[2] = 3;
	L.data[3] = 4;
	L.length = 4;
	int e = -1; //用变量e把删除的元素带回来
	if (ListDelete(L, 3, e)) {
		printf("已删除第3个元素,删除元素的值为=%d\n",e);
	}
	else
	{
		printf("位序i不合法,删除失败\n");
	}
	for (int i = 0; i < L.length; i++)
	{
		printf("L[%d]=%d\n",i,L.data[i]);
	}
}

删除操作的时间复杂度:

在这里插入图片描述
在这里插入图片描述

4.顺序表的查找

1.按位查找

(1)静态分配

在这里插入图片描述

(2)动态分配

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述按位查找的时间复杂度:

在这里插入图片描述

2.按值查找

在这里插入图片描述
在这里插入图片描述
结构类型的数据元素不能这样

在这里插入图片描述
在这里插入图片描述

按值查找的时间复杂度:
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸葛东_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值