排序算法整理
来源:互联网 发布:知乎注册要用手机 编辑:程序博客网 时间:2024/05/19 02:24
为准备面试将几个排序算法写了一下,熟悉熟悉,到时也不至于手生。
一 ﹑冒泡法
最简单的冒泡法,时间复杂度O(n)。
int bubble_sort( int a[] , int n ){ int i , j ; for ( i = 1 ; i <= n ; i ++ ) // 多少趟 { for ( j = 0 ; j <= n - i ; j ++ ) { if ( a[i] > a[j+1] ) { swap(&a[i],&a[j]); // 交换 } } }}
总结:
冒泡法,算法简单,易于实现,且整个过程可以很形象地关键字如泡泡一样上升。
二﹑选择排序
int select_sort( int a[] , int n ){ int i , j , k ; for ( i =1 ; i <= n ; i ++ ) { k = 0 ; for ( j = 1 ; j <= n - i ; j ++ ) { if ( a[j] > a[k] ) { k = j ; } } swap(&a[k],&a[n-i]); }}
总结:
选择排序对冒泡法的交换进行改进。
三﹑快速排序
int qsort( int a[] , int low, int high ){ if ( low == high ) { return 0 ; } int i = partion(a,low,high); qsort(a,low,i-1); qsort(q,i+1,high);}
partion算法1:
int partion( int a[] , int low , int high ){ int x = a[low] ; while( low < high ) { for ( ; low < high && a[high] >= x ; ) high-- ; swap(&a[high],&a[low]); for ( ; low < high && a[low] <= x ; ) low++ ; swap(&a[low],&a[high]); } return low ;}
partion算法2:
int partion( int a[] , int low , int high ){ int x = a[low] ; while( low < high ) { for ( ; low < high && a[high] >= x ; ) high-- ; a[low] = a[high] ; for ( l low < high && a[low] <= x ; ) low++; a[high] = a[low] ; } a[low] = x ;}
总结:
快排的平均性能O(nlgn) , 这是每次将它分为两个均等的区间即T(n)=2T(n/2)。但是若本来有序的情况下,则是T(n)=T(1)+T(n-1),可以看到退化为冒泡法啦。当然这里可以利用随机选取避免的。 快速排序的示例:这里使用3.14159来排序,呵呵,这个比较有意义。将本来没有意思的东西变得有意思这是某某的职责。当时,我感觉这个partion这个过程,就好像是将
枢纽像抛皮球一样从左抛到右,又从右抛到左。
四﹑堆排序
堆排序与元素的初始序列无关,在最坏的情况下也是O(lgn),这个优点也是快速排序不能比拟的。堆排序的思想:建一个初始堆,然后交换堆顶元素和序列最末尾的一个元素,然后将该元素筛下去。
初始序列: 49 38 65 97 76 13 27 49~
图一 筛选97
图二 筛选65
图三 筛选38
图四 筛选49
至此完成初始堆的建立,交换13和97,然后又是重复调用该过程即可。如下图所示:
然后序列为 97 27 38 49~ 76 65 49重复执行上述过程即可。
附上源代码:
#include<stdio.h>void swap( int &a , int &b ){ int tmp ;tmp = a ;a = b ;b = tmp ;}void heapadjust( int a[] , int s , int m ){ int j ; for ( j = 2*s ; j <= m ; j *=2 ) //若下标从0开始 heapadjust(a,0,0) 那么这里是一个死循环 :( { if ( j<m && a[j+1] < a[j] ) { j++ ; } if( a[j] < a[s] ) { swap(a[s],a[j]); } else { break ; } s = j ; }}void heapsort( int a[] , int n ){ int i ; for ( i = n/2 ; i >= 1 ; i-- ) { heapadjust(a,i,n); } for ( i = n ; i >= 1 ; i-- ) { swap(a[1],a[i] ); heapadjust(a,1,i-1); }}int main(){int i , n ;int c[] = { 0,49 , 38 , 65 , 97 , 13 , 27 , 49 } ; //这里下标从1开始好n = sizeof(c)/sizeof(int) ;heapsort(c,n);for ( i = 1 ; i < n ; i++ ){ printf("\t%d",c[i] );}printf("\n"); #ifdef __cplusplus printf("c++\n"); //查看是c++编译器么 #endifreturn 0 ;}
五﹑基数排序
传说中O(n+rd)的排序算法,前面的几种都是比较和移动的算法,而 基数排序借助多关键字的思想(摸扑克牌),进行r次分配和收集。
#include<stdio.h>#include<assert.h>//算法仅考虑正数的情况 对于有负数的情况要先将负数打出来 然后额外排序//可以将正数看成是字符串的形式#define MAX_SPACE 1000#define RADIX 10typedef struct { int key ; int next ;}SLCell;typedef struct { SLCell r[MAX_SPACE]; int keynum ; int recnum ;}SLList;typedef int ArrType[RADIX];ArrType front , end ;//计算出第i位的数int ord( int n , int i ){ int r ; assert(i!=0); //要经常使用断言 使程序更加稳定 r = ( n %(i*10) )/i ; return r ;}//静态表中已按前i-1个关键字排好 下面排i个关键字 void Distribute( SLCell *r , int i , ArrType &f , ArrType &e ){ int j , p ;// 队首置空for ( j = 0 ; j < RADIX ; j ++ ){ f[j] = 0 ;}for ( p = r[0].next ; p ; p=r[p].next ){ j = ord(r[p].key , i*10) ; if ( !f[j] ) //插入静态链表中 { f[j] = p ; } else { r[e[j]].next = p ; } e[j] = p ;}}//这里传来i其实没用 主要是在Radixsort函数调用看起来美观void Collect(SLCell *r , int i , ArrType &f , ArrType &e ){int j , t ; for ( j = 0 ; j < RADIX && !f[j] ; j++ ); r[0].next = j ; t = e[j] ; while ( j < RADIX ) { for (j++ ; !f[j] && j < RADIX ; j++) ; //找到下一个不为空队首 if ( f[j] ) { r[t].next = f[j] ; t = e[j] ; } } r[t].next = 0 ;}void Radixsort( SLList &L ){ int i ; for( i = 0 ; i < L.recnum ; i++ ) { L.r[i].next = i+ 1 ; } L.r[L.recnum].next = 0 ; for ( i = 1 ; i <= L.keynum ; i++ ) //按关关键字从小到大分配 收集 { Distribute(L.r,i,front,end); Collect(L.r,i,front,end); }}int main(){int n , i ;int a[] = { 0,8, 9 , 10 , 12 , 15 ,16,100, 102,115} ;n = sizeof(a) / sizeof(int) -1 ;SLList list ;for ( i = 1 ; i <= n ; i ++ ){ list.r[i].key = a[i] ;}list.recnum = n ;list.keynum = 3 ;Radixsort(list);for ( i = 1; i <=n ; i++ ){ printf("\t%d",list.r[i]);}printf("\n");return 0 ;}
- 排序算法整理
- 排序算法整理
- 排序算法整理
- 整理几个排序算法
- 排序算法整理
- 排序算法整理
- java排序算法整理
- 外部排序算法整理
- 各种排序算法整理
- 排序算法整理
- 常见排序算法整理
- 排序算法 整理
- 常用排序算法整理
- 排序算法收集整理
- 排序算法-整理归档
- 排序算法整理
- Java:排序算法整理
- 排序算法整理
- actioncolumn里面设置操作列显示和隐藏
- 快速幂模板(整数+矩阵)
- 搭建 Http Dynamic Streaming 点播/直播服务器
- HTML页和ashx页之间的关联
- 修改代码实现常见视频的自动播放
- 排序算法整理
- Linux时间子系统之三:时间的维护者:timekeeper
- 晶体管参数在实际使用中的意义
- 面试题整理(三)
- 用 Windows server 2003 组策略部署 Windows 防火墙
- 编程之美之 饮料供货 之 动态规划算法和备忘录算法实现
- python中read() readline()以及readlines()用法
- Xcode调试 之 内存泄露
- 路径与属性