第二章 向量、栈和队列
线性表
线性表的抽象模型
- 线性表:n 个数据元素组成的一个有限序列 k0, k1 , … , kn-1
元素 | 性质 |
---|---|
k0 | 开始结点,没有前趋,仅有一个后继 |
kn-1 | 终端结点,没有后继,仅有一个前趋 |
ki ( i 在(0,n-1)区间内) | 有且仅有一个前趋ki-1和一个后继ki+1 |
n | 线性表的长度,当n=0时,线性表为空表 |
- 线性表的分类:
类别 | 定义 |
---|---|
向量 | 数据类型相同的数据元素组成的线性表。 例:串是由单个字符组成的线性表,也可称为字符向量。 |
文件 | 记录:数据元素为组合项时,组合项中的数据项可以为不同的数据类型。 由记录组成的线性表称为文件。 |
- 线性表的基本操作:
操作 | 解释 |
---|---|
表的初始化 | 生成一个空表 |
判断表是否为空 | 表结点的个数是否为0 |
判断表是否已满 | 表结点的个数是否为允许的最大数 |
求表长 | 表中结点的个数 |
取表中第 i 个元素 | 取给定地址 i 的元素 |
查找表中值为 x 的结点 | 返回所有值为 x 的结点的地址 |
插入结点 | 在表中第 i 个位置上插入结点 |
删除结点 | 删除表中第 i 个位置的结点 |
- 线性表的抽象数据模型:
ADT LinearList
{
Data
数据元素有限序列 k0, k1,...,kn-1
k0无前趋,后继为k1
kn-1无后继,前趋为kn-2
ki前趋为ki-1,后继为ki+1,0<i<n-1
Operations
InitList
Input: 申请表的空间长度
Preconditions: 无
Process: 申请一个表空间,生成一个空表
Output: 表空间位置和范围,表长为0
Postconditions: 表已存在
DestroyList
Input: 无
Preconditions: 表已存在
Process: 撤销一个表
Output: 无
Postconditions: 表不存在
ListEmpty
Input: 无
Preconditions: 表已存在
Process: 判断表是否为已满
Output: 若为空表返回TRUE,否则返回FALSE
Postconditions: 无
ListFull
Input: 无
Preconditions: 表已存在
Process: 判断表是否为空表
Output: 若表已满,返回TRUE,否则返回FALSE
Postconditions: 无
ListLength
Input: 无
Preconditions: 表已存在
Process: 求表的结点个数
Output: 返回表的长度
Postconditions: 无
GetElem
Input: 结点序号 i
Preconditions: 表已存在
Process: 按 i 读取 ki
Output: 若读取成功,返回 ki 的值,否则返回NULL
Postconditions: 无
LocateElem
Input: 要在表中查找到值
Preconditions: 表已存在
Process: 扫描表,找与查找值相等的结点
Output: 若查找成功,则返回找到的结点的序号,否则返回-1
Postconditions:
InsertElem
Input: 新结点要插入的位置
Preconditions: 表已存在
Process: 将新结点按插入位置插入其中
Output: 若插入成功,则返回TRUE,否则返回FALSE
Postconditions: 表中增加一个结点,表的长度加一
DeleteElem
Input: 要删除结点的序号
Preconditions: 表已存在
Process: 删除指定序号的结点
Output: 若删除成功,则返回TRUE,否则返回FALSE
Postconditions: 表中减少一个结点,表的长度减1
}
线性表的数据结构表示
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int ElementType;
typedef struct linearList{
ElementType * data;
int MaxSize;
int Last;
}LinearList;
/* 线性表的初始化 */
void InitList(LinearList * L,int size){
if(size>0){
L->MaxSize = size;
L->Last = 0;
L->data = (ElementType *)malloc(sizeof(ElementType) * L ->MaxSize);
}
}
/* 释放线性表的空间 */
void FreeList(LinearList *L){
free(L->data);
}
/* 判断线性表是否为空 */
bool ListEmpty(LinearList *L){
return (L->Last <=0) ? true : false;
}
/* 判断线性表是否为满 */
bool ListFull(LinearList *L){
return (L->Last >= L->MaxSize) ? true : false;
}
/* 求线性表的长度 */
int ListLength(LinearList *L){
return L->Last;
}
/* 取线性表的第 i 个表目 */
ElementType getElement(LinearList *L, int i){
return (i>0 ||i<L->Last) ? L->data[i] : NULL;
}
/*
在线性表中查找值为 x 的结点
若查找成功,返回结点的序号,否则返回-1
若表中符合条件的结点有多个,返回最前面的结点的序号
*/
int LocalElem(LinearList *L, ElementType x){
int i;
for(i=0;i<L->Last;i++){
if(L->data[i] == x) return i;
}
return -1;
}
/*
在线性表中的第 i 个位置插入值为 x 的结点
插入成功返回TRUE,否则返回FALSE
*/
bool InsertElem(LinearList *L,ElementType x, int i){
int j;
if(i<0 || i>L->Last || L->Last == L->MaxSize){
return false;
}else{
for(j=L->Last-1;j>=i;j--)
L->data[j+1] = L->data[j];
L->data[i] = x;
L->Last++;
return true;
}
}
/*
删除表中第 i 个结点
删除成功返回TRUE,否则返回FALSE
*/
bool DeleteElem(LinearList *L, int i){
int j;
if(i<0 || i>=L->Last || L->Last==0) return false;
else{
for(j=i;j<L->Last-1;j++){
L->data[j]=L->data[j+1];
}
L->Last--;
return true;
}
}
/* 打印线性表的表目 */
void printout(LinearList *L){
int i;
for(i=0;i<L->Last;i++){
printf("%d ",L->data[i]);
}
printf("\n");
}
首先这个代码里面是有一些问题的:
(1)如果你使用的是C语言实现的代码,从C99标准开始,C语言有布尔类型了,关键字是“_Bool”,其取值只能是0和1。如果你使用的编译器版本支持C99标准,就可以直接使用布尔类型数据。
一些具体的使用方法请参考:
链接: C语言的布尔类型(_Bool).
(2)在这个函数中的编译是会出现两个警告的。
/* 取线性表的第 i 个表目 */
ElementType getElement(LinearList *L, int i){
return (i>0 ||i<L->Last) ? L->data[i] : NULL;
}
||== Build: Debug in LinearList (compiler: GNU GCC Compiler) ==
D:\C++\DataStructure\LinearList\main.c||In function ‘getElement’:
D:\C++\DataStructure\LinearList\main.c|42|warning: pointer/integer type mismatch in conditional expression
D:\C++\DataStructure\LinearList\main.c|42|warning: returning ‘void *’ from a function with return type ‘ElementType’ {aka ‘int’} makes integer from pointer without a cast [-Wint-conversion]
||== Build finished: 0 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ==|
- warning: pointer/integer type mismatch in conditional expression
条件表达式中整数\指针数据类型不匹配,放到这个代码中来说,我用的是ElementType作为函数返回值的类型,但是我的条件表达式中出现了NULL。因为我ElementType是int,这个NULL和我的ElementType不能匹配,所以就出现了这样的报错。 - warning: returning ‘void *’ from a function with return type ‘ElementType’ {aka ‘int’} makes integer from pointer without a cast [-Wint-conversion]
警告:从返回类型为 ‘ElementType’ {aka ‘int’} 的函数返回 'void *'从指针生成整数而不进行强制转换 [-Wint-conversion]
这个警告其实感觉上是上一个警告的延伸,int不能强制转换为string类型的数据,也就是ElementType不能和Null进行匹配
(目前没有想到合适的解决办法,如果小伙伴们有什么好的解决办法,欢迎在评论区和我交流)
【测试】
int main()
{
LinearList *L = (LinearList *)malloc(sizeof(LinearList));
InitList(L,5);
InsertElem(L,10,0);
InsertElem(L,20,0);
InsertElem(L,30,0);
InsertElem(L,40,0);
InsertElem(L,50,0);
if(InsertElem(L,60,0))
printout(L);
else if(ListFull(L))
printf("List is full, failed to insert\n");
printout(L);
DeleteElem(L,1);
DeleteElem(L,1);
printf("After twice deletions the list is ");
printout(L);
printf("The location of data 20 is %d\n",LocalElem(L,20));
printf("The 3rd value is %d\n",getElement(L,2));
FreeList(L);
return 0;
}
List is full, failed to insert
50 40 30 20 10
After twice deletions the list is 50 20 10
The location of data 20 is 1
The 3rd value is 10
Process returned 0 (0x0) execution time : 0.058 s
Press any key to continue.