1、定义
线性表:零个或多个元素组成的有限序列。第一个无前驱,最后一个无后继,其余元素都有一个前驱和后继。元素的个数为n。
数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。例如,编程语言中的整型,浮点型等。
抽象数据类型ADT:对数据类型进行抽象,抽取出事务具有的普遍性的本质,是特征的概括,而不是细节。(数据类型和相关的操作捆绑在一起)
线性表抽象数据类型(List):
Data:线性表的数据对象集合为{a,b,c...},每一个元素的数据类型为DataType
Operation: InitList(*L),初始化,判断,取值,返回,插入...
ADT: 线性表List Data: 线性表的数据对象集合为{a1,a2,...,an},每个元素类型为DataType。除了第一个无前驱,最后一个无后继, 其他每个元素都有一个字节前驱和直接后继结点。数据元素间关系一对一。 Operation: InitList(*L);//初始线性表,创建空表 ClearList(*L);//清空线性表数据 ListEmpty(L);//判断列表是否为空 ListLength(L);//获取线性表的长度 GetElem(L,i,* e);//获取指定位置的元素,返回在指针元素中 LocateElem(L,e);//查找元素在线性表中的位置 ListInsert(*L,i,e);//向线性表中指定位置插入元素 ListDelete(*L, i, *e);//删除指定位置处的元素
2、线性表的顺序存储结构
类似于数组,元素依次排放。顺序结构封装的三个属性:数据起始地址,线性表最大长度,当前线性表长度。线性表是从1开始,而数组是从0开始。
插入:首先判断插入删除的位置是否合理,然后从表尾至插入位置依次向后移动一位,完成后插入元素。表长加1。
删除:首先去除需要删除的元素,然后删除位置后面的元素开始依次向前移动一位。此时,最后一位元素清零。表长减1。
线性表的读取为0(1),插入和删除都是0(n)。
优点:无需为表示表中的元素之间的逻辑关系而增加额外的存储空间,可以快速的存取表中的任意位置的元素。
缺点:插入和删除时需要移动大量元素,当线性表长度变化较大时,难以确定存储空间的容量。可能造成存储空间碎片。
3、顺序线性表的实现
#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAZSIZE 20 //线性表的最大存储空间,使用数组实现 typedef int STATUS; //用STATUS来表示函数返回状态码,是上面定义的OK等数据状态 typedef int ELEMTYPE; //ELEMTYPE是表示我们存储数据的类型,根据情况而定,这里设置为int typedef struct { ELEMTYPE data[MAZSIZE]; //数组存储数据元素 int length; //线性表的当前长度 }SqList; //表名 //四个基本操作:初始,清空,判断是否为空,获取长度(形参的类型与是否需要修改有关) STATUS InitList(SqList* L); //需要改变线性表 STATUS ClearList(SqList* L); //需要改变线性表 STATUS ListEmpty(SqList L); //只需要读取 int ListLength(SqList L); //只需要读取 //四个元素操作,获取指定位置元素,获取指定元素的位置,插入,删除 STATUS GetElem(SqList L, int i, ELEMTYPE* e); int GetLocate(SqList L, ELEMTYPE e); STATUS ListInsert(SqList* L, int i, ELEMTYPE e); STATUS ListDelete(SqList* L, int i, ELEMTYPE* e); void PrintList(SqList L); //四个基本操作:初始,清空,判断是否为空,获取长度 //初始化 STATUS InitList(SqList* L) { L->length = 0; for (int i = 0; i < MAZSIZE; i++) { L->data[i] = 0; } return OK; } //清空 STATUS ClearList(SqList* L) { L->length = 0; for (int i = 0; i < MAZSIZE; i++) { L->data[i] = 0; } return OK; } //判断列表是否为空 STATUS ListEmpty(SqList L) { if (L.length > 0) { return TRUE; } else { return FALSE; } } //获取线性表的长度 int ListLength(SqList L) { return L.length; } //获取指定位置元素 STATUS GetElem(SqList L, int i, ELEMTYPE* e) { if (L.length == 0 || i < 1 || L.length < i) return ERROR; *e = L.data[i - 1]; //线性表中的数据和正常一样,从1开始,而数组是从0开始 return OK; } //获取指定元素的位置 int GetLocate(SqList L, ELEMTYPE e) { if (L.length == 0) return ERROR; int i = 0; for (; i < MAZSIZE; i++) if (L.data == e) break; if (i >= MAZSIZE) return ERROR; return (i + 1); } //插入 STATUS ListInsert(SqList* L, int i, ELEMTYPE e) { if (i<1 || i>L->length+1||L->length==MAZSIZE) return ERROR; for (int k =L->length; k >= i; k--) { L->data[k] = L->data[k-1]; } L->data[i - 1] = e; L->length++; return OK; } //删除 STATUS ListDelete(SqList* L, int i, ELEMTYPE* e) { if (L->length == 0 || i<1 || i>L->length) return ERROR; *e = L->data[i - 1]; for(; i < L->Length ;i++ ) { L->data[i - 1] = L->data[i]; } L->data[L->length - 1] = 0; L->length--; return OK; } //打印 void PrintList(SqList L) { printf_s("print the List\n"); for (int i = 0; i < L.length; i++) { printf_s("%d ", L.data[i]); } printf_s("\n"); } int main() { SqList L; ELEMTYPE e; printf_s("1.Initial List\n"); InitList(&L); printf_s("2. Insert Element 1-10\n"); for(int i = 1; i <= 10; i++) ListInsert(&L,i,i); printf_s("3. Insert 7 at the Location of 5\n"); ListInsert(&L, 5, 7); PrintList(L); printf("3.ListDelete the first:\n"); ListDelete(&L, 1, &e); printf("%d \n", e); printf("4.ListDelete the end:"); ListDelete(&L, ListLength(L), &e); printf("%d \n", e); PrintList(L); printf("5.1 find element use GetElem by index(6): "); GetElem(L, 6, &e); printf("%d \n", e); printf("5.1 find element:256 index by LocateElem:"); printf("%d \n", GetLocate(L, 256)); printf("6.Get List length:%d\n", ListLength(L)); printf("7.ClearList\n"); ClearList(&L); if (ListEmpty(L) == OK) printf("8.ListEmpty\n"); system("pause"); return 0; }
原文地址:https://www.cnblogs.com/lemonzhang/p/12313049.html
时间: 2024-10-10 05:17:15