排序算法
来源:互联网 发布:怪物猎人初音捏脸数据 编辑:程序博客网 时间:2024/04/30 05:08
衡量排序算法的优劣:
1.时间复杂度:分析关键字的比较次数和记录的移动次数
2.空间复杂度:分析排序算法中需要多少辅助内存
3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。
常用的内部排序
1.选择排序:直接选择排序、堆排序
直接选择排序:第一次找出最小的元素放到第一个位置处,第二次找第二小的元素放到第二个位置,以此类推。
代码如下:
自定义类:
package com.v512.order;public class DataWrap implements Comparable<DataWrap>{ int data; String flag; public DataWrap(int data,String flag){ this.data = data; this.flag = flag; } public String toString(){ return data + flag; } //根据data实例变量来决定两个dataWrap的大小 @Override public int compareTo(DataWrap dw) { return this.data > dw.data? 1 : (this.data == dw.data? 0 : -1); }}
主函数:
package com.v512.order;/** * 直接选择排序 * @author shkstart * 2013-11-27 */public class SelectSort { public static void selectSort(DataWrap[] data) { System.out.println("开始排序"); int arrayLength = data.length; for (int i = 0; i < arrayLength - 1; i++) { for (int j = i + 1; j < arrayLength; j++) { if (data[i].compareTo(data[j]) > 0) { DataWrap temp = data[i]; data[i] = data[j]; data[j] = temp; } } System.out.println(java.util.Arrays.toString(data)); } } public static void main(String[] args) { DataWrap[] data = { new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(-30, ""), new DataWrap(-49, ""), new DataWrap(21, ""), new DataWrap(30, "*"), new DataWrap(30, "") }; System.out.println("排序之前:\n" + java.util.Arrays.toString(data)); selectSort(data); System.out.println("排序之后:\n" + java.util.Arrays.toString(data)); }}
运行结果:
排序之前:
[9, -16, 21*, 23, -30, -49, 21, 30*, 30]
开始排序
[-49, 9, 21*, 23, -16, -30, 21, 30*, 30]
[-49, -30, 21*, 23, 9, -16, 21, 30*, 30]
[-49, -30, -16, 23, 21*, 9, 21, 30*, 30]
[-49, -30, -16, 9, 23, 21*, 21, 30*, 30]
[-49, -30, -16, 9, 21*, 23, 21, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
排序之后:
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
堆排序
暂未写
2.交换排序:冒泡排序、快速排序
冒泡排序:
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。(DataWrap类前面已给出)
package com.v512.order;/** * 冒泡排序 * @author shkstart * 2013-11-27 */public class BubbleSort { public static void bubbleSort(DataWrap[] data) { System.out.println("开始排序"); int arrayLength = data.length; for (int i = 0; i < arrayLength - 1; i++) { boolean flag = false; for (int j = 0; j < arrayLength - 1 - i; j++) { if (data[j].compareTo(data[j + 1]) > 0) { DataWrap temp = data[j + 1]; data[j + 1] = data[j]; data[j] = temp; flag = true; } } System.out.println(java.util.Arrays.toString(data)); if (!flag) break; } } public static void main(String[] args) { DataWrap[] data = { new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(-30, ""), new DataWrap(-49, ""), new DataWrap(21, ""), new DataWrap(30, "*"), new DataWrap(30, "")}; System.out.println("排序之前:\n" + java.util.Arrays.toString(data)); bubbleSort(data); System.out.println("排序之后:\n" + java.util.Arrays.toString(data)); }}
运行结果:
排序之前:
[9, -16, 21*, 23, -30, -49, 21, 30*, 30]
开始排序
[-16, 9, 21*, -30, -49, 21, 23, 30*, 30]
[-16, 9, -30, -49, 21*, 21, 23, 30*, 30]
[-16, -30, -49, 9, 21*, 21, 23, 30*, 30]
[-30, -49, -16, 9, 21*, 21, 23, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
排序之后:
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列(DataWrap类前面已给出)。
package com.v512.order;/** * 快速排序 * @author shkstart * 2013-11-27 */public class QuickSort { private static void swap(DataWrap[] data, int i, int j) { DataWrap temp = data[i]; data[i] = data[j]; data[j] = temp; } private static void subSort(DataWrap[] data, int start, int end) { if (start < end) { DataWrap base = data[start]; int i = start; int j = end + 1; while (true) { while (i < end && data[++i].compareTo(base) <= 0) ; while (j > start && data[--j].compareTo(base) >= 0) ; if (i < j) { swap(data, i, j); } else { break; } } swap(data, start, j); subSort(data, start, j - 1); subSort(data, j + 1, end); } } public static void quickSort(DataWrap[] data){ subSort(data,0,data.length-1); } public static void main(String[] args) { DataWrap[] data = { new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(-30, ""), new DataWrap(-49, ""), new DataWrap(21, ""), new DataWrap(30, "*"), new DataWrap(30, "") }; System.out.println("排序之前:\n" + java.util.Arrays.toString(data)); quickSort(data); System.out.println("排序之后:\n" + java.util.Arrays.toString(data)); }}
3.插入排序:直接插入排序、折半插入排序、Shell排序
直接插入排序:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。
折半插入排序
折半插入排序是对直接插入排序的简单改进。
此处介绍的折半插入,其实就是通过不断地折半来快速确定第i个元素的插入位置,这实际上是一种查找算法:折半查找。Java的Arrays类里的binarySearch()方法,就是折半查找的实现,用于从指定数组中查找指定元素,前提是该数组已经处于有序状态。
与直接插入排序的效果相同,只是更快了一些,因为折半插入排序可以更快地确定第i个元素的插入位置。
代码:`package com.v512.order;
/**
* 折半插入排序
* @author shkstart
* 2013-11-27
*/
public class BinaryInsertSort {
public static void binaryInsertSort(DataWrap[] data) {
System.out.println(“开始排序”);
int arrayLength = data.length;
for (int i = 1; i < arrayLength; i++) {
DataWrap temp = data[i];
int low = 0;
int high = i - 1;
while (low <= high) {
int mid = (low + high) / 2;//mid为已排序数组的中间元素
if (temp.compareTo(data[mid]) > 0) {
low = mid + 1;
} else {
high = mid - 1;
}
}
for (int j = i; j > low; j–) {
data[j] = data[j - 1];
}
data[low] = temp;
System.out.println(java.util.Arrays.toString(data));
}
}public static void main(String[] args) { DataWrap[] data = { new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(-30, ""), new DataWrap(-49, ""), new DataWrap(21, ""), new DataWrap(30, "*"), new DataWrap(30, "")}; System.out.println("排序之前:\n" + java.util.Arrays.toString(data)); binaryInsertSort(data); System.out.println("排序之后:\n" + java.util.Arrays.toString(data));}
}
`
运行结果:
排序之前:
[9, -16, 21*, 23, -30, -49, 21, 30*, 30]
开始排序
[-16, 9, 21*, 23, -30, -49, 21, 30*, 30]
[-16, 9, 21*, 23, -30, -49, 21, 30*, 30]
[-16, 9, 21*, 23, -30, -49, 21, 30*, 30]
[-30, -16, 9, 21*, 23, -49, 21, 30*, 30]
[-49, -30, -16, 9, 21*, 23, 21, 30*, 30]
[-49, -30, -16, 9, 21, 21*, 23, 30*, 30]
[-49, -30, -16, 9, 21, 21*, 23, 30*, 30]
[-49, -30, -16, 9, 21, 21*, 23, 30, 30*]
排序之后:
[-49, -30, -16, 9, 21, 21*, 23, 30, 30*]
shell排序
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
代码:
package com.v512.order;/** * Shell排序 * @author shkstart * 2013-11-27 */public class ShellSort { public static void ShellSort(DataWrap[] data) { System.out.println("开始排序"); int arrayLength = data.length; int h = 1; while (h <= arrayLength / 3) { h = h * 3 + 1; } while (h > 0) { System.out.println("===h的值:" + h + "==="); for (int i = h; i < arrayLength; i++) { DataWrap temp = data[i]; if (data[i].compareTo(data[i - h]) < 0) { int j = i - h; for (; j >= 0 && data[j].compareTo(temp) > 0; j -= h) { data[j + h] = data[j]; } data[j + h] = temp; } System.out.println(java.util.Arrays.toString(data)); } h = (h - 1) / 3; } } public static void main(String[] args) { DataWrap[] data = { new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(-30, ""), new DataWrap(-49, ""), new DataWrap(21, ""), new DataWrap(30, "*"), new DataWrap(30, "")}; System.out.println("排序之前:\n" + java.util.Arrays.toString(data)); ShellSort(data); System.out.println("排序之后:\n" + java.util.Arrays.toString(data)); }}
运行结果:
排序之前:
[9, -16, 21*, 23, -30, -49, 21, 30*, 30]
开始排序
===h的值:4===
[-30, -16, 21*, 23, 9, -49, 21, 30*, 30]
[-30, -49, 21*, 23, 9, -16, 21, 30*, 30]
[-30, -49, 21*, 23, 9, -16, 21, 30*, 30]
[-30, -49, 21*, 23, 9, -16, 21, 30*, 30]
[-30, -49, 21*, 23, 9, -16, 21, 30*, 30]
===h的值:1===
[-49, -30, 21*, 23, 9, -16, 21, 30*, 30]
[-49, -30, 21*, 23, 9, -16, 21, 30*, 30]
[-49, -30, 21*, 23, 9, -16, 21, 30*, 30]
[-49, -30, 9, 21*, 23, -16, 21, 30*, 30]
[-49, -30, -16, 9, 21*, 23, 21, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
排序之后:
[-49, -30, -16, 9, 21*, 21, 23, 30*, 30]
4.归并排序
代码:
归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
package com.v512.order;/** * 归并排序 * * @author shkstart * 2013-11-27 */public class MergeSort { public static void mergeSort(DataWrap[] data) { // 归并排序 sort(data, 0, data.length - 1); } // 将索引从left到right范围的数组元素进行归并排序 private static void sort(DataWrap[] data, int left, int right) { if(left < right){ //找出中间索引 int center = (left + right)/2; sort(data,left,center); sort(data,center+1,right); //合并 merge(data,left,center,right); } } // 将两个数组进行归并,归并前两个数组已经有序,归并后依然有序 private static void merge(DataWrap[] data, int left, int center, int right) { DataWrap[] tempArr = new DataWrap[data.length]; int mid = center + 1; int third = left; int temp = left; while (left <= center && mid <= right) { if (data[left].compareTo(data[mid]) <= 0) { tempArr[third++] = data[left++]; } else { tempArr[third++] = data[mid++]; } } while (mid <= right) { tempArr[third++] = data[mid++]; } while (left <= center) { tempArr[third++] = data[left++]; } while (temp <= right) { data[temp] = tempArr[temp++]; } } public static void main(String[] args) { DataWrap[] data = { new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(-30, ""), new DataWrap(-49, ""), new DataWrap(21, ""), new DataWrap(30, "*"), new DataWrap(30, "") }; System.out.println("排序之前:\n" + java.util.Arrays.toString(data)); mergeSort(data); System.out.println("排序之后:\n" + java.util.Arrays.toString(data)); }}
今天先写到这,明天补完!(文中代码有些引自尚硅谷,在此致谢!)
5.桶式排序
6.基数排序
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 欢迎使用CSDN-markdown编辑器
- 每天一个 Linux 命令(21):find命令之xargs
- 设计模式的六大原则
- RequestSync分析
- 杨辉三角 C语言代码
- 排序算法
- 前置++和后置++不同的本质分析
- mac sumblime text3插件Emmet一直提示loading pyv8
- GBDT(MART) 迭代决策树入门教程 | 简介
- Tensorflow实战——利用Softmax Regression识别手写数字
- UNIX 进程揭秘--进程的生命周期
- 队列
- cf246c
- C++动态内存管理