线性表-顺序存储

线性表

定义:由零个或多个数据元素组成的有限序列。

关键点:

首先它是一个序列,也就是说元素之间是有个先来后到的。

若元素存在多个则第一个元素无前驱,最后一个元素无后继,其他元素都有且只有一个前驱和后

继。

线性表强调是有限的,事实上无论计算机发展到多强大,它所处理的元素都是有限的。

用数学语言定义如下:

若将线性表记为(a1,...,ai-1,ai,ai+1,...,an),则表中ai-1领先于ai,ai领先于ai+1,则ai的直接前驱是 ai-1,ai+1是ai的直接后继。 所以线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,称为空表。

面向对象和面向过程的区别:

面向过程:处理问题一步一步来,比如买菜做饭

面向对象:指挥他人去做,拿到结果就行,比如去餐厅吃饭

抽象数据类型

数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。

在C语言中,按照取值的不同,数据类型可以分为两类:

原子类型:不可以再分解的基本类型,例如整型,浮点型,字符型等。

结构类型:由若干个类型组合而成,是可以再分解的,例如整型数组,结构体等。

抽象:是指抽取出事物具有的普遍性的本质。它要求抽取出问题的特征而忽略非本质的细节,是对事物 的一个概括。抽象是一种思考问题的方式,它隐藏了繁琐的细节。

我们对已有的数据类型进行抽象,就有了抽象数据类型。

Abstract Data Type(ADT)是指一个数学模型及定义在该模型上的一组操作。

标准格式:

ADT 抽象数据类型名

Data

数据元素之间逻辑关系的定义

Operation

操作

endADT

线性表的抽象数据类型

ADT 线性表(List)

Data

线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType。其中,除第一个元    素a1外,每一个元素有且只有一个直接前驱元素,除最后一个元素an外,每一个元素有且只有一 个直接后继元素。数据元素之间的关系是一对一的关系。

Operation

1.InitList(*L):初始化操作,建立一个空的线性表L。

2.ListEmpty(L):判断线性表是否为空表,若线性表为空,返回true,否则返回false

3.ClearList(*L):将线性表清空。

4.GetElem(L,i,*e):将线性表L中的第i个位置元素值返回给e。

5.LocateElem(L,e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在 表中序号表示成功;否则,返回0表示失败。

6.ListInsert(*L,i,e):在线性表L中第i个位置插入新元素e。

7.ListDelete(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值

8.ListLength(L):返回线性表L的元素个数。

endADT

举个例子:

要实现两个线性表A、B的并集操作,还要使得集合A=A∪B。

操作步骤:遍历集合B,依次取出元素,判断元素是否在集合A中,如果不存在,将元素插入到集合A中。

GetElem(L,i,*e)

LocateElem(L,e)

ListInsert(*L,i,e)

 

线性表的顺序存储结构

顺序存储是指用一段连续的存储单元依次存储线性表的数据元素。(跟数组很相似)

下面是我写的一些代码:

#include<stdio.h>
#define MAX_SIZE 10  //线性表的最大容量
#define OK 1  //返回状态 成功
#define ERROR 0  //返回状态 失败
#define NOT_EXIST 0  //状态 不存在
#define TRUE 1  //代表线性表为空
#define FALSE 0  //代表线性表不为空
typedef int Status;  //状态 OK ERROR
typedef int ElemType;  //线性表的元素类型 int
typedef struct {  //自定义的顺序表,名为SqList
	ElemType datas[MAX_SIZE];  //顺序表所维护的一个存储元素的集合
	int length;  //元素长度
}SeqList;
//初始化
void init(SeqList *L) {
	//对某个线性表进行初始化
	L->length = 0;
	for (int i = 0; i<5; i++) {
		L->datas[i] = i + 1;
		L->length++;
	}
}
//增
Status insert(SeqList *L, int position, ElemType e) {
	/*在某个线性表中的某个位置插入某个元素
	返回插入成功或失败*/
	if (L->length == MAX_SIZE) {
		printf("线性表已满!\n");
		return ERROR;
	}
	if (position<1 || position>L->length + 1) {
		printf("插入位置不合法!\n");
		return ERROR;
	}
	for (int i = L->length; i>position - 1; i--) {
		L->datas[i] = L->datas[i - 1];
	}
	L->datas[position - 1] = e;
	L->length++;
	return OK;
}
//删
Status delete_L(SeqList *L, int position, ElemType *e) {
	/*在某个线性表中的某个位置删除某个元素
	并将删除前的元素赋值给*e
	返回删除成功或失败*/
	if (L->length == 0) {
		printf("线性表为空!\n");
		return ERROR;
	}
	if (position<1 || position>L->length + 1) {
		printf("删除位置不合法!\n");
		return ERROR;
	}
	*e = L->datas[position - 1];
	for (int i = position - 1; i<L->length - 1; i++) {
		L->datas[i] = L->datas[i + 1];
	}
	L->length--;
	return OK;
}
//查
Status find(SeqList *L, int position, ElemType *e) {
	/*根据位置查询某个线性表中的元素
	并将查询的元素赋值给*e
	返回删除成功或失败*/
	if (L->length == 0) {
		printf("线性表为空!\n");
		return ERROR;
	}
	if (position<1 || position>L->length + 1) {
		printf("查询位置不合法!\n");
		return ERROR;
	}
	*e = L->datas[position - 1];
	return OK;
}
int find_locate(SeqList *L, ElemType e) {
	//查找表中某个元素的位置
	int position = NOT_EXIST;
	if (L->length == 0) {
		printf("线性表为空!\n");
		return position;
	}
	for (int i = 0; i<L->length; i++) {
		if (L->datas[i] == e) {
			position = i + 1;
			return position;
		}
	}
	return NOT_EXIST;
}
int size(SeqList *L) {
	//返回线性表的长度(也可以用来判断是否为空)
	return L->length;
}
Status empty(SeqList *L) {
	return L->length == 0 ? TRUE : FALSE;
}
void clear(SeqList *L) {
	L->length = 0;
	printf("清空完毕!\n");
}
//打印线性表
void print(SeqList *L) {
	//对某个线性表进行输出
	if (L->length == 0) {
		printf("[]\n");
		return;
	}
	printf("[");
	for (int i = 0; i<L->length; i++) {
		if (i == L->length - 1) {
			printf("%d]\n", L->datas[i]);
		}
		else {
			printf("%d,", L->datas[i]);
		}
	}
}
//结构体中,如果通过普通结构体变量调用元素 L.length
//如果通过指针结构体变量调用元素 L->length
int main() {
	SeqList L;
	int position;
	ElemType e;
	int choice;
	printf("----------线性表-------\n");
	printf("1、初始化操作\n");
	printf("2、插入元素\n");
	printf("3、删除元素\n");
	printf("4、获取元素所在位置\n");
	printf("5、获取位置所在元素\n");
	printf("6、获取长度\n");
	printf("7、清空列表\n");
	printf("8、判空列表\n");
	printf("9、打印列表\n");
	printf("10、退出\n");
	printf("11、返回主菜单\n");
	printf("-------------------------\n");
	while (1) {
		printf("   请输入你想要的选项:\n");
		scanf("%d", &choice);
		switch (choice) {
		case 1:
			init(&L);
			break;
		case 2:
			printf("请输入插入的位置:");
			scanf("%d", &position);
			printf("请输入插入的元素:");
			scanf("%d", &e);
			insert(&L, position, e);
			break;
		case 3:
			printf("请输入删除的位置:");
			scanf("%d", &position);
			if (delete_L(&L, position, &e)) {
				printf("删除的元素为%d", e);
			}
			break;
		case 4:
			printf("请输入查询的位置:");
			scanf("%d", &position);
			if (find(&L, position, &e)) {
				printf("该位置的元素为:%d", e);
			}
			break;
		case 5:
			printf("请输入查询的元素:");
			scanf("%d", &e);
			printf("该元素的位置为:%d", find_locate(&L, e));
			break;
		case 6:
			printf("该线性表长度为:%d", size(&L));
			break;
		case 7:
			clear(&L);
			break;
		case 8:
			if (empty(&L)) {
				printf("该线性表为空!\n");
			}
			else {
				printf("该线性表不为空!\n");
			}
			break;
		case 9:
			print(&L);
			break;
		case 10:
			printf("退出\n");
			break;
		case 11:
			main();
			break;
		default:
			printf("输入错误!\n\a");
			break;
		}
	}
	return 0;
}

有问题的可以问我奥~~~

下节我们来看线性表的链式存储。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值