线性表的顺序表示和实现

线性表可以用顺序存储结构和链式存储结构。用顺序存储结构实现的线性表称作顺序表,用链式存储结构实现的线性表称作链表。链表主要有单链表,循环单链表和双向循环链表。

顺序表的存储结构

实现顺序存储结构的方法是使用数组。数组满足顺序表的特点:逻辑上相邻的元素在物理存储上也相邻。

//结构体定义
typedef struct {
	Datatype list[Maxsize];//Datatype表示存储的元素的数据类型,数组用来存储数据
	int size;//元素个数
}Sequlist;

其中数组可以动态申请

Datatype* list;//数组的首地址
int maxlength;//最大分配的存储容量
int size;//元素个数

顺序表操作的实现(数组是静态数组)

初始化顺序表:void Listintiate(Sequlist*L)

void Listintiate(Sequlist*L) {
	L->size = 0;//元素个数初始化为0
}

求当前元素个数:int Listlength(Sequlist* L) 

int Listlength(Sequlist* L) {
	return L->size;//返回元素个数
}

插入元素:int Listinsert(Sequlist* L, int i, Datatype x)

i表示插入的位置,x表示要插入的元素

1.先判断参数i是否合法和顺序表是否已满

2.如果均没有,将数组中的元素从最后的位置开始向后移动,直到空出指定的位置

3.插入元素,更新元素个数

int Listinsert(Sequlist* L, int i, Datatype x) {
	if (L->size >= Maxsize) {
		printf("顺序表已满\n");
		return 0;
	}
	else if (i<0 || i>L->size) {
		printf("参数i不合适\n");
		return 0;
	}
	else {
		for (int j = L->size;j > i;j--) {
			L->list[j] = L->list[j - 1];
		}
		L->list[i] = x;
		L->size++;
		printf("存入数据成功\n");
		return 1;
	}
}

删除元素:int Listdelete(Sequlist* L, int i, Datatype* x)

返回数据类型:1——删除成功,0——删除失败

i需要删除的位置的下标,x存储被删除的元素

1.判断顺序表是否为空,参数i是否合法

2.找到需要删除的元素,存储在x中

3.将位置i后面的元素向前移动,更新顺序表元素个数

int Listdelete(Sequlist* L, int i, Datatype* x) {
	if (L->size <= 0) {
		printf("顺序表为空\n");
		return 0;
	}
	else if (i<0 || i>L->size) {
		printf("参数i不合适\n");
		return 0;
	}
	else {//如果i要表示第几个,i改为i-1
		*x = L->list[i];
		for (int j = i;j < L->size;j++) {
			L->list[j] = L->list[j + 1];
		}
		L->size--;
		printf("删除数据成功\n");
		return 1;
	}
}

取元素:int Listget(Sequlist* L, int i, Datatype* x)

返回类型:1——获取成功,0——获取失败

i表示想要获取的元素的下标,x存储获取到的元素

int Listget(Sequlist* L, int i, Datatype* x) {
	if (i<0 || i>=L->size) {
		printf("参数i不合适\n");
		return 0;
	}
	else if (L->size == 0) {
		printf("顺序表为空\n");
		return 0;
	}
	else {
		*x = L->list[i];
		return 1;
	}
}

顺序表操作的效率分析

顺序表中的插入与删除操作时顺序表中时间复杂度最高的操作。

插入操作:若i=size,在最后位置插入,根本无需移动(特别快);若i=0,在最前面插入,表中元素全部要后移(特别慢);考虑在各种位置插入(共n+1种可能)的平均移动次数:设Pi是在第i个存储位置插入一个数据元素的概率,顺序表中的数据元素个数为n,当在顺序表的任何位置上插入数据元素的概率相等时,有Pi=1/(n+1),则 插入时的平均移动次数为:(1/n+1)(1+2+3+4+……+n)=n/2

同理可得,顺序表删除元素的平均移动次数为:(1/n)(1+2+3+4+……+n-1)=(n-1)/2

顺序表的优点:算法简单,内存单元利用率较高,缺点:需要预先去欸的那个元素的 最大个数

完整的代码:

#include <stdio.h>
#include <stdlib.h>
//顺序表 
#define Maxsize 80
typedef int Datatype;
typedef struct {
	Datatype list[Maxsize];
	int size;
}Sequlist;
//初始化顺序表
void Listintiate(Sequlist*L) {
	L->size = 0;
}
//元素个数
int Listlength(Sequlist* L) {
	return L->size;
}
//插入数据
int Listinsert(Sequlist* L, int i, Datatype x) {

	if (L->size >= Maxsize) {
		printf("顺序表已满\n");
		return 0;
	}
	else if (i<0 || i>L->size) {
		printf("参数i不合适\n");
		return 0;
	}
	else {
		int j;
		for (j = L->size;j > i;j--) {
			L->list[j] = L->list[j - 1];
		}
		L->list[i] = x;
		L->size++;
		printf("存入数据成功\n");
		return 1;
	}
}
//删除数据
int Listdelete(Sequlist* L, int i, Datatype* x) {
	if (L->size <= 0) {
		printf("顺序表为空\n");
		return 0;
	}
	else if (i<0 || i>L->size) {
		printf("参数i不合适\n");
		return 0;
	}
	else {
		int j;
		*x = L->list[i];
		for (j = i;j < L->size;j++) {
			L->list[j] = L->list[j + 1];
		}
		L->size--;
		printf("删除数据成功\n");
		return 1;
	}
}
//取数据
int Listget(Sequlist* L, int i, Datatype* x) {
	if (i<0 || i>=L->size) {
		printf("参数i不合适\n");
		return 0;
	}
	else if (L->size == 0) {
		printf("顺序表为空\n");
		return 0;
	}
	else {
		*x = L->list[i];
		return 1;
	}
}
//输出顺序表
void Listoutput(Sequlist* L) {
	int i;
	for (i = 0;i < L->size;i++) {
		printf("%-6d", L->list[i]);
	}
}
int main() {
	Sequlist List;
	Listintiate(&List);
	int n;
	printf("请输入要出入的元素个数n:");
	scanf("%d", &n);
	//插入数据
	int i;
	for (i = 0;i < n;i++) {
		//要输入的数据
		Datatype x;
		scanf("%d", &x);
		Listinsert(&List, i, x);
	}
	printf("顺序中元素的个数为%d\n",Listlength(&List));
	//数据输出
	Listoutput(&List);
	//数据删除
	int postion;
	printf("\n输入要删除的位置:");
	scanf("%d", &postion);
	getchar();
	//用来接收删掉的数据
	Datatype a;
	Listdelete(&List, postion, &a);
	printf("删除的元素为%d\n", a);
	//取数据
	printf("要获取的位置的下标:");
	scanf("%d",&postion); 
	int flag=Listget(&List, postion, &a);
	if(flag==1){
		printf("下标为%d的元素为:%d",postion,a);		
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值