【算法】九大排序算法总结
来源:互联网 发布:金税盘开票软件最新版 编辑:程序博客网 时间:2024/04/25 18:44
数据结构
这里我不采用数组来进行排序,而是采用更加符合应用的数据结构来排序。
#define M 100typedef int datatype;typedef struct node{ datatype r[M+1]; int lengh;}table;
这是一种简单描述,更加详细的数据机构应该是下面这样(但是为了方便描述还是使用上面的简单结构):
#define M 100typedef int datatype;typedef struct { datatype key; //其他数据...}sort_record;typedef struct node{ sort_record r[M+1]; int lengh;}table;
说明:这里不考虑程序的鲁棒性,对于略去了对参数的检查,只为了更加清晰地描述算法,本来想用数组的但是觉得使用结构体更加合乎实际应用逻辑。每种算法都是必须非常熟练的,至于思路就不用说了读代码就行
注意:数组中第一个元素tab[0]都是拿来作为哨兵元素的。
插入排序
1. 直接插入排序
//1.直接插入void direct_insert_sort(table* tab){ int i,j; for (i = 1;i<tab->lengh;i++) { j = i-1; tab->r[0] = tab->r[i]; while(tab->r[0] < tab->r[j]) { tab->r[j+1] = tab->r[j]; j = j-1; } tab->r[j+1] = tab->r[0]; }}
2. 二分插入排序
void binary_insert_sort(table* tab){ int i,j,left,right,mid; for(i =1;i<tab->lengh;i++) { left = 1;right = i-1; tab->r[0] = tab->r[i]; while(left <= right) { mid = (left + right) /2; if (tab->r[mid] > tab->r[0]){ right = mid -1; } else{ left = mid+1; } } for (j=i-1;j>=left;j--) { tab->r[j+1] = tab->r[j]; } tab->r[left] = tab->r[0]; }}
3. 希尔插入排序
void shell_sort(table* tab){ int i,j,gap; gap = tab->lengh / 2; while(gap >= 1) { for (i = 1+gap;i<=tab->lengh;i++) { j = i -gap; tab->r[0] = tab->r[i]; while(tab->r[0] < tab->r[j] && j>0) { tab->r[j+gap] = tab->r[j]; j = j-gap; } tab->r[j +gap] = tab->r[0]; } gap = gap/2; }}
交换排序
4. 冒泡排序
//4.冒泡排序void bubble_sort(table* tab){ int i,j,done; done = 1; for(i = 1;i<= tab->lengh&&done;i++) { done = 0; for (j = 1;j<= tab->lengh - i;j++) { if (tab->r[j] > tab->r[j+1]) { swap(tab->r[j],tab->r[j+1]); done = 1; } } }}
5. 快速排序
//5.快速排序void quick_sort(table* tab,int left,int right){ if (left >= right) return; int i,j; i = left;j = right; tab->r[0] = tab->r[i]; while(i < j) { while(tab->r[i] <= tab->r[j]&&i<j) j--; if (i<j){ tab->r[i] = tab->r[j]; i++; } while(tab->r[j] >= tab->r[i]&&i<j) i++; if (i<j){ tab->r[j] = tab->r[i]; j--; } } tab->r[i] = tab->r[0]; quick_sort(tab,left,i-1); quick_sort(tab,i+1,right);}
选择排序
6. 直接选择排序
//6.直接选择void direct_select_sort(table* tab){ int i,j,k; for (i =1;i<=tab->lengh;i++) { k = i; for(j = i+1;j<=tab->lengh;j++) { if (tab->r[k] > tab->r[j]) k = j; } if (k != i) { swap(tab->r[k],tab->r[i]); } }}
7. 堆排序
//7.堆排序//index表示要调整的节点的下标,n表示堆元素个数。void shift_heap(table* tab,int index,int n){ int i,j,finished = 0; tab->r[0] = tab->r[index]; i = index; j = 2*i; while(j<=n && !finished) { if (tab->r[j] > tab->r[j+1]&&j<=n) j++; if (tab->r[0] <= tab->r[j]) { finished = 1; } else { tab->r[i] = tab->r[j]; i = j; j = 2*i; } } tab->r[i] = tab->r[0];}void heap_sort(table* tab){ int i; for (i = tab->lengh/2;i>=1;i--) { shift_heap(tab,i,tab->lengh); } for (int i = 2;i<tab->lengh;i++) { shift_heap(tab,i,tab->lengh); }}
8. 归并排序
//8.归并排序//将tabs中的u-m-v的元素合并到tabg中void merge(table* tabs,table* tabg,int u,int m,int v){ int i,j,k,t; i = u; j = m +1; k = u; while(i<=m && j <= v) { if (tabs->r[i] < tabs->r[j]) { tabg->r[k++] = tabs->r[i]; i++; } else { tabg->r[k++] = tabs->r[j]; j++; } } if (i<=m) { for(t = i;t<=m;t++) tabg->r[k++] = tabs->r[t]; } else { for(t = i;t<=v;t++) tabg->r[k++] = tabs->r[t]; }}//递归实现void merge_sort1(table* tabs,table* tabg,int left,int right){ if (left>= right) { return; } int mid = (left+right)/2; merge_sort1(tabs,tabg,left,mid); merge_sort1(tabs,tabg,mid+1,right); merge(tabs,tabg,left,mid,right);}//非递归实现void merge_pass(table* tabs,table* tabg,int len){ int i,j,n; tabg->lengh = n = tabs->lengh; for(i =1;i<n-2*len+1;i+=2*len) { merge(tabs,tabg,i,i+len-1,i+2*len-1); } if (i+len-1<n){ merge(tabs,tabg,i,i+len-1,n); } else{ for(j=i;j<=n;j++){ tabg->r[j] = tabs->r[j]; } }}void merge_sort(table* tab){ int len; table tmp; len =1; while(len<tab->lengh) { merge_pass(tab,&tmp,len); len = 2*len; merge_pass(&tmp,tab,len); len = 2*len; }}
9. 桶排序
桶排序(Bucket Sort)的原理很简单,它是将数组分到有限数量的桶子里。
假设待排序的数组a中共有N个整数,并且已知数组a中数据的范围[0, MAX)。在桶排序时,创建容量为MAX的桶数组r,并将桶数组元素都初始化为0;将容量为MAX的桶数组中的每一个单元都看作一个”桶”。
在排序时,逐个遍历数组a,将数组a的值,作为”桶数组r”的下标。当a中数据被读取时,就将桶的值加1。例如,读取到数组a[3]=5,则将r[5]的值+1。
桶排序不能应用于排序数很大的情况,因为这样会需要一个很大很大桶,显然是科学的。
桶排序是稳定的,最好的时间复杂度达到O(N)
/** 桶排序* tab -- 排序结构* max --待排序结构中最大范围[0,max)*/void bucket_sort(table* tab,int max){ int i,j; int* bucket; if (tab == NULL || tab->lengh > max || max < 1) return; if ((bucket = (int*)malloc(sizeof(int)*max)) == NULL) return; memset(bucket,0,max*sizeof(int)); //1.计数 for (i = 1;i<tab->lengh;i++) { bucket[tab->r[i]]++; } //2.排序 for(i = 1,j = 1;i < max;i++) { while(bucket[i]-- != 0) tab->r[j++] = i; } free(bucket);}
基数排序
基数排序比较麻烦,自我认为找工作,面试笔试都不会考到,理解基本思路即可。
实现思路:
最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。
最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。
- 【排序算法】:九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 九大排序算法总结
- 【算法】九大排序算法总结
- 九大排序算法再总结
- 九大排序算法再总结
- POJ 1860 Currency Exchange
- Python使用C语言生成的库
- CocoaPods升级
- springboot 试用笔记
- hdu 5001 Walk(概率dp+搜索,矩阵快速幂)
- 【算法】九大排序算法总结
- 数组中未出现的最小正整数
- MATLAB中cell函数
- STC单片机使用RS485下载程序方法
- android存储方式之文件存储
- 面试编程加数据库
- Runtime.getRuntime().exec()进程阻塞问题
- Android button按键点击无反应
- github-july-最长回文子串