说明:以下笔记中,代码全为伪代码,请自行阅读与理解。下一篇文章即将用一个小小的实验题来对文章内容进行验证和实现。
文章结尾将会放出实验题,可以先行思考。
第一章 线性表
2.1 线性表的定义和特点
定义:由n(n>=0)个数据特性相同的元素构成的元素构成的有限序列称为线性表。
线性表的个数n定义为线性表的程度,n=0时称为空表。
对于非空的线性表或者线性结构,其特点是:
(1)存在唯一的一个被称作“第一个”的数据元素。
(2)存在唯一的一个被称作“最后一个”的数据元素。
(3)除第一个以外,结构中的每个数据元素均只有一个前驱。
(4)除最后一个外,结构中的每个元素均只有一个后继。
2.2案例引入
一元多项式运算:数组表示的顺序储存结构。(书p19、p20)
稀疏多项式运算:采用链式储存结构表示多项式的有序序列(书p20)
图书信息管理系统:抽象成线性表,采用适当的存储结构来表示该线性表。
2.3线性表的类型定义
不需要背熟,因为背了根本没用,你应该掌握主要内容。
比如InitList(&L)操作结果:
构成一个空的线性表L;InitList是一个函数名,你也可以定义为IL,这个名字完全是你自己决定的,&L的L也是自己可以定义的,你可以定义为H,所以记住根本没实际作用,你要知道的是这个函数有什么功能,是怎样实现的?为什么L前面有个&?
2.4线性表的顺序表示和实现
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。(逻辑上相邻的数据元素,其物理次序也是相邻的)
只要确定了存储线性表的起始位置,线性表中任意一数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。
由于高级程序设计语言中的数组类型也有随机存取的特性,因此,通常都用数组来描述数据结构中的顺序和存储结构。在此,由于线性表的长度可变,且所需最大存储空间随问题不同而不同,则在C语言中可用动态分配的一维数组表示线性表,描述如下:
//----顺序表的存储结构(伪代码)----
说明:
(1)数组空间通过后面算法2.1初始化动态分配得到,初始化完成后,数组指针elem指示顺序表的基地址,数组空间大小为MAXSIZE。
(2)元素类型定义中的ElemType数据类型是为了描述统一而自定的,在实际应用中用户可根据实际需要具体定义表中数据元素的数据类型,既可以是基本数据类型,如 int、float、char 等,也可以是构造数据类型,如struct结构体类型。
(3)length表示顺序表中当前数据元素的个数。因为C语言数组的下标是从0开始的,而位置序号是从1开始的,所以要注意区分元素的位置序号和该元素在数组中的下标位置之间的对应关系,数据元素的位置序号和该元素在数组中的下标位置之间的对应关系,数据元素 a1、a2、…… 、an 依次存放在数组 elem【0】、elem【1】、…… 、elem【Length-1】中。
顺序表中基本操作的实现:
1.初始化:
顺序表的初始化操作就是构造一个空的顺序表。
Status Init_SqList( SqList *L )
{ L->elem_array=( ElemType * )malloc(MAX_SIZE*sizeof( ElemType ) ) ;
if ( !L -> elem_array ) return ERROR ;
else { L->length= 0 ; return OK ; }
}
2.取值:
取值操作时根据指定的位置序号i,获取顺序表中第i个数据元素的值。
由于顺序存储结构具有随机存取的特点,可以直接通过数组下标定位得到,elem【i -1】单元存储第i个数据元素。
实现步骤
(1) 将线性表L中的第i个至第n个结点后移一个位置。
(2) 将结点e插入到结点ai-1之后。
(3) 线性表长度加1。
Status Insert_SqList(Sqlist *L,int i ,ElemType e)
{
int j ;
if ( i<0||i>L->length-1) return ERROR ;
if (L->length>=MAX_SIZE)
{ printf(“线性表溢出!n”); return ERROR ; }
for ( j=L->length–1; j>=i-1; --j )
L->Elem_array[j+1]=L->Elem_array[j];
/* i-1位置以后的所有结点后移 */
L->Elem_array[i-1]=e; /* 在i-1位置插入结点 */
L->length++ ;
return OK ;
}
3.查找:
查找操作是根据指定的元素值e,查找顺序表中第1个与e相等的元素。若查找成功,则返回该元素在表中的位置序号;若查找失败,则返回0.
Status Locate_Delete_SqList(Sqlist *L,ElemType x)
/* 删除线性表L中值为x的第一个结点 */
{ int i=0 , k ;
while (i<L->length) /*查找值为x的第一个结点*/
{ if (L->Elem_array[i]!=x ) i++ ;
else
{ for ( k=i+1; k< L->length; k++)
L->Elem_array[k-1]=L->Elem_array[k];
L->length--; break ;
}
}
if (i>L->length)
{ printf(“要删除的数据元素不存在!n”) ;
return ERROR ; }
return OK;
}
4.插入:
在表的第i个位置插入一个新的数据元素e,使长度为n的线性表变成长度为n+1的线性表。
Status Insert_SqList(Sqlist *L,int i ,ElemType e)
{ int j ;
if ( i<0||i>L->length-1) return ERROR ;
if (L->length>=MAX_SIZE)
{ printf(“线性表溢出!n”); return ERROR ; }
for ( j=L->length–1; j>=i-1; --j )
L->Elem_array[j+1]=L->Elem_array[j];
/* i-1位置以后的所有结点后移 */
L->Elem_array[i-1]=e; /* 在i-1位置插入结点 */
L->length++ ;
r
5.删除
删除线性表的第i个数据元素,使线性表的长度减一。
实现步骤
(1) 将线性表L中的第i+1个至第n个结点依此向前移动一个位置。
(2) 线性表长度减1。
ElemType Delete_SqList(Sqlist *L,int i)
{ int k ; ElemType x ;
if (L->length==0)
{ printf(“线性表L为空!n”); return ERROR; }
else if ( i<1||i>L->length )
{ printf(“要删除的数据元素不存在!n”) ;
return ERROR ; }
else { x=L->Elem_array[i-1] ; /*保存结点的值*/
for ( k=i ; k<L->length ; k++)
L->Elem_array[k-1]=L->Elem_array[k];
/* i位置以后的所有结点前移 */
L->length--; return (x);
}
}
实验:
1、随机产生n个100以内整数生成一个顺序存储的线性表, 并实现如下功能(用菜单实现,并加入开始画面和结束画面):
1. SORT(排序) 2. INSERT(插入) 3. DELETE(删除) 4. EXIT(退出 )