摘要:
B树是一种很有用的查找结构,能够在O(h)的时间复杂度内完成查找操作(h为树的高度)。其它操作,比如求最大,最小,前驱,后继等,复杂度均为O(h)。当树越平衡时,时间复杂度越低(O(lg(n)),因此,可以通过随机化建树,达到这一目的。另外还有一些结构,比如红黑树,其自身的性质可以保证树的平衡性,因此性能相对较好。这里我用c++实现了B树,个人认为,除了删除一个节点的操作有点复杂外,B树绝大部分操作都是很直观的,实现起来还是很容易的。代码如下:btree.h头文件, 1 #ifndef _BTREE_H_ 2 #define _BTREE_H_ 3 4 class BTree 5 { 6 p. 阅读全文
posted @ 2014-01-06 21:29
Tiancai Ye
阅读(171)
评论(0)
推荐(0)
摘要:
顺序统计量即求出第i小的元素,这里放在了排序算法中,是因为,如果我们对一个数组进行排序,那么第i小的元素就是a[i-1]。但是,显然这样时间复杂度较高。首先来看,如何求最大最小值。通过遍历一遍数组,很容易在O(n)内得到最大最小值。那如果需要同时获得最大最小值呢?O(2n)是可以完成的,但是实际上,我们只需要O(1.5n)就可以完成,秘诀在于,我们将数组中的两个元素成对比较,小的与当前最小值比较,大的与当前最大值比较,这样我们处理两个元素,只需要3次比较。我们再来看,如何在平均线性时间获得第i小的元素。模仿快速排序,我们可以对数组进行分割,不同的是,我们只需要继续在分割后的某一个子数组中继续查 阅读全文
posted @ 2014-01-06 21:22
Tiancai Ye
阅读(302)
评论(0)
推荐(0)
摘要:
算法导论有证明,基于比较的排序(插入,选择,归并,快速,堆排序)的渐进时间复杂度下限为O(lg(n))。因此,这里提到的线性时间排序,必然不是基于比较的排序。本质上讲,个人认为这些线性时间排序就是用空间换取时间。计数排序,a,b均为长度为n的数组,a为输入,b为排序好的数组,要求是a的元素必须都为小于k的非负数,计数排序直接将值作为c数组的寻址 1 void counting_sort(int a[], int b[], int n, int k) 2 { 3 int* c = new int[k]; 4 5 for (int i = 0; i = 0; --i)12 ... 阅读全文
posted @ 2014-01-06 20:33
Tiancai Ye
阅读(172)
评论(0)
推荐(0)
摘要:
快速排序,顾名思义,当然很快~~~其平均渐进时间复杂度为O(lg(n)),而且常系数较小,在多数情况下能达到最优性能。当然,在最差情况下,时间复杂度为O(n2),我们可以通过随机选取的方式避免最差情况。快速排序的核心其实也是分治思想,将一个数组分为两部分,一部分大于a[q],一部分小于a[q],那么对这两部分依次如此排序下去,就可以将整个数组排序。关键在于如何在O(n)的时间内完成分割: 1 int partition(int a[], int p, int r) 2 { 3 int key = a[r - 1]; 4 int i = p; 5 for (int j =... 阅读全文
posted @ 2014-01-06 20:24
Tiancai Ye
阅读(154)
评论(0)
推荐(0)
摘要:
堆排序是一个很有趣的算法,其时间复杂度为O(lg(n)),同时是就地排序,空间复杂度优于归并排序(归并排序在归并子结果时需要另外开辟一个数组)。其唯一的缺点就是常系数较大,在问题规模较小的时候优势不明显,甚至较差。算法主要利用了堆这个数据结构。那么什么是堆呢?堆即为一个完全二叉树,同时具有堆特性:对大顶堆而言,父节点始终大于等于子节点,对于小顶堆而言则相反。由于是完全二叉树,可以将整颗树存储在线性表里面,同时可以快速的计算出父节点,左右子节点的位置。如下代码所示: 1 inline int parent(int i) 2 { 3 return (i - 1) / 2; 4 } 5 6... 阅读全文
posted @ 2014-01-06 20:17
Tiancai Ye
阅读(209)
评论(0)
推荐(0)
摘要:
归并排序使用了分治的思想,即将一个数组的排序分解为两个子数组(首先分解为规模更小的子问题),然后对这两个子数组分别排序(分而治之),最后对两个已排序的子数组进行合并(合并子问题结果)。关键在于,合并操作只需要O(n)的时间复杂度,那么根据master定理,归并排序的整体时间复杂度为O(lg(n)),从渐进时间复杂度来看,优于插入排序和选择排序(但是其常系数比插入排序大,在问题规模较小时,可能没有插入排序优)。整个代码的关键部分在于如何在O(n)的时间复杂度内合并子问题的结果。代码如下: 1 void merge(int a[], int p, int q, int r) 2 { 3 i... 阅读全文
posted @ 2014-01-06 19:54
Tiancai Ye
阅读(165)
评论(0)
推荐(0)
摘要:
插入排序和选择排序可以说是最基本的排序方法,时间复杂度都是O(n2),实现如下:插入排序: 1 void insertion_sort(int a[], int n) 2 { 3 for (int i = 1; i = 0 && a[j] > key) 8 { 9 a[j + 1] = a[j];10 --j;11 }12 a[j + 1] = key;13 }14 }选择排序: 1 void selection_sort(int a[], int n) 2 { 3 for ... 阅读全文
posted @ 2014-01-06 19:41
Tiancai Ye
阅读(175)
评论(0)
推荐(0)