本文只用于个人数据结构期末复习,其中我认为不会考试的内容,不给相关的代码
线性表
线性表基本概念
线性表是n个数据特征相同的元素的组成有限序列是最基本且最常用的一种线性结构**(线性表,栈,队列,串和数组都是线性结构)**.
对于非空的线性表或者线性结构的特点:
- 第一个数据元素-首元素(不等同于头结点)
- 最后一个数据元素-尾元素(不等同于尾结点)
- 除了第一个外,每一个数据元素都有且只有一个前驱
- 除了最后一个外,每一个数据元素都有且只有一个后继
特点:逻辑上相邻的数据元素,物理次序上也是相邻的
代码实现
#defind maxsize 100
#defind OK 1
#defind ERROR 0
定义数据结构
//以学生信息为例
//学生信息的数据结构
typedef struct{
int id;
char name[30];
}Student;
//线性表的数据结构
typedef struct{
Student *elem; //储存空间的基地址
int length; //数据结构的长度
}SqList;
//定义SqList类型的变量
SqList L;
通过上述代码我们就可以访问 L.elem[i-1] 去访问序号为i的学生信息
初始化
Status InitList(SqList &L){
L.elem = new ElemType [maxsize];
if(!L.elem) exit(-1);
L.length = 0;
return ok;
}
取值
Status Get(SqList &L,int i,ElemType &e){
if(i<1||i>L.length) return ERROR;
e = L.elem[i-1];
return OK;
}
插入
Status ListInsert(SqList &L,int i,ElemType e){
if(i<1||(i>L.length+1)) return ERROR;
if(L.length-1;j>=i-1;j--)
L.elem[j+1] = L.elem[j];
L.elem[i-1] = e;
}
删除
Status ListDelete(SqList &L,int i){
if(i<1||i>L.length) return ERROR;
for(j=i;j<=L.length-1;j++)
L.elem[j-1] = L.elem[j];
L.length--;
return OK;
}
链表
概念:用一组任意的存储单元存储线性表的数据结构(这组存储单元可以是连续的也可以不连续),其包括数据域和指针域,数据域存数据,指针域存后继空间

代码实现
定义数据结构
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
注意其中 *LinkList 和 LNode * 本质上是一样的,只是为了方便阅读所以用 LinkList L 来强调定义某一个单链表的头指针,而 LNode *p 其中p指向单链表中的某个结点的指针
初始化
Status InitList(LinkList &L){
L = new LNode; //生成头结点,用头指针L指向头结点
L->next = NULL;
return OK;
}
取值
Status Get(LinkList L,int i,ElemType &e){
p = L->next;
j = 1; //计数器
while(p && j<i){ //顺着链表往后找知道i==j
p = p->next;
j++;
}
if(!p||j>i) return ERROR;
e = p->data;
return OK;
}
插入
Status ListInstert(LinkList &L,int i,EleType e){
p = L;
j = 0;
while(p&&j<i-1){
p = p->next;
j++;
}
if(!p||j>i-1) return ERROR;
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
删除
Status ListDelete(LinkList &L,int i){
p = L;
j = 0;
while(p&&j<i-1){
p = p->next;
j++;
}
if(!p->next||j>i-1) return ERROR;
q = p->next;
p -> next = q -> next;
delete q;
return OK;
}
创建方法
头插法
void CreateList(LinkList &L,int n){
L = new LNode;
L->next = NULL;
for(i = 0;i<n;i++){
p = new LNode;
cin>>p->data;
p->next = L->next;
L->next = p;
}
}
尾插法
void CreateList(LinkList &L,int n){
L = new LNode;
L->next = NULL;
r = L;
for(i = 0;i<n;i++){
p = new LNode;
cin>>p->data;
p->next = NULL;
r->next = p;
r = p;
}
}
两种方法的结果是一样的,区别为头插法为把新元素插入到了最前端,而尾插法反之,主要尾插法会多出一个指向为节点的尾指针(一般指向NULL)
链表还有两种为 双向链表 和 循环链表
双向链表 为其数据结构中不仅有指向后继的指针,还包括一个指向前驱的指针,在插入删除时需要注意.
循环链表 为头尾相连即尾指针指向头结点 考点 当 L->next = L 的时候此时链表为空
栈和队列
本质 两者都是一种特殊的线性表
栈
定义 限定仅在表尾进行插入或者删除操作的线性表,其中表头称为 栈底(buttom) 表尾称之为 栈顶(top) 其又称为后进先出(Last in frist out)线性表(简称 LIFO 结构)
栈的数据结构
typedef struct{
SElemtype *base;//为栈底指针
SElemtype *top;
int stacksize;
}SqStack;
其中的 base 可以作为判断栈时候为空,若 base == NULL 此时栈为空
队列
定义 仅限于在表尾进行插入,表头进行删除操作的线性表,其中表头称为 队头(front)
表尾称为 队尾(rear) 其又称为先进先出(frist in frist out)线性表(简称 FIFO 结构)
###单链表队列
其数据结构
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode, * QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
循环队列
其数据结构
typedef struct{
QElemType *base; //初始化动态分布存储空间
int front; //队列头指针,若队列不为空,指向队列的头元素
int rear; //队列尾指针,若队列不为空,指向队列的尾元素的下一个元素
}SqQueue;
判断队列是否为空 Q.front == Q.rear 此时为队空
判断队列是否为满 (Q.rear+1) % MAXQSIZE == Q.front 此时为队满
注意 C语言不能动态分布存储空间,所以如果需要使用循环队列需要给定一个最大队列长度,若无法预估所用队列的最大长度应该采用链队列
栈和队列的异同
相同
- 都是线性结构
- 插入操作都是限定在表尾进行
- 都可以通过顺序结构和链式结构实现
- 插入与删除的时间复杂度都是O(1),在空间复杂度上两者相同
不同
- 删除元素的位置不同
- 顺序栈能够实现多栈空间共享,而顺序队列不能
本文介绍了数据结构中的线性表,包括其基本概念、代码实现、链表的定义和操作,以及栈和队列的特性,特别讨论了栈和队列在数据结构中的应用和异同。
621

被折叠的 条评论
为什么被折叠?



