标签:
说到算法,排序算法可能是大部分人最早接触的算法,我还记得我接触的第一个排序算法可能就是冒泡排序(bubble sort)了,估计不少同学和我一样吧。再后来接触到了插入排序(insertion sort),归并排序(merge sort),快速排序(quick sort),堆排序(heap sort),希尔排序(shell sort)。如果回顾一下这些排序算法,仔细思考一下他们有什么共同点的话,你或许会发现他们都是通过比较一对对元素来实现排序的,这就是所谓的比较模型。这篇博客就将对比较模型下的常见排序算法做一个总结。(以下算法的排序都是按升序排列)
冒泡排序(bubble sort):
冒泡排序的思想是从第一个元素开始每个元素都同它后一位元素进行比较,如果该元素大于其后一位元素就交换这两个元素。如果我们要对n个元素排序的话,可以看见,第一次遍历需要遍历到第n-1个元素,并且经过这趟比较后,最大的元素一定来到了第n个位置。从最大的元素开始,一个个被安放到正确的位置上,这就是冒泡的含义。经过第一趟比较后,下一趟比较只需要遍历到第n-2个元素,并且第二大的元素的位置也将被确定。如此下去..直到所有元素的正确位置都被确定了为止。
void bubble_sort(int a[],int n) { int i, j; for (j = 0; j < n-1; j++) for (i = 0; i < n - j - 1; i++) if (a[i] > a[i + 1]) swap(&a[i], &a[i + 1]); }
在上面的代码中把j看作已被安放到正确位置上的元素数,整个代码段的逻辑简直清晰的不得了。
算法的时间复杂度显然是θ(n^2)。但我看到百科上写着最佳时间复杂度是O(n),查了一下后原来是可以改进一下排序算法,改后版本如下:
void bubble_sort(int a[],int n) { bool didswap = false; int i, j; for (j = 0; j < n - 1; j++) { for (i = 0; i < n - j - 1; i++) if (a[i] > a[i + 1]) { swap(&a[i], &a[i + 1]); didswap = true; } if (didswap == false) return; } }
这样在数组已经顺序排列的情况下得到O(n)的时间复杂度。其余时候均为θ(n^2)。
插入排序(insertion sort):
其实插入排序也分好几种,这里先介绍最简单的直接插入排序。其思想是从第i个元素开始(前i-1个元素以及排好序的前提下),先将其值记录下来,存放到一个变量比如说key中去;然后从第i-1个元素向第一个元素扫描,如果被扫描的元素大于key,则将该元素后移一位,否则将key插入到该元素后面去。我们一般从第二个元素开始,第一个元素可认为已经排好了序。
void insertion_sort(int a[],int n) { int i, j, key; for (i = 1; i < n; i++) { key = a[i]; for (j = i - 1; j >= 0 && a[j] > key; j--) a[j + 1] = a[j]; a[j+1] = key; } }
分析直接插入排序算法的时间复杂度,最外层是一个n-1次循环,循环里花费的时间为θ(j),所以做一个n-1次的求和,因为这是一个算数级数,最后的结果应该是θ(n^2)。
临时有事,先占个坑,明天再更。
标签:
原文地址:http://www.cnblogs.com/evilkant/p/5769298.html