线性表的存储结构是线性结构,其特点是:
在数据元素的非空有限集中
(1)存在惟一的一个被称做“第一个”的数据元素;
(2)存在惟一的一个被称做“最后 一个”的数据元素;
(3)除第一个之外,集合中的每个数据元素均只有一个前驱;
(4)除最 后一个之外,集合中每个数据元素均只有一个后继。
顺序表:
定义:
- 用一组地址连续的存储单元依次存储线性表中的数据元素
2.代码的实现
const int LIST_INIT_SIZE=100; // 线性表存储空间初始分配量 const int LISTINCREMENT=10; // 线性表存储空间分配增量 typedef struct { ElemType *elem; // 存储空间基址 int length; // 当前长度 int listsize; // 允许的最大存储容量 // (以sizeof(ElemType)为单位) } SqList; // 顺序表
空表图示例:
判空:(SqList &L)L->length == 0?空表:非空
判满:(SqList &L)L->length == L->listsize?表满:未满
表长度计算方法:(SqList &L)L->length
单链表:
定义:
- 用一组地址任意的存储单元依次存储线性表中的数据元素
2.代码的实现
Struct L_Node{ Elemtype data; Struct L_Node* next; }Node;
空表图示例:
判空:headNode->next == NULL? 空表:非空
判满:
表长度计算方法:
Node* posNode=headNode; //初始化 int length; // 表的结数 for(length=0;posNode->next != NULL;length++) posNode=posNode->next;
静态链表:
定义:
- ~在不设指针类型的高级程序设计语言中使用链表结构。
~数组的第零分量表示头结点,每个结点的指针域表示下一个结点在数组中的相对位置,即数组代替指针,实现单链表
2.代码的实现:
#define MAXSIZE 1000 typedef struct { ElemType data; int cur; } component,SLinkList[MAXSIZE];
空表图示例:
判空:SLinkList[MAXSIZE-1].cur == 0 ? 空表:非空
判满:SLinkList[0].cur == MAXSIZE-1 ? 表满:未满
表长度计算方法:length = SLinkList[0].cur-S:LinkList[MAXSIZE-1].cur
循环链表:
定义:
- 线性表的另一种形式的链式存 储表示。它的特点是表中最后一个结点的指针域指向头结点,整 个链表成为一个由链指针相链接的环
2.代码表示:
Struct Node{ ElemType data; Struct Node* next; }; Struct Node* lastNode->next = headNode;
空表图示例:
判空:headNode->next == headNode ? 空表;非空
判满:
表长度计算方法:
Struct Node* posNode=headNode; for(length=0;posNode->next!headNode;length++) posNode=posNode->next;
双向循环链表:即双链表;
定义:
- 是其结点结构中含有两 个指针域,其一指向数据元素的“直接后继”,另一指向数据 元素的“直接前驱”
2.代码表示:
typedef struct { ElemType data; DuLNode *prior; DuLNode *next;} DuLNode, *DuLink;
空表图示例:
判空:
headNode->prior == headNode
headNode->next == headNode
判满:
表长度计算方法:
Node* posNode=headNode; //初始化 int length; // 表的结数 for(length=0;posNode->next != NULL;length++) posNode=posNode->next;
上述数据结构适合解决什么类型的问题
顺序表:
适用于已知数据元素个数或数据元素个数变化不大的数据结构
单链表:
动态的存储分配,在数据元素变化大时,相比顺序表可以减少空间浪费现象
静态链表:
进行插入和删除操作时无需移动后续元素,优化了顺序表的插入及删除操作。缺点:没有解决连续存储分配带来的表长难以确定的问题
循环链表:
1. 时常仅保存一个尾指针,因为尾指针的下一个节点即是头结点。这样便可以方便地在首尾进行操作
2. 从任意结点出发都可访问到表中所有结点,这一优点使某些运算在单循环链表上易于实现
实例:如将两个线性表(a1,a2,…,an)和(b1,b2,…,bm)连接成一个线性表
双向循环链表:
从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点
实例:逆序查找