【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

导读:本篇文章讲解 【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1、堆

堆结构

堆结构就是用数组实现的完全二叉树,完全二叉树中如果每颗子树的最大值都在顶部就是大根堆,完全二叉树中如果每颗子树的最小值都在顶部就是小根堆,优先级队列结构也是堆结构。

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

堆排序

先让整个数组都变成大根堆结构,建立堆的过程:
1、从上到下的方法,时间复杂度O(N*logN)
2、从下到上的方法,时间复杂度O(N)
把堆的最大值和堆末尾的值交换,然后减少堆的大小之后,再去调整堆,一直周而复始,时间复杂度O(N*logN),堆的大小减成0之后,堆排序结束。

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

已知一个几乎有序的数组,请选择一个合适的排序策略,对这个数组进行排序。(☆几乎有序:如果把数组排好序的话,每个元素移动的距离一定不超过k,并且k相对于数组长度来说是比较小的)

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

自定义堆比较器

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

2、前缀树

单个字符串中,字符从前到后的加到一颗多叉树上。字符放在路上,节点上有专属的数据项(常见的是pass和end),所有样本都这样添加,如果没有路就新建,有路就复用,沿途节点的pass值增加1,每个字符串结束时来到的节点end值增加1,一般可用于完成前缀相关的查询。

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

前缀树-支持英文以外的字符

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

3、桶排序-计数排序&基数排序

桶排序思想下的排序都是不基于比较的排序,时间复杂度为O(N),额外空间复杂度为O(M),应用范围非常有限,需要样本的数据状况满足桶的划分。

计数排序

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

基数排序

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

4、排序算法的稳定性

稳定性是指同样大小的样本在排序之后不会改变相对次序,对基础类型来说,稳定性毫无意义;对非基础类型来说,稳定性才有意义。有些排序算法可以实现成稳定的,而有些排序算法无论如何都实现不成稳定的。

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

不基于比较的排序,对样本数据有严格要求,不易改写;

基于比较的排序,只要规定好两个样本怎么比大小就可以直接复用;

基于比较的排序,时间复杂度的极限是O(N*logN)

时间复杂度O(N*logN)、额外空间复杂度低于O(N)、且稳定的基于比较的排序不存在;

为了绝对的速度选快排,为了省空间选堆排,为了稳定性选归并。

常见的坑:

① 归并排序的额外空间复杂度可以变成O(1),“归并排序内部缓存法”,但是将变得不在稳定;

② “原地归并排序”垃圾,会让时间复杂度变成O(N^2);

③ 快速排序稳定性改进,“01 stable sort”,但是对样本数据要求更多;

④ 在整型数组中,请把奇数放在数组左边,偶数放在数组右边,要求所有奇数之间原始的想对次序不变,所有偶数之间原始相对次序不变,且要求时间复杂度做到O(N),往外空间复杂度做到O(1),抱歉这做不到;因为奇、偶的要求是一个“零一标准”(不是奇数就是偶数),在快速排序中的partition是做不到稳定性的,如果能做到稳定性的话,快速排序为什么不改成稳定的呢?

工程上对排序的改进:

① 出于对稳定性的考虑;

② 充分利用O(N*logN)和O(N^2)排序各自的优势。

5、链表

快慢指针问题

输入链表头节点,奇数长度返回中点,偶数长度返回上中点

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

输入链表头节点,奇数长度返回中点,偶数长度返回下中点

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

输入链表头节点,奇数长度返回中点前一个,偶数长度返回上中点前一个

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

输入链表头节点,奇数长度返回中点前一个,偶数长度返回下中点前一个 

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

给定一个单链表的头节点head,请判断该链表是否为回文结构(中间轴对称结构)

使用容器-压栈弹出逐一比对

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

不靠容器-改原链表逐一比对

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

将单向链表按某值划分成左边小、中间相等、右边大的形式

把链表放入数组里,在数组上做partition

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

分成小、中、大三部分,使用6个变量把各部分之间串起来

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

rand指针是单链表节点结构中新增的指针,rand可能指向链表中的任意一个节点,也可能指向null
给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数完成这个链表的复制,并返回复制的新链表的头节点
要求:时间复杂度O(N),额外空间复杂度O(1)

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

使用容器

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

不靠容器

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

给定两个可能有环也可能无环的单链表,头节点head1和head2。
请实现一个函数,如果两个链表相交,请返回相交的第一个节点,如果不相交,返回null。
要求:如果两个链表长度之和为N,时间复杂度为O(N),额外空间复杂度为O(1)

☆链表问题中两大德高望重的难题之一,另外一个约瑟夫环问题比这个要更难一些

【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表【算法扫盲】堆、前缀树、桶排序、排序算法的稳定性、链表

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/111925.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!