1. 线性表
由n个相同类型的元素组成的有限序列
有且仅有一个第一个节点(头节点)和最后一个节点(末节点),第一个元素无前趋,最后一个元素无后继,其余元素只有一个前趋一个后继
1.1 顺序表(sequence list)
内存连续,连续存储,相邻元素在内存中的位置也相邻
优点:
1. 无需为表示数据元素之间的关系而增加额外的存储空间
2. 可以随机存取表中的任一数据元素,元素存储位置可以用一个简单、直观的公式表示(sizeof(elemtype)*index)
缺点:
1. 插入和删除运算必须移动(操作位置之后的所有数据)大量数据,效率低
2. 必须预先分配内存空间,造成空间利用率低,且容量难以扩充
1.2 链表(link list)
链式存储,不要求相邻元素在内存中的位置也相邻
优点:
1. 无顺序表的缺点(插入和删除非常高效,不需要移动元素内存;不需要预分配内存空间,可以很方便的扩容)
缺点:
1. 无顺序表的优点(需要添加额外的存储空间表示后继元素的地址,不可以随机存取)
3.1.2.1 循环链表
末结点的后继为头结点,形成环
3.1.2.2 双向链表
添加存储单元存储元素的前驱
1.3 栈(stack)
栈是操作受限的线性表;限定对元素的插入和删除只能在表的一端进行;通常把进行插入和删除操作的这一端称作栈顶(Top),另一端称做栈低(Bottom);
最后进栈的元素最先出栈,栈也被称为后进先出表(LIFO)
栈的运算:
置空栈setnull
判栈空empty
进栈push
出栈pop
读取栈顶元素gettop(只读取,不出栈)
1.4 队列
队列(queue)也是一种操作受限制的线性表;限定所有的插入只能在表的一端进行;所有的删除只能在表的另一端进行;允许插入的一端叫做队尾(rear),允许删除的一端叫做队头(front);
队列的操作是按先进先出的原则进行的,因此队列也称作先进先出的线性表(FIFO)
队列的运算:
初始化队列iniqueue
入队列addqueue
出队列outqueue
读队头元素gethead
判断队空empty
假溢出:在删除元素后没有移动顺序表中的元素,导致顺序表未填满但是rear已经是顺序表的最后位置了
解决方式:
每次删除数据后移动元素,并修改rear值
或在发生假溢出时,所有数据向前移动
两种解决方式都会引起大量的元素移动,最常用的方法是使用循环队列(假想顺序表的首尾相连,则不需要移动数据,也不存在假溢出)
1.4.1 循环队列
1.4.2 链队列
1.5 广义表
广义表是线性表的一个推广,广义表的元素可以是一个记录,也可以是一个结构或者广义表
广义表的运算:
求长度
求深度
#include <stdio.h>
struct elemtype
{
int id;
char name[20];
};
#define MAX_SIZE 500
struct sequencelist
{
elemtype data[MAX_SIZE];
int last;
};
struct node
{
elemtype data;
node *next;
} linklist;
struct seqstack
{
elemtype data[MAX_SIZE];
int top;
};
struct sequeue
{
elemtype queue[MAX_SIZE];
int front, rear;
};
struct linknode
{
elemtype data;
linknode *next;
};
struct linkqueue
{
linknode *front, *rear;
};
struct glistnode
{
int atom;
union {
glistnode *snext;
elemtype data;
} elementdata;
glistnode *next;
} glist;
void setnull(const sequencelist &)
{
}
int length(const sequencelist &list)
{
return list.last + 1;
}
elemtype *get(const sequencelist &list, int index)
{
if (index <= list.last)
return (elemtype *)&(list.data[index]);
return nullptr;
}
elemtype *prior(const sequencelist &, const elemtype &);
elemtype *next(const sequencelist &, const elemtype &);
int locate(const sequencelist &list, const elemtype &item);
void insert(sequencelist &list, const elemtype &item, int index);
void del(sequencelist &list, int index);
int main()
{
sequencelist list;
return 0;
}