线性表
定义:由零个或多个数据元素组成的有限序列。
关键点:
首先它是一个序列,也就是说元素之间是有个先来后到的。
若元素存在多个则第一个元素无前驱,最后一个元素无后继,其他元素都有且只有一个前驱和后
继。
线性表强调是有限的,事实上无论计算机发展到多强大,它所处理的元素都是有限的。
用数学语言定义如下:
若将线性表记为(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;
}
有问题的可以问我奥~~~
下节我们来看线性表的链式存储。