数据结构之排序
来源:互联网 发布:c语言华氏度转摄氏度 编辑:程序博客网 时间:2024/05/12 10:44
排序算法总结:
逐个分析排序算法:
1.插入类排序:像打扑克一样,第一张牌不用整理,从第二张开始将牌和之前的所有牌比较并插入到正确位置上。算法为:
★查找待插入元素的插入位置
★此位置之后的所有元素后移一位
★插入即可
(1)直接插入排序:
设一个监视哨r[0],用来存放待插记录,从第二个元素开始,和已经排好序的数列从后向前比较,直到找到大于待插记录停止,将比较过的数列整体后移,然后插入。
//此方法最坏时间复杂度为o(n*n),因为比较一趟,移动一趟;空间复杂度为o(1),因为只占用了一个监视哨;此方法是稳定的
public class test1 { public static void main(String[] args) { int i, j; int r[] = { 0, 0, 1, 9, 5, 15, 3, -5 };// 注意,第一个0是监视哨,占位置而已 for (i = 2; i < r.length; i++) {//不是<=,因为0号位置没有用到 r[0] = r[i]; if (r[i] < r[i - 1]) {//当待排元素小于前一个元素时,才比较,否则不用比较。 for (j = i - 1; r[j] > r[0]; j--) {//注意判断条件是大于 r[j + 1] = r[j];//后移序列 r[j] = r[0];//插入操作 } } else { continue; }} for (i = 1; i < r.length; i++) { System.out.println(r[i]); }}}
(2)折半插入排序
同样设一个监视哨来存放当前待排元素,设置两个指针low和high,用中间值mid来和待排元素比较
//时间复杂度:移动加比较,仍为o(n*n),空间复杂度仍为O(1).且是稳定的。
public class test1 { public static void main(String[] args) { int i, j; int low, high, mid; int a[] = { 0, 0, -4, 25, 17, 1, -1, 5, 80 }; for (i = 2; i < a.length; i++) { a[0] = a[i]; if (a[i] < a[i - 1]) { low = 1; high = i - 1; while (low <= high) { mid = (low + high) / 2; if (a[mid] < a[0]) { low = mid + 1; } else { high = mid - 1; }} for (j = i - 1; j >= low; j--) { a[j + 1] = a[j]; a[j] = a[0]; }} else { continue;}} for (i = 1; i < a.length; i++) { System.out.print(a[i]); System.out.print(" "); }}}
(3)希尔排序:
2.交换类排序:对待排序的关键字两两进行比较,只要发现为逆序就进行交换,知道没有逆序的记录为止。
(1)冒泡排序:依次比较相邻两个关键字的大小,逆序则交换,最终每比较一趟,最大或者最小的数字沉到底。可以设置一个标志位flag,用来跟踪判断序列是否已完成排序。
时间复杂度:最优情况下,序列已有序,时间复杂度为o(n),最坏情况下,序列完全是乱的,则需要o(n*n)的时间复杂度。
是一种稳定的算法且空间复杂度为o(1).
//注意设置标志位a[0],用来实现交换过程。
public class test1 { public static void main(String[] args) { int i, j; int a[] = {0, 46, 25, 68, 33, 33, 19, 12, 80}; System.out.println(a.length) for(j=1; j < a.length-1 ;j++) {//外层循环,循环次数不变 for(i=1; i < a.length-j; i++) {//内层循环比较然后交换,循环次数依次减少 if(a[i] > a[i+1]) { a[0] = a[i]; a[i] = a[i+1]; a[i+1] = a[0]; }}} for(i=1; i < a.length; i++) { System.out.print(a[i]+" "); }}}
(2)快速排序:几乎是最快的排序方法,采用分治的思想。
分治思想:将原问题分解为若干个规模更小但结构和原问题相似的子问题,递归的解这些子问题,然后将这些子问题的解组合为原问题的解
快排的思想:选择一个枢轴,设置high和low.两头同步开始交替比较,关键字小于枢轴的均移到枢轴之前,关键字大于枢轴的均移到枢轴之后。
public class test2 { static void quicksort(int n[], int low, int high) { if (low < high) { int dp = partition(n, low, high); quicksort(n, low, dp - 1); quicksort(n, dp + 1, high);}}//递归的过程 static int partition(int n[], int low, int high) {//一趟比较的过程 int pivot = n[low]; while (low < high) { while (low < high && n[high] >= pivot) high--; if (low < high) n[low++] = n[high]; while (low < high && n[low] <= pivot) low++; if (low < high) n[high--] = n[low]; } n[low] = pivot; return low; } public static void main(String[] str) {//主函数负责初始化和显示 int n[] = { 0, -1, 53, 1, 36, 84, 19, 93, 113, 45, 23 }; quicksort(n, 1, 10); for (int i = 1; i < 10; i++) System.out.print(n[i] + " ");}}
3.选择类排序:基本思想:k初始值为i=1的值,从所有剩下的记录中按顺序寻找小于关键字的记录,找到后将其位置赋给k,比较i和k的值是否相等,不相等则交换即可。
(1)简单选择:时间复杂度为o(n*n),空间复杂度为o(1),排序方式不稳定
public class test1 { static void sort(int a[]) { for (int i = 0; i <= a.length - 1; i++) { int k = i; for (int j = i + 1; j <= a.length - 1; j++) { if (a[j] < a[k]) k = j;} if (k != i) { int t = a[i]; a[i] = a[k]; a[k] = t; }}} public static void main(String[] args) { int a[] = { 1, -1, 3, 14, 0 }; sort(a); for (int i = 0; i <= a.length - 1; i++) { System.out.println(a[i] + " "); }}}
- 《数据结构--排序》之插入排序
- 《数据结构--排序》之快速排序
- 《数据结构--排序》之选择排序
- 《数据结构--排序》之归并排序
- 数据结构排序之堆排序
- 数据结构之排序--归并排序
- 数据结构排序之冒泡排序
- 数据结构排序之快速排序
- 数据结构排序之快速排序
- 数据结构排序之桶排序
- 数据结构--排序之插入排序
- 数据结构--排序之希尔排序
- 数据结构--排序之堆排序
- 数据结构排序之快速排序
- 数据结构排序之冒泡排序
- 数据结构排序之选择排序
- 数据结构排序之插入排序
- 数据结构之排序:希尔排序
- App的动态加载和插件化,文件,其他( 安全问题)
- 如何设置Android Studio左边项目栏的字体大小?
- LeetCode 27 Remove Element
- android基础---->传感器的使用
- Uva10340
- 数据结构之排序
- javascript Array 的增 删 找 的简单例子
- 【USACO题库】1.5.2 Prime Palindromes回文质数(模拟,打表)
- A. Infinite Sequence
- 3月23日 雨
- html5中meta属性使用总结
- Toast 位置的改变 和 Toast的简单用法
- Octotree Chrome插件离线安装
- 手机卫士1