北师大数据结构期末考试复习

绪论

数据

数值性数据,非数值性数据

输入,输出,存储数据

数据元素(数据的基本单位)

有时一个数据元素可以由若干数据项(Data Item)组成。数据项是具有独立含义的最小标识单位。

数据对象(数据的子集)

具有相同性质的数据成员(数据元素)的集合

数据结构 Data_Structure = { D, R, M }

D 是某一数据元素的集合;
R 是该集合中所有数据成员之间的关系的有限集合;
M 是作用在该集合所有数据成员之上的方法(或操作)。

数据的逻辑结构

数据的逻辑结构抛弃了数据元素及其关系的实现细节,只反映了系统的需求(从用户使用层面上)而不考虑如何实现。
数据的逻辑结构从逻辑关系上描述数据,与数据的存储无关。
数据的的逻辑结构与数据元素的内容无关。
数据的逻辑结构与它所包含的数据元素个数无关。
数据的逻辑结构与数据元素所处位置无关。

分类
线性结构

线性表

非线性结构

多维数组
广义表

图(或网络)

无结构

集合

数据的存储结构(物理结构)

内容存储:数据元素的内容或值

关系存储:各数据元素之间的逻辑关系

附加存储:为使施加于数据结构上的运算得以实现而附加的存储空间

顺序存储表示:连续空间存储

链接存储表示:动态分配内存空间

索引存储表示:用于对索引文件的实现(索引表)

散列存储表示:用于直接存取文件的实现(函数求出的关键码)

数据类型

基本数据类型

构造数据类型

抽象数据类型

信息隐藏

数据封装

使用与实现相分离

算法: 算法+数据结构=程序

输入:0个或多个输入

输出:1个或多个输出

确定性

有穷性

有效性

评价(复杂度,完善)

正确性

可读性

健壮性

高效性

简单性

基本方法

穷举型(素数)

迭代法(求根)

递推法(斐波那契数列)

递归法(同上)

动态规划法

time() 后期测试
double start, stop;
time (&start);	
int k = seqsearch (a, n, x);
time (&stop);			
double runTime = stop - start;
printf ( ”%d%d\n " , n, runTime );
时间复杂度

c < log2n < n < nlog2n < n^2 < n^3 < 2^n < 3^n < n!

for(int i = 0;i < m;i++)

语句频度:m+1

递归的复杂度(递推后去计算)

2.线性表

定义 n(≥0)个数据元素的有限序列,记作(a1, a2, …, an)
ai 是表中数据元素,n 是表长度。

特点:线性排列

除第一个元素外,其他每一个元素有一个且仅有一个直接前趋。

除最后一个元素外,其他每一个元素有一个且仅有一个直接后继。

线性表key point

1.表中元素具有逻辑上的顺序性,在序列中各元素排列有其先后次序,有唯一的首元素和尾元素。
2.表中元素个数有限。
3.表中元素都是数据元素。即每一表元素都是原子数据,不允许“表中套表”。
4.表中元素的数据类型都相同。这意味着每一表元素占有相同数量的存储空间。

顺序表
定义

将线性表中的元素相继存放在一个连续的存储空间中,即构成顺序表。

存储

它是线性表的顺序存储表示,可利用一维数组描述存储结构。

特点

元素的逻辑顺序与物理顺序一致。

访问方式

可顺序存取,可按下标直接存取。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FmPB80jr-1631361136971)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103155834911.png)]

LOC是元素存储位置,l是元素大小

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kHUpfhB-1631361136973)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103155928887.png)]

静态结构:表一旦装满,不能扩充
int n;
T data[MAXN];
动态结构:可以扩充
int maxsize;
int n;
T *data;
查找

从顺序表的头开始顺序查找

查找成功:n*(n+1)/2n = (n+1)/2

查找不成功:n

插入
for(int j = L.n-1;j >= i-1;j--)// 第i个位置插入
{
    L.data[j+1] = L.data[j];
}
L.data[i-1] = x;

插入时平均移动元素个数:n*(n+1)/2(n+1) = n/2

删除
for(int j = i;j < L.n;j++) // 删除第i个元素
{
    L.data[j-1] = L.data[j];
}

删除时平均移动元素个数:n*(n-1)/2n = (n-1)/2

链表(连接存储)

链表中第一个元素结点称为首元结点,最后一个元素称为尾结点。首元结点不是头结点。

单链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j25WW0ML-1631361136987)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103161822923.png)]

线性结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3b6A1cSW-1631361136993)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103161843031.png)]

结点可以连续,可以不连续存储
结点的逻辑顺序与物理顺序可以不一致
表可扩充

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gikqYGIq-1631361136996)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103162055240.png)]

定义
struct node{
    T data;
    struct node *link;
};
插入
newnode->link = first;
first = newnode; // 在第一个节点前插入

//首先定位到插入位置p后面
newnode->link = p->link;
p->link = newnode;
删除
q = first;
first = first->link;
delete q;	// 删除表中第一个元素

//删除p后面的节点
q = p->link;
p->link = q->link;
delete q;
带头结点的单链表

头结点位于表的最前端,本身不带数据,仅标志表头。
设置头结点的目的是
统一空表与非空表的操作
简化链表操作的实现。

前插法建立单链表

从一个空表开始,重复读入数据:
生成新结点
将读入数据存放到新结点的数据域中
将该新结点插入到链表的前端
直到读入结束符为止。

输入顺序与链接顺序相反

while(val != endtag)
{
    LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
    s->data = val;
    s->link = first->link;
    first->link = s;
}
后插法建立单链表

输入顺序与链接顺序相同

rear->link = s;
s = rear;
清空,计算长度,按值查找,定位
循环链表(约瑟夫环)

循环单链表是单链表的变形。链表尾结点的 link 指针不是 NULL,而是指向了表的前端。

为简化操作,在循环单链表中往往加入头结点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x9cuJLtr-1631361136997)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103164435110.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8SrvqP42-1631361136999)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103164837602.png)]

循环单链表的判空条件是

first -> link == first;

循环单链表的特点是:只要知道表中某一结点的地址,就可搜寻到所有其他结点的地址。
在搜寻过程中,没有一个结点的 link 域为空。

循环单链表的所有操作的实现类似于单链表,差别在于检测到链尾,指针不为NULL,而是回到链头。

在表尾可直接插入新结点,时间复杂性 O(1);
在表尾删除时要找前趋,时间复杂性 O(n);
在表头插入相当于在表尾插入;
在表头可直接删除,时间复杂性 O(1)。

双向链表

双向链表是指在前趋和后继方向都能遍历的线性链表。双向链表每个结点的结构为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pTQeMidO-1631361137000)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103165317973.png)]

双向链表通常采用带头结点的循环双链表形式。每一个结点处于两个链中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XfyhjXyY-1631361137003)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103165343965.png)]

p->lLink 指示结点 p 的前趋结点
p->rLink 指示结点 p 的后继结点
p->lLink->rLink指示结点 p 的前趋结点的后继结点,即结点 p 本身
p->rLink->lLink指示结点 p 的后继结点的前趋结点,即结点 p 本身

定位
插入

p的前驱结点为新插入结点

newnode->llink = p->llink;
p->llink = newnode;
newnode->rlink = p;
newnode->llink->rlink = newnode;

p的后继节点为新插入节点

newnode->rlink = p->rlink;
p->rlink=  newnode;
newnode->llink = p;
newnode->rlink->llink = newnode;
删除
p->rlink->llink = p->llink;
p->llink->rlink = p->rlink;

顺序表与链表的比较

基于空间的比较

存储分配的方式
顺序表的存储空间可以是静态分配的,也可以是动态分配的。
链表的存储空间是动态分配的。

存储密度 = 结点数据本身所占的存储量/结点结构所占的存储总量
顺序表的存储密度 = 1
链表的存储密度 < 1

基于时间的比较

存取方式
顺序表可以随机存取,也可以顺序存取。
链表只能顺序存取。

插入/删除时移动元素个数
顺序表平均需要移动近一半元素。
链表不需要移动元素,只需要修改指针。
若插入/删除仅发生在表的两端,宜采用带尾指针的循环链表。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWvVQ0ZV-1631361137004)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210103172524706.png)]

一元多项式

静态数组表示
int degree;	// 实际阶数
int coef[Maxdegree+1];	// 系数数组

优点:简化操作

缺点:系数多项式不经济

只保存非0项
struct data{
    float coef;	// 系数
	int exp;	// 指数
};

struct polynomial{
    int maxsize;	// 数组最大保存项数
    int n;	//实际项数
    data* Term;
}
链表
typedef struct node {		//多项式数据定义	
    float coef;	              	//系数	    
    int exp;		   	//指数
    struct node * link;	//链接指针
};

多项式的项数可以动态地增长,不存在存储溢出问题。

插入、删除方便,不移动元素。

加法(类似于归并排序)

?静态链表

3.栈和队列

栈(后进先出)

只允许在一端插入和删除(栈顶)

另一端(栈底)

顺序栈
struct seqstack{
    int *elem;
    int top, maxsize;	// top为栈顶指针
};

//初始化时S.top = -1
//判断栈空为判断S.top == -1是否为true
//判断栈满是否为S.top == S.maxsize-1

void push(SeqStack& S, int x)
{
    //栈满判断,栈满处理(建立新栈,将原来的栈拷贝)
    S.elem[++S.top] = x;
}

bool pop(SeqStack& S, int& x)
{
    //判断栈是否为空
    x = S.elem[S.top--];
    return true;
}

bool getTop(SeqStack& S, int& x)
{
    // 判断是否栈空
    x = S.elem[S.top];
    return true;
}
双栈共享一个栈空间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FgYWFiXw-1631361137006)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210106095937669.png)]

两个栈共享一个数组空间V[MaxSize],设立栈顶指针数组t[2]和栈底指针数组b[2]

t[i]和b[i]指定栈i的栈顶和栈底

初始

t[0] = b[0] = -1;	// 一开始未存元素
t[1] = b[1] = maxSize;

栈满条件

t[0] + 1 = t[1];

栈空条件

t[0] = b[0];
t[1] = b[1];
链式栈

顺序栈有栈满问题,一旦栈满需要做溢出处理,扩充栈空间,时间和空间开销较大。
链式栈无栈满问题,只要存储空间还有就可扩充。
链式栈的栈顶在链头,插入与删除仅在栈顶处执行。(前插法建立栈)

栈的混洗

当进栈元素的编号为1, 2, …, n时,可能的出栈序列有多少种

卡特兰数:1/(n+1)*C(2n,n)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vv4BxP3C-1631361137007)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210106103722470.png)]

队列

队列是只允许在一端删除,在另一端插入的线性表
允许删除的一端叫做队头 (front),允许插入的一端叫做队尾 (rear)。

顺序队列
struct{
    int elem[maxsize];
    int rear, front;
};

队列与栈的共性在于它们都是限制了存取位置的线性表;区别在于存取位置有所不同。

进出队列的方案

1.先加元素再动指针(队尾指针指示实际队尾的后一位置,队头指针指示实际队头的位置)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值