toaday I'm going to review some important sorting algorithms based on comparison.besides,related data structures such as heap ,will also be talked.
1.1 堆排序
1.2 选择排序,插入排序,冒泡排序
1.3 快速排序
1.4 相关笔试题分析
1.1 堆排序
1.1.1 什么是堆? what and why?
1.1.2 堆的实现?什么二叉堆?
1.1.3 堆的相关操作?
1.1.4 堆与优先队列的关系? 优先队列 what and why?
1.1.5 如何利用堆进行堆排序 ?
1.1.6 堆的优缺点? 堆排序分析.
1.1.7 References & Externel Links
1.1.1 什么是堆?Heap?
1.1.1.1 what?
很多人以为
堆 == 二叉堆 == 优先队列 他们之间的关系真的是相等的吗?
在英语中,heap作为动词 把..堆起/使成堆 的意思。作为名词是堆/很多的意思。
1964年,J. W. J. Williams 发明了堆排序(Heap Sort)[1],同时描述了如何利用二叉堆来实现一个优先队列。 使用该种数据结构可以高效的获取队列中的最大值或者最小值,从而进行排序操作。
(关于二叉堆见1.1.2,什么是优先队列见1.1.4 )
之后,后人不断加以改进,产生了一系列不同的堆.
比如k-叉堆,斐波那契堆,二项堆,左式堆,斜堆等等。 见堆变体。
从最初William的二叉堆用于堆排序,到后来的各式各样的堆,基本都是以树的形式表示。因此说
堆是一共基于树的数据结构。
维基百科也有说:A heap is a specialized tree-based data structure that satisfies the heap property。
所谓的heap property(堆的性质)即是大根堆/小跟堆的性质(所有父节点≥/≤子节点)。
因此,亦可以说堆不是一个数据结构,而是一类数据结构[this is my personal opinion]。
1.1.1.2 关于二叉堆 Binary Heap
二叉堆是一种堆。
维基百科上说:
A binary heap is a heap data structure that takes the form of a binary tree. Binary heaps are a common way of implementing priority queues.[2]
显而易见的,将堆与二叉堆划等号(堆heap == 二叉堆bianry heap),显然是一个不成熟的想法。
heap != bianry heap,that is to say , heap is a class of data structures.but binay heap is a common type of heap.
它们与优先队列的关系将会在1.1.4中简要探讨。
1.1.1.3 why ?
既然知道了什么是堆,那么为什么要用堆呢?williams为什么要引入它呢。它又有哪些优点呢。
我认为,对于传统的大根堆或者小跟堆而言,最大值/最小值分别处于root节点位置.(为什么?)
这方便我们从中读/取最大值,最小值,这是一个O(logn)的操作。相对于数组而言,这有显著的性能提升。因此堆适用于那些需要频繁取最大/最小值的应用。
1.1.2 堆的实现?什么二叉堆?
堆采用树结构实现。对于不同的堆有不同的树实现。
1.1.2.0 什么是二叉堆
二叉堆是一种堆,二叉堆广泛地被使用,以至于,当我们谈论堆时,通常默认指的就是二叉堆。
二叉堆也是优先队列的一种常见的实现。 (什么是优先队列见1.1.4 )
二叉堆基于二叉树是实现,除了是二叉树之外,还需要满足下面两个条件。
1.Shape property :一个二叉堆是一个完全二叉树。在此含义即是所有的层(除了最后一层)都是满的,只有最后一层不是满的,而且最后一层的节点从左向右依次填充。
2.Heap property: (大根堆)对于所有的父亲节点而言,其值≥子节点。
(小根堆)对于所有的父亲节点而言,其值≤ 子节点。 【注意可以等于】
1.1.2.1 二叉堆的实现
对于最常见的二叉堆:
他使用二叉树来实现,这个二叉树是一个完全二叉树(完全二叉树在不同的文献中有着不同的含义,在此处我们取所有的层(除了最后一层)都是满的,只有最后一层不是满的,而且最后一层的节点从左向右依次填充。见维基百科-完全二叉树)
逻辑上,二叉堆是一棵树。 物理上,二叉堆常用数组来实现。而不需要指针。这样可以获得较好的性能。(考虑为什么可以?)
如下图所示:
逻辑结构:
物理结构:
image
1.1.2.2 斐波那契堆的实现
1.1.2.3 二项堆堆的实现
1.1.3 堆的相关操作?
对于不同的heap,我们有不同的操作,在此,我们先对最为广泛的二叉堆进行阐述。
【本部分主要采自算法导论第三版 && 只针对大根堆(小根同理)】
【注:大根堆 == 最大堆,小根堆 == 最小堆】
- Max-Heapify 维护大根堆的性质。O(log n)
- Build-Max-Heap 从无序的输入数据数组中构造一个大根堆。 O(n)
- HeapSort O(nlog n ) 对一个数组进行[原址]排序。
- Max-Heap-Insert,Heap-Extract-Max,Heap-Increase-Key,Heap-Maximum【O(1)】过程、时间复杂度均为O(log n )功能是利用二叉堆实现一个优先队列。
【此处只是列出了算法伪代码以及算法思想,比较晦涩,最好还是找到具体的例子(譬如算法导论上就可以找到),配合算法,会有更加深刻的理解,此处限于篇幅就不做举例了】
1.1.3.1 Max-Heapify
Max-Heapify(A,i) 自顶向下维护大根堆性质。 O(log n)
1.1.3.2 Build-Max-Heap
Build-Max-Heap(A) 从最后一个非叶子节点开始,到根节点一次调用Max-Heapify(A,i)
【此算法的复杂度是O(n) 而不是O(n log n)试想为什么?】【算法导论上有证明】
1.1.3.3 HeapSort
HeapSort(A) O(n log n )
思想:
每次从root节点取出最大值,然后调整。
即:
从最后一个节点开始,将其调换A[1]](最大值),将脱离堆,从根节点开始调整堆。
1.1.3.4 优先队列の操作
Max-Heap-Insert,Heap-Extract-Max,Heap-Increase-Key,Heap-Maximum【O(1)】过程、时间复杂度均为O(log n )功能是利用二叉堆实现一个优先队列。
these operations are implemented to implement a priority queue.
the operations above ,i.e. Max-Heapify,Build-Max-Heap ,HeapSort are enough for heapsort.
- Max-Heap-Insert,在大根堆中插入一个元素并调整之
- Heap-Extract-Max,取出最大值即根节点,然后调整之
- Heap-Increase-Key,将某个节点增加一定的值,然后调整之
- Heap-Maximum,返回根节点的值
1.1.4堆与优先队列的关系? 优先队列what and why?
1.1.5 如何利用堆进行堆排序 ?
1.1.6 堆的优缺点? 堆排序分析.
1.1.7 References & Externel Links
1.2 选择排序,插入排序,冒泡排序
1.3 快速排序
1.4
[1] : Williams, J. W. J. (1964), "Algorithm 232 - Heapsort", Communications of the ACM, 7 (6): 347–348
网友评论