常用排序、选择算法
2012-05-30 11:10
190 查看
1 插入排序
插入排序的左边是有序的,依次从右边拿出一个数,插入到左边,直到右边没有更多的数,此时左边的数已经全部按序排列。
插入排序的C语言实现
插入排序的平均时间复杂度是O(N^2),当输入序列已经排好序的情况下,可以达到O(N)。所以当数组已经部分排好序的情况下,插入排序的效率较高。
这里是一个关于插入排序的舞蹈视频:http://t.cn/hros0W 。不管怎么样,视频只能帮助你理解排序的一个总体思路,但是只有切身用代码实现了,才算是真正会了,有时候少一个等号,迭代少了一次,都会导致结果的错误。至于完全理解每个算法的适用场合,还需要在工作中的不断经验积累,以及良好的数学功底。
2 冒泡排序 Bubble Sort
冒泡大概是最好理解的一个排序算法之一了,不过我第一次接触的时候也花了一些时间才明白过来。从名字上来看,冒泡排序就像是水里的泡泡一样,最大的元素不断的浮出水面,排到整个数组的最后。具体的说,第一次迭代,最大的元素会排到数组最后,第二次迭代,次大的元素会排到数组的倒数第二,第三次迭代,第三大的元素会排到数组的倒数第三……以此类推。
冒牌排序的平均时间复杂度是O(N^2),最坏的情况是O(N^2),最优情况O(N)。
冒泡排序的C实现代码:
冒泡排序的舞蹈视频:http://t.cn/hrf58M
3 快速排序
快速排序如它的名字一样,是速度最快的排序之一。快速排序的平均时间复杂度是O(NlogN),最坏的情况是O(N^2)。
快速排序是一种递归排序算法,首先选择一个pivot轴心元素,让数组中比pivot小的元素排到其左边,比它大的元素排到右边。然后再递归用快速排序整理pivot左边的部分,以及右边的部分。直到整体实现有序。这里使元素分别排到pivot两边的算法叫partition分区算法。最好的pivot选取是选择一个数组的中数median,如果不巧选到了一个数组里的Max or Min,就会导致最坏情况的发生。具体的分析就不在这里说了。如果想知道去看看CLRS算法导论,里面有详细的partition算法,还有关于如何选取一个好的pivot。
快速排序的C语言简单实现:
同样在最后给出舞蹈视频:http://t.cn/ScTA1d
4 归并排序 Merge Sort
一直想不通为什么要把Merge翻译成归并…
Merge Sort也用到了递归,更确切的说法是用到了Divide and Conquer的分治思想,分:把一个数组分成2段,先将左边排序,再将右边排序,合:最后融合到一个数组里。
伪代码:
void mergeSort(
left = mergeSort(array, 0, middle);
right = mergeSort(array, middle, end);
merge(left, right);
}
Merge Sort的平均和最坏的时间复杂度都是O(NlogN),至于怎么得出的可以参看算法导论CLRS,简单的说一下:设时间复杂度是T(n),那么从上面伪代码可以推出递归式:T(n) = 2T(n/2) + O(n), 这里的O(n)最后merge过程的时间复杂度,可以求出T(n)是O(NlogN),有个公式的,你也可以推理或者猜一个答案来反证,总之方法很多,如果你本科算法课好好听了应该会有印象。
简单的说一下Merge过程,现在有两个排好了序的数组,然后要融合它们,怎么做?分别从两个数组的头部开始迭代,逐个比较,小的那个拿走,直到迭代完成。
Merge Sort的C语言实现:
还有一点关于merge过程想说的,上面的最后,只需要copy左半部分剩下的到原数组里,为什么呢?因为右半部分如果有剩下,那么它已经在原数组里正确的位置上了。
例如,merge这样一个数组的左右两个部分:2 3 7 || 1 8 9, 左边会先被迭代光,此时右边还剩8和9,但是位置已然已经正确了;再例如 1 8 9 || 2 3 7 ,这时候就是左边会剩下,需要迭代完。
最后给出merge sort的视频 http://v.youku.com/v_show/id_XMzMyODk5Njg4.html
面试的很少会直接考你排序,一般都是夹在在某些题目里。稍后我会更新一些题目上来。
插入排序的左边是有序的,依次从右边拿出一个数,插入到左边,直到右边没有更多的数,此时左边的数已经全部按序排列。
插入排序的C语言实现
void insertion_sort(int array[], int length){ int i,j; for(i=1;i<length;i++){ for(j=i;j>0;j--){ if(array[j]<array[j-1]){ int temp = array[j]; array[j] = array[j-1]; array[j-1] = temp; }else break; } } }
插入排序的平均时间复杂度是O(N^2),当输入序列已经排好序的情况下,可以达到O(N)。所以当数组已经部分排好序的情况下,插入排序的效率较高。
这里是一个关于插入排序的舞蹈视频:http://t.cn/hros0W 。不管怎么样,视频只能帮助你理解排序的一个总体思路,但是只有切身用代码实现了,才算是真正会了,有时候少一个等号,迭代少了一次,都会导致结果的错误。至于完全理解每个算法的适用场合,还需要在工作中的不断经验积累,以及良好的数学功底。
2 冒泡排序 Bubble Sort
冒泡大概是最好理解的一个排序算法之一了,不过我第一次接触的时候也花了一些时间才明白过来。从名字上来看,冒泡排序就像是水里的泡泡一样,最大的元素不断的浮出水面,排到整个数组的最后。具体的说,第一次迭代,最大的元素会排到数组最后,第二次迭代,次大的元素会排到数组的倒数第二,第三次迭代,第三大的元素会排到数组的倒数第三……以此类推。
冒牌排序的平均时间复杂度是O(N^2),最坏的情况是O(N^2),最优情况O(N)。
冒泡排序的C实现代码:
void bubbleSort(int arr[],int len){ int i,j; int flag; for(i = 0;i < len;i++){ flag = 0; for(j = 0; j < len -i -1; j++){ if(arr[j]>arr[j+1]){ //swap arr[j], arr[j+1]; int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; flag = 1; } } /*if in this loop, flag has never been changed, then the whole array is already sorted*/ if(flag == 0){ break; } } }
冒泡排序的舞蹈视频:http://t.cn/hrf58M
3 快速排序
快速排序如它的名字一样,是速度最快的排序之一。快速排序的平均时间复杂度是O(NlogN),最坏的情况是O(N^2)。
快速排序是一种递归排序算法,首先选择一个pivot轴心元素,让数组中比pivot小的元素排到其左边,比它大的元素排到右边。然后再递归用快速排序整理pivot左边的部分,以及右边的部分。直到整体实现有序。这里使元素分别排到pivot两边的算法叫partition分区算法。最好的pivot选取是选择一个数组的中数median,如果不巧选到了一个数组里的Max or Min,就会导致最坏情况的发生。具体的分析就不在这里说了。如果想知道去看看CLRS算法导论,里面有详细的partition算法,还有关于如何选取一个好的pivot。
快速排序的C语言简单实现:
void quicksort(int array[],int left,int right){ int index = partition(array,left,right); /*recursively sort the left part*/ if(left<index-1){ quicksort(array,left,index-1); } /*recursively sort the right part*/ if(index<right){ quicksort(array,index,right); } } /*return the index of pivot element*/ int partition(int array[],int left,int right){ int pivot = array[(left+right)/2]; while(left<right){ /*find the element that should on right side of pivot*/ while(array[left]<pivot){ left++; } /*find the element that should on left side of pivot*/ while(array[right]>pivot){ right--; } /*swap left and right*/ if(left<=right){ int tmp = array[left]; array[left] = array[right]; array[right] = tmp; left++; right--; } } return left; }
同样在最后给出舞蹈视频:http://t.cn/ScTA1d
4 归并排序 Merge Sort
一直想不通为什么要把Merge翻译成归并…
Merge Sort也用到了递归,更确切的说法是用到了Divide and Conquer的分治思想,分:把一个数组分成2段,先将左边排序,再将右边排序,合:最后融合到一个数组里。
伪代码:
void mergeSort(
left = mergeSort(array, 0, middle);
right = mergeSort(array, middle, end);
merge(left, right);
}
Merge Sort的平均和最坏的时间复杂度都是O(NlogN),至于怎么得出的可以参看算法导论CLRS,简单的说一下:设时间复杂度是T(n),那么从上面伪代码可以推出递归式:T(n) = 2T(n/2) + O(n), 这里的O(n)最后merge过程的时间复杂度,可以求出T(n)是O(NlogN),有个公式的,你也可以推理或者猜一个答案来反证,总之方法很多,如果你本科算法课好好听了应该会有印象。
简单的说一下Merge过程,现在有两个排好了序的数组,然后要融合它们,怎么做?分别从两个数组的头部开始迭代,逐个比较,小的那个拿走,直到迭代完成。
Merge Sort的C语言实现:
void mergeSort(int a[],int start,int end){ if(start<end){ int mid = (start+end)/2; mergeSort(a,start,mid); mergeSort(a,mid+1,end); merge(a,start,mid,end); } } void merge(int a[], int start, int mid, int end){ int i = start; //copy array a into a temporary helper array int helper[end]; while(i<=end){ helper[i] = a[i]; i++; } //start to merge left part and right part int left = start; int right = mid+1; //pointer 'current' is pointing at current index of array 'a' int current = start; while(left <= mid && right <= end){ if(helper[left]<=helper[right]){ a[current] = helper[left]; left++; }else{ a[current] = helper[right]; right++; } current++; } //copy the remaining of left part into array 'a' while(left <= mid){ a[current] = helper[left]; current++; left++; } }
还有一点关于merge过程想说的,上面的最后,只需要copy左半部分剩下的到原数组里,为什么呢?因为右半部分如果有剩下,那么它已经在原数组里正确的位置上了。
例如,merge这样一个数组的左右两个部分:2 3 7 || 1 8 9, 左边会先被迭代光,此时右边还剩8和9,但是位置已然已经正确了;再例如 1 8 9 || 2 3 7 ,这时候就是左边会剩下,需要迭代完。
最后给出merge sort的视频 http://v.youku.com/v_show/id_XMzMyODk5Njg4.html
面试的很少会直接考你排序,一般都是夹在在某些题目里。稍后我会更新一些题目上来。
相关文章推荐
- 两种常用的选择排序算法--简单选择排序、堆排序
- 常用算法之选择排序
- 常用算法Java实现之选择排序
- 算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版
- 常用的数据排序算法图解(冒泡,选择二分...)
- 常用算法之:选择排序(C语言版)
- 常用的选择排序.Shell排序.快速排序.冒泡排序.插入排序的算法
- 常用算法--基本排序算法(冒泡排序,选择排序,插入排序,快速排序,归并排序,桶排序)
- 算法之常用排序:冒泡排序、选择排序、插入排序
- 【Java 常用算法】选择排序
- 常用算法-直接选择排序
- 几种常用的排序算法:插入排序、冒泡排序、选择排序的算法及C++实现
- 常用算法之选择排序
- Java学习资料-Java常用算法-选择排序算法
- 白话经典算法系列之四 直接选择排序及交换二个数据的正确实现
- 算法——排序——选择排序
- Java算法之排序(快速,冒泡,归并,选择)
- 算法复习--------------基本算法:顺序查找,选择排序,冒泡排序算法等简单算法
- 八大种必知排序算法(二) 选择排序,插入排序,希尔算法
- 数据结构与算法:C++实现选择排序