【考研—数据结构】时间复杂度、线性数据结构

注:以下内容均为个人复习使用,不保证所述内容绝对严谨;
注:考研知识点相对基础,因此这里只做知识点合集,不保证内容详细。

一、算法复杂度

时间复杂度,空间复杂度;
书写规则:

n趋近于无穷大
只关心最高阶
忽略系数(忽略常数)

(说白了这考题就是个极限等价问题,还只考你等价无穷大
(这里跟实操的时候考虑的还是不太一样,众所周知我的O(n)和dalao的O(n)是不一样的,100*n和n 天壤之别)

二、线性表

(易忘点:判满入栈/队,判空出栈/队)

定义

一、顺序表:(就是数组)

  1. 常考操作:插入、查找、删除、合并、就地转置
  2. 默认: 默认从下标0开始

二、链表:(就是类似于邻接表的东西)(后补:邻接表其实就是静态链表…)

  1. 分类: 单链表、双向链表、单循环链表、双向循环链表
  2. 常考操作: 插入、查找、删除、合并
  3. 静态链表:用结构体数组表示链表;特点:仍需提前预判空间规模,但删除插入操作O(1);eg.(邻接表)一类.
  4. 带头结点“ 与 ”不带头节点“ : 前者表示 头指针指向无值空间; 后者表示 头指针指向头元素(有值)。

三、常考点1:原地逆置

  1. 顺序表原地逆置: 头尾相应位置 swap( a ,b ) 。 额外空间O(1),时间复杂度O(n)。
  2. 链表原地逆置: 所有指针指向的地址不变,从头节点开始,逐一将 p->nex 修改为 已经逆置的链表部分的尾部。

四、常考点2:有序序列合并

  1. 顺序表合并时间复杂度过高,只需学会 双指针判断每个元素在总体序列的真正rank即可
  2. 链表序列合并:细节处理比较多。(也不知道考试要求的伪代码允许写多么伪,还是严格写比较好)

※※ 线性表热门考点 ※※

链表 原地逆置(手写代码)

有头节点时,head->nex为头元素;
无头节点时,head为头元素

//头指针为head,指向空
	//原链表 head->a[1]->a[2]....->NULL
	//目标形状: NULL <- a[1] <- a[2].... <-head 
	struct ss *pos,*later;
	pos=head->nex;
	head->nex=NULL;
	while(pos!=NULL){
		later= pos->nex;
		pos->nex = head->nex;
		head->nex = pos;
		pos=later;	
	}

有序 链表合并(手写代码)

//双列合并
	STU *p1=head1;
	STU *p2=head2;
	while(p1!=NULL){
		STU *pre2=p2;
		while( p2->nex!=NULL && p1->nex!=NULL &&
			p2->nex->va < p1->nex->va ) p2=p2->nex;
		STU *later2 = p2->nex;
		p2->nex = p1->nex;
		p1->nex = pre2;
		p1=p2->nex; p2=later2;
	}
	cout<<"After congregation:"<<endl;
	for(ss *i=head1->nex->nex;i;i=i->nex){//把两个头指针跳了 
		cout<<i->va<<" ";
	} cout<<endl;

吐槽:上机写代码舒服多了,手写代码好像在create shit…

三、栈

定义

一、定义:尾进尾出 / top进 top出 的线性表
二、Tips:
坑点1:考研默认top指向空,内容位置在 [0,top-1]
坑点2:先判空再出栈,先判满再入栈
三、链栈: 指针+链表表示栈
四、 对顶栈
就是两个栈共用同一个连续空间,分别从该连续空间的两端向中间进行存储。
对顶栈栈满标志为 size_stack1+size_stack2==n;

链栈–定义

struct stack{//即单链表
	stack *link;//指向该元素的下一个
	int size value;//信息存储
};
struct stack * TOP;//top指针锁定栈地址

※※ 栈热门考点 ※※

非递归实现递归函数**

例子1:

//递归函数
int ack(int m,int n){
	if(m==0) return n+1;
	if(n==0) return ack(m-1,1);
	return ack(m-1,ack(m,n-1));
}
//非递归--栈写法
int ack_in_stack(int m,int n){
	int stack[N],top=0;
	stack[top++]=m;stack[top++]=n;//top位指向空
	whlie(top!=1){
		m=stack[--top];
		n=stack[--top];
		if(m==0) stack[top++]=n+1;
		else if(n==0) stack[top++]=m-1,stack[top++]=1;
		else stack[top++]=m-1,stack[top++]=m,stack[top++]=n-1;
	}
	return stack[0];
}

较难:栈写 二叉树的前序遍历、后序遍历

后缀表达式

阅读方法(后缀转中缀):碰到一个运算符,取两个数字,运算结果放回数字序列
优先级问题:最先出现的运算符号最先计算
例: AB+CD - * EFG * - /
中缀: (A+B) * (C-D) / ( E - F * G )

前缀表达式

阅读方法(前缀转中缀):碰到一个数字取一个运算符跟在数字身后
优先级问题:最后出现的运算符号最先计算
例: + - * ^ ABCD / E / F + G H
中缀 A^B * C - D + E/F/ (G+H)

出栈顺序判断

手跑栈即可

括号匹配、进制转换

汉诺塔

书上栈和队列的部分还考了汉诺塔的手算题,
汉诺塔不是个dp吗2333,为社么放这里…
汉诺塔问题题解链接:博客链接

递归与非递归比较

递归比非递归:(效率低)速度慢、占用空间大;(用户友好)可读性更强,更容易证明,更清晰

四、 队列

一、定义:尾进头出 / rear进 front出 的线性表 二、 特殊存储结构:
链 队:纯链表
循环队列 :顺序表写队列时用,目的是为了防止队列的“假溢出”
双端队列 : 输入受限 两端出 一端入 输出受限 两端入 一端出

考点:出队顺序、和栈一起考

五、 矩阵压缩

特殊矩阵信息的压缩存储
考点主要在下标信息的相互转换、计算 且以下对于矩阵的名称 (定义同线性代数)

暴力存储:O(n^2)
对称矩阵: 用线性数组存储一半矩阵的信息 O( (1+n)*n/2 )
三角矩阵: 线性数组存储一半矩阵的信息 O( (1+n)*n/2 )
稀疏矩阵: 这个意思基本跟邻接表存图差不多 O(M)
三对角矩阵 : 爪形行列式,首尾两行各有两个元素,其余行都是三个元素。

压缩存储方法:

三元组:

//只记录非0元素,未记录点默认为0.
int n,m,c;
struct ss{
	int x,y,va;//行下标、列下标、值
}Poing[N];//point[i]表示原矩阵中第i个非零点 A[x][y[=va;
//另存三个数据: n,m,c,分别表示行数、列数、非零元素数

十字链表:

/*十字链表的结构类型定义如下:*/
typedef struct{
    int x,y,va;//行下标、列下标、值
    STU *right; //行方向后继
    STU *down; //列方向后继
} STU;
typedef struct{
    STU *X_head;//行链表头指针
   	STU *Y_head;//列链表头指针
    int m,n,len; /*稀疏矩阵的行数、列数、非零元素的个数*/
} List;

二维矩阵连续空间存储地址的计算(注意下标起止点)

六、串

1. KMP算法

问题描述:判断短字符串是否为长字符串的子串
KMP算法的相关博客
时间复杂度:O(长串长度)
核心思想:nex数组表示公共前缀,回弹位置

2. 马拉车算法

问题描述:求最长回文子串
马拉车算法的相关博客
核心思想:回文串对称性质

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GoesM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值