(一)顺序表
1.基本概念:
首元结点:存储第一个数据元素的结点。
头结点:在链表的首元结点之前附设一个结点,便于对首元结点操作。
头指针:指向链表中的第一个结点。
插入/删除:在顺序表中插入或删除一个元素,需要平均移动一半个元素,具体移动的元素个数与元素位置有关。
在单链表中,除了首元结点外,任一结点的存储位置由前驱结点的链域的值指示。
在单链表中设置头结点的作用是:插入和删除首元素时不必进行特殊处理。
Q1:在什么情况下用顺序表比链表好?
Answer:当不涉及插入和删除操作的时候,或者添加或删除线性表的最后一个元素时。
Q2:连续存储分配设计是,存储单元的地址_______?
A:一定连续。连续存储分配不一定是顺序存储,也可能是静态链表,但地址的分配一定是连续的。
Q3:链式存储设计时,节点内的存储单元地址______?
A:一定连续。链式存储设计时,各个不同结点的存储空间可以不连续,但是结点内的存储单元的地址必须是连续的。
存储结构:有顺序存储、链式存储、索引存储和散列(Hash)存储。循环队列是用顺序表表示的队列,因此与存储结构相关。
2.顺序表的定义
1)静态分配一维数组
#define MaxSize 50 //定义线性表的最大长度 typedef struct{ ElemType data[MaxSize]; //顺序表的元素 int length; //顺序表的长度 }SqList; //顺序表的类型定义
一旦空间占满,再加入新的数据将产生溢出,就会导致程序崩溃。
2)动态分配一维数组
#define InitSize 100 //表长度的初始定义 typedef struct{ ElemType * data; //指示动态分配数组的指针 int MaxSize,length; //数组的最大容量和当前个数 }SeqList; //动态分配数组顺序表的类型定义 //初始的动态分配语句为 L.data = (ElemType *)malloc(sizeof(ElemType) * InitSize); //C++的初始动态分配语句为 L.data = new ElemType[InitSize];
注意:动态分配并不是链式存储,同样还是属于顺序存储结构,其物理结构没有变化,依然是随机存取方式,只是分配的空间大小可以在运行时决定。