数据结构与算法基础总结

数据结构与算法:
双向循环链表怎么实现
栈有几种实现方式
以数组第一个位置作为栈顶的出栈入栈时间复杂度,作为栈低的时间复杂度。
STL栈的实现原理以及自己实现的原理区别
(自己实现如果使用静态数组,需要传参指定静态数组的大小,也可以使用动态数组)
以链表实现不同端作为栈顶的时间复杂度
双向循环链表找到最后一个元素的时间复杂度  listp
数组实现的栈和链表实现的栈比较
数据量大数组更好,为什么?

栈实现的leet题
有效括号
最小栈
最小栈的两种实现方式
两个栈时,大于不加入最小栈
最小栈就是利用一个栈来保存最小元素

队列
循环队列怎么实现
(使用两个指针)
tail=
使用两个指针,怎么判断循环队列为空
怎么判断循环队列满了———牺牲一个存储空间
leet题
两个栈实现队列

排序算法
快慢指针
移动零
数组元素交换时,怎么减少交换次数?
1,下标相等无需交换。

什么是原地算法
(在原来的空间就完成操作的算法,没有申请额外空间)
什么是稳定的排序算法
排序过程中,相等元素的相对位置不会发生改变

对撞指针

反转字符串
1、对撞指针2
 2、std::reverse(a.begin(),a.end());

递归
递归的概念
函数中调用函数
函数的递归调用需要使用到栈,保存在栈中的数据结构叫栈帧,栈帧包括三个部分:参,局,地。
如果递归没有退出条件,就会stackOverflow。

递归和迭代的区别
函数调用函数和函数内部循环
递归代码量可能少,但是运行时占用内存多。

斐波那契数列,走台阶
一模一样的迭代实现,

排序算法
冒泡,选择,插入排序区别和实现过程
必须三分钟内写出来

冒泡排序的重点是:
n个元素大循环n-1轮,小循环是n-大循环循环的次数,即每比较一轮下一轮少一个
优化:bool值第一轮判断数组是否存在交换,不存在则已经有序,则直接退出
不到最后一个

选择排序
选择最小的往前排序
选择排序原理和冒泡排序一样,n个元素大循环n-1轮,小循环比较到最后一个元素
找最小下标
冒泡选择比较
冒泡原地稳定,用的多
选择原地不稳定,用的少

插入排序
从第二个开始,小于就一直往前交换,否则下一个
注意插入排序不是找插入位置,而是往前排序
也是第一轮n个元素n-1轮,小循环当前元素往前循环比较
往前排序

以上三种排序算法时间复杂度都是___

性能比较:插入》选择》冒泡

归并排序
归并排序的实现原理

快排的原理以及实现
5分钟内写出来
快排随机选取分区点的公式
不随机选取会有什么问题
快排无论选择第一个,最后一个,还是随机,实现过程都一样

快排和归并是反着来的
不快
归并两两合并是需要使用到额外空间

快速排序对有序数组的退化和处理方法
快排怎么解决有很多重复元素的问题
三路快排实现原理  great从后面来,中间指针所指数据用于和less和great比较

二分查找
两种实现过程 三分钟实现
时间复杂度
寻找目标元素,寻找插入位置

如何防止mid计算时,数据溢出

几种实现过程以及变化
1、三种最简单的实现
等于的一种
不等于的两种,最后left=right,还需要比较等不等于目标值。
2、查找第一个等于目标元素的下标
注意判断条件
3、查找第一个大于等于目标元素的位置
大于等于可以合并
(不同于找元素插入位置,不可以合并)
4、查找最后一个小于等于目标元素的位置,
小于等于可以合并
5、查找最后一个等于目标元素的位置

二分查找下标不跳过mid的变形问题
1、这个边界值可能符合需求,依然保留它。
2、第一个大于等于,最后一个小于等于。
第一个在左边,左往右靠,靠到相等
最后一个在右边,右往左靠,靠到相等
注意,右往左靠需要加1
防止4,5计算下标一直是4,但是right一直等于5,导致循环退出不了。

链表
1,反转链表
两种方法
三个指针的方法:注意空指针
回勾递归算法:注意回勾的是当前head
5行代码ko

2,链表中间结点
各就位在第一个结点
想象只有三个结点链表
快慢指针
为什么慢指针先走
快慢指针都可以先走,而如果快指针先走,只是快指针到达最后需要跳出,跳出之前要完成慢指针再走一步
快指针走完每一步都要进行判断

3,删除链表的倒数第n个结点
还是三个结点链表
快指针先走n+1步,再一起一步一步走
要删除的结点是slow的下一个结点

各就位之后,无论谁先走,最后走的次数都是一样的
注意以上两题判断退出条件的区别和原因

4,合并两个有序链表
亚结点,三个指针完成

二叉树
二叉树的前中后序遍历,层序遍历
迭代和递归实现
二叉树的三种遍历使用迭代时为什么要用栈,用队列可以吗
递归的时候结果集作为参数在另一个函数里面使用性能更好
中序遍历(迭代)的细节:
1、提前放入根结点,重复
2、放入右结点,如果判空,那么为什么会造成死循环。
3、如果栈为空是不是就代表遍历完成了。
4、循环的最后一句的作用。

优先选择递归实现
层序遍历更具队列先进先出的特点,一层循环,两层循环都可以实现。

什么深度优先搜索(DFS)和广度优先搜索(BFS)
depth first search

breadth first search

二叉树的几个算法:
1、二叉树的最大深度
深度优先搜索
创建新结点保存二叉树的结点和每个结点的层数
每个结点的层数怎么计算,什么时候保存
广度优先搜索———层序遍历
2、路径之和
递归实现可以传递新参数,无需额外空间
可以用加也可以用减
使用迭代时,怎么保存到达每一个结点时的数据总和。
(学会使用结构体保存多余而且复杂了数据集)
3、翻转二叉树
dfs和bfs都可以实现
只需将每个结点的两个指针交换指向即可
递归,迭代都可以实现
想象7个结点的书

4、相同的树
dfs和bfs的实现过程而已,只是每一次处理两颗树
递归也可以实现
5、对称二叉树
a.递归——一个左起遍历,一个右起遍历
b.还可以将两颗子树的其中一颗先翻转,再比较是否为相同树
c.迭代——— 一个队列,两个队列都可以,两个相同顺序遍历也可以,一个左起一个右起也可以。

什么是二叉查找树
特点:
左小右大
查询,插入,删除的时间复杂度同二分查找
二叉查找树退化问题
怎么防止

什么是平衡二叉查找树
平衡什么东西
(平衡一颗二叉查找树左右子结点数不要相差太多)

举例三种平衡二叉查找树
1、AVL树要求树中任何结点的两个子树高度差最大为1。
2—3树、树中的一个结点可以存储两个数据,这个结点可以有三个指针,而这棵树又符合平衡二叉查找树特点。


说说红黑树的特点
1,是一颗平衡二叉查找树;
2,左小右大;
3,每个结点不是红色就是黑色;
4,根节点是黑色(人头也是黑色);
5,如果一个结点是红色 那么它的子结点必须是黑色;
6,任何结点到叶子结点的任何路径所含黑结点的个数必须相同。
堆和优先队列
什么是堆
堆就是二叉堆
内部实现:
本质上就是一颗完全二叉树
什么是完全二叉树
1,完全二叉树的两个特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。需要注意的是,满二叉树肯定是完全二叉树,而完全二叉树不一定是满二叉树

大顶堆
leftindex=index*2+1
rightindex=index*2+2
parentindex=(index-1)/2

往二叉树(数组)中插入元素,应该插入什么位置———数组的第一个空闲位置,就是二叉堆的最后一个位置,需要上浮
push_back,
siftup
add——上浮
remove——下沉
下沉的过程:
因为要删除堆顶元素,我们用最后一个元素覆盖堆顶元素,因为是大顶堆,所以再让这个元素和子结点中大的交换,一直下沉即可。

小顶堆
同理

完全二叉树在数组中怎么存储

什么是堆化heapify
将一个数组转为二叉堆存储形式
方法:将所有的非叶子结点下沉
怎么获取最后一个非叶子结点
最后一个叶子结点的父结点就是


什么是优先队列
利用大顶堆和小顶堆实现的优先队列,只能对堆顶元素进行操作

STL的优先队列默认是大顶堆还是小顶堆?

内部实现
大顶堆,小顶堆

优先队列存储结构体需要做什么
怎么自定义比较函数
比较函数大于号小于号决定什么

优先队列会去重吗
不是set和map

算法:
1,合并k个有序链表
两种实现方法,
可以利用亚杰点加三个指针的方式
也可以优先队列
k个链表中可能有空链表
2,数组中的第k个最大值
注意,是排好序后的第k个最大元素,就是倒数第k个元素。
第几是从1开始的



什么是floodfill算法
二维数组和一维数组的转换
二转一
index=i*col+j;

一转二
i=index/col;
j=index%col;

column列

二维数组的四联通
需要一个二维数组

二维数组八联通

海量数据查询
怎么判断某个数是否在海量的数据当中
用哈希存储数据会发生什么
1亿数据=1亿位=1MB

什么是位图
就是用存储数据容量的位来表示一个数据是否存在。

怎么实现
数组存储int,一个int8字节,32位。
要存储num则:
计算存储在哪个int:id=num/32
计算存储在int中的哪个位:
bitId=num%32

或运算做什么,与运算做什么

布隆过滤器是什么
比位图更省内存的数据存在表示方法
位图存储每一个哈希函数计算出来的值

怎么实现
位图+多个哈希函数
误判
不存在一定不存在
存在不一定存在
说说红黑树的特点

缓存淘汰机制

FIFO,LRU,LFU

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值