写在前面的:
数据结构的学习是从线性表开始的,由于我们对新知识的很多概念并不是很清除,因此入门的List学习起来会十分困难。
当我们学会了List之后,就搭建好了数据结构的基本思维模式,往后学习便会比较轻松。而且栈和队列其本质都是List,只是有某些特殊性质而已。
综上所述,List这块的内容值得你花比较多的时间来啃,性价比较高。
操作:
初、创、销、增、删、清、查、判——初始化、创建、销毁、增加、删除、清空、查询、判断是否为空(所有的数据结构都需要这几种操作)——任何操作在执行之前都要先区分它所处的不同条件。例如:如果要删除线性表的元素,首先要保证线性表不为空,否则删除元素的操作不成立
形参:
1、当参数需要被改动时,则使用指针(或引用)作为形参
2、当参数不需要被改动时,则使用普通的变量作为形参
//将属于Lb但不属于La的元素插入La中 //List* La————>La是个指针,它指向一个类型为List的变量;*La表示它指向的变量,该变量类型为List void umion(List* La,List Lb){//数组La需要被改变内容,而数组Lb不需要被改变内容 int La_len,Lb_len,i; //La_len表示数组La的长度,Lb_len表示数组Lb的长度 ElemType e;//数据元素e的类型与La和Lb中存放的数据元素的类型一致 La_len=ListLength(*La); Lb_len=ListLength(Lb);//求线性表La和Lb的长度,即给La_len和Lb_len赋值;此处La是个指针,长度为4字节,*La才是我们关注的数组 for(i=1;i<=Lb_len;++i){//遍历Lb GetElem(Lb,i,&e);//将Lb第i个元素返回给e;函数声明:GetElem(L,i,*e) if(!LocateElem(*La,e))//判断La中是否存在于e相等的元素;函数声明:LocateElem(L,e) ListInsert(La,++La_len,e);//将e插入到la中,并将La的长度加一 }
线性表的顺序存储结构
用静态数组(固定长度的数组)来存储线性表中的数据信息。其本质就是对定长数组的一种应用,故在使用前,必须要能预估数组的大概长度;当数组的长度不确定时,不能使用循序存储结构
属性:
1、存储空间的起始位置:数组名data(data[0]的位置)
2、线性表的最大存储容量:数组长度MaxSize,是个定值
3、线性表的当前长度:length(表中数组元素的个数,随着插入和删除操作,该值会改变)
优点:
1、无需为表示元素间的逻辑关系而增加额外的存储空间,存储密度高
2、可快速读取任何位置的元素
缺点:
1、插入和删除操作较慢
2、需要大片连续空间;当线性表长度变化较大时,难以确定其存储空间
3、造成存储空间的“碎片”
碎片的产生:
顺序表占用一整块连续的存储空间。若10个不同大小的顺序表L1~L9按从左到右的顺序排列;假设L5占10个字节,当L5被释放掉,且L4和L6始终驻留,L5中只能存放小于或等于10个字节的数据。这样必然会留下更小的缝隙,而这种更小的缝隙是可以在程序运行时逐渐积累数量的。如果一个程序长时间运行,并且以一定频率产生这种缝隙,久而久之,这类缝隙越来越多,且所有缝隙无法被使用。这就是所谓的碎片。
//线性表的顺序存储结构
/*当int占4个字节时,该结构所占的类型空间为4*(MAXSIZE+1)=4*(20+1)=84个字节,即需要
84*8=672bit————>这部分空间中存放了一个定长数组(按普通数组来对待),还存放了一个表是
数组长度的整型数值*/
#define MAXSIZE 20
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];//数组中存放的元素为int型,ElemType代表该数组是个数据类型
int length;
}SqList;//SqList是匿名结构体的别名
//返回第i个位置的元素
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
Status GetElem(SqList L, int i, ElemType* e) {//返回值为int类型,Status代表返回值表状态;不改变L的值,但改变e的值
if (L.length &#