几种经典排序算法
2013-07-30 21:16
176 查看
为了对以下各个算法进行方便的测试,我首先写好了测试主方法体。如下(java实现):
1、冒泡排序(Bubble Sort)时间复杂度:O(n平方)
可以说是最简单的排序方法。这种方法的基本思想是,将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮。在冒泡排序算法中我们要对这个“气泡”序列处理若干遍。所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。如果发现两个相邻元素的顺序不对,即“轻”的元素在下面,就交换它们的位置。显然,处理一遍之后,“最轻”的元素就浮到了最高位置;处理二遍之后,“次轻”的元素就浮到了次高位置。在作第二遍处理时,由于最高位置上的元素已是“最轻”元素,所以不必检查。一般地,第i遍处理时,不必检查第i高位置以上的元素,因为经过前面i-1遍的处理,它们已正确地排好序。算法示例实现如下(java实现):
2、选择排序(Selection Sort)时间复杂度:O(n平方)
选择排序的基本思想是,经过n-i遍历,第一次遍历,选出最小/最大的元素,与排在第一位的元素交换位置;第二次遍历选出第二小/第二大的元素,与第二个元素交换位置;依次类推。算法示例实现如下(java实现):
3、插入排序(Insertion Sort)[b]时间复杂度:O(n平方)[/b]
插入排序基本思想:经过i-1遍处理后,前i-1项己排好序。第i遍处理将第i项插入前i-1项的适当位置,既找到相邻的两个元素x和y,使得input[x]≤input[i]≤input[y],将第i项插入此位置,使得前i项又是排好序的序列。我们可以用顺序比较的方法。首先比较input[i]和input[i-1],如果input[i-1]≤input[i],则[1..i]已排好序,第i遍处理就结束了;否则交换input[i]与input[i-1]的位置,继续比较input[i-1]和input[i-2],直到找到某一个位置j(1≤j≤i-1),使得input[j] ≤input[j+1]时为止。算法示例实现如下(java实现):
4、快速排序(Quick Sort)[b]时间复杂度:O(nlgn)[/b]
快速排序基本思想:用数组的首元素作为标准将A划分成前、后两部分,比首元素小的构成前部分,比首元素大的构成后部分,这两部分构成两个新的子问题。通过递归的方式,算法分别对这两个子问题进行排序。算法示例实现如下(java实现):
5、二分归并排序(Merge Sort)[b]时间复杂度:O(nlgn)[/b]
二分归并排序基本思想:使用了分治策略。将源数组从中间平分为前后两部分,分别对前后两部分进行排序,排序好的前后两部分数据再归并成源数组。当然对于前后两部分的排序也是使用二分归并排序,这是一个递归的过程。算法示例实现如下(java实现):
6、堆排序(Heap Sort)[b]时间复杂度:O(nlgn)[/b]
堆排序基本思想:首先说一下什么是堆,堆其实是一棵完全二叉树,不过它需要满足堆的性质---父节点大于等于子节点(大顶堆),或者父节点小于等于子节点(小顶堆)。堆排序前首先要构造堆,即要将输入的数组调整成堆(大顶堆为例);然后进行排序,最大堆只能保证首元素是当前堆中最大的元素,我们可以把首元素与堆的最后一个元素互换,这样首元素就排在了最后一个位置,也是正确的位置。然后将堆的前n-1个元素进行排序。互换到首元素位置的元素可能会破坏最大堆的性质,我们调整它使之重新成为最大堆,然后将首元素交换至当前堆的最后一个位置。依次递归。算法示例实现如下(java实现):
public class Sort { public static void main(String[] args) { int[] input = { 10, 5, 3, 1, 2 }; //此处调用方法,以调用冒泡排序为例 bubbleSort(input); for (int i = 0; i < input.length; i++) { System.out.println(input[i]); } } }
1、冒泡排序(Bubble Sort)时间复杂度:O(n平方)
可以说是最简单的排序方法。这种方法的基本思想是,将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮。在冒泡排序算法中我们要对这个“气泡”序列处理若干遍。所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。如果发现两个相邻元素的顺序不对,即“轻”的元素在下面,就交换它们的位置。显然,处理一遍之后,“最轻”的元素就浮到了最高位置;处理二遍之后,“次轻”的元素就浮到了次高位置。在作第二遍处理时,由于最高位置上的元素已是“最轻”元素,所以不必检查。一般地,第i遍处理时,不必检查第i高位置以上的元素,因为经过前面i-1遍的处理,它们已正确地排好序。算法示例实现如下(java实现):
public static void bubbleSort(int[] input) { for (int i = 0; i < input.length; i++) { for (int j = 0; j < input.length - i - 1; j++) { if (input[j] > input[j + 1]) { int temp = input[j]; input[j] = input[j + 1]; input[j + 1] = temp; } } } }
2、选择排序(Selection Sort)时间复杂度:O(n平方)
选择排序的基本思想是,经过n-i遍历,第一次遍历,选出最小/最大的元素,与排在第一位的元素交换位置;第二次遍历选出第二小/第二大的元素,与第二个元素交换位置;依次类推。算法示例实现如下(java实现):
public static void selectionSort(int[] input) { for (int i = 0; i < input.length; i++) { int minIndex = i; for (int j = i; j < input.length - 1; j++) { if (input[minIndex] > input[j + 1]) minIndex = j + 1; } if (minIndex != i) { int temp = input[i]; input[i] = input[minIndex]; input[minIndex] = temp; } } }
3、插入排序(Insertion Sort)[b]时间复杂度:O(n平方)[/b]
插入排序基本思想:经过i-1遍处理后,前i-1项己排好序。第i遍处理将第i项插入前i-1项的适当位置,既找到相邻的两个元素x和y,使得input[x]≤input[i]≤input[y],将第i项插入此位置,使得前i项又是排好序的序列。我们可以用顺序比较的方法。首先比较input[i]和input[i-1],如果input[i-1]≤input[i],则[1..i]已排好序,第i遍处理就结束了;否则交换input[i]与input[i-1]的位置,继续比较input[i-1]和input[i-2],直到找到某一个位置j(1≤j≤i-1),使得input[j] ≤input[j+1]时为止。算法示例实现如下(java实现):
public static void insertionSort(int[] input){ for (int i = 1; i < input.length; i++) { for (int j = i; j >0; j--) { if (input[j] < input[j-1]) { int temp = input[j]; input[j] = input[j-1]; input[j-1] = temp; } else break; } } }
4、快速排序(Quick Sort)[b]时间复杂度:O(nlgn)[/b]
快速排序基本思想:用数组的首元素作为标准将A划分成前、后两部分,比首元素小的构成前部分,比首元素大的构成后部分,这两部分构成两个新的子问题。通过递归的方式,算法分别对这两个子问题进行排序。算法示例实现如下(java实现):
public static void quickSort(int[] input, int start, int end) { int i, j, temp; if (start < end) { i = start; j = end; temp = input[start]; while (i < j) { while (i < j && input[j] >= temp) j--; while (i < j && input[i] <= temp) i++; int exchange = input[j]; input[j] = input[i]; input[i] = exchange; } input[start] = input[j]; input[j] = temp; quickSort(input, start, j - 1); quickSort(input, j + 1, end); } }
5、二分归并排序(Merge Sort)[b]时间复杂度:O(nlgn)[/b]
二分归并排序基本思想:使用了分治策略。将源数组从中间平分为前后两部分,分别对前后两部分进行排序,排序好的前后两部分数据再归并成源数组。当然对于前后两部分的排序也是使用二分归并排序,这是一个递归的过程。算法示例实现如下(java实现):
public static void mergeSort(int[] input, int start, int end) { int middle; if (start < end) { middle = (start + end) / 2; mergeSort(input, start, middle); mergeSort(input, middle + 1, end); merge(input, start, middle, end); } } public static void merge(int[] input, int start, int middle, int end) { int[] temp = new int[end - start + 1]; int i = start, j = middle + 1, n = 0; while (i <= middle && j <= end) { if (input[i] < input[j]) { temp = input[i]; i++; } else { temp = input[j]; j++; } n++; } while (i <= middle) { temp = input[i]; i++; n++; } while (j <= end) { temp = input[j]; j++; n++; } for (int x = 0, y = start; x <= n && y <= end; x++, y++) input[y] = temp[x]; }
6、堆排序(Heap Sort)[b]时间复杂度:O(nlgn)[/b]
堆排序基本思想:首先说一下什么是堆,堆其实是一棵完全二叉树,不过它需要满足堆的性质---父节点大于等于子节点(大顶堆),或者父节点小于等于子节点(小顶堆)。堆排序前首先要构造堆,即要将输入的数组调整成堆(大顶堆为例);然后进行排序,最大堆只能保证首元素是当前堆中最大的元素,我们可以把首元素与堆的最后一个元素互换,这样首元素就排在了最后一个位置,也是正确的位置。然后将堆的前n-1个元素进行排序。互换到首元素位置的元素可能会破坏最大堆的性质,我们调整它使之重新成为最大堆,然后将首元素交换至当前堆的最后一个位置。依次递归。算法示例实现如下(java实现):
public static void heapSort(int[] input) { for (int i = input.length / 2; i >= 0; i--) adjustHeap(input, i, input.length - 1); for (int i = input.length - 1; i >= 0; i--) { int temp = input[0]; input[0] = input[i]; input[i] = temp; adjustHeap(input, 0, i - 1); } } public static void adjustHeap(int[] input, int i, int n) { int child; for (; i <= n / 2;) { child = i * 2; if (child + 1 <= n && input[child] < input[child + 1]) child += 1; if (input[i] < input[child]) { int temp = input[i]; input[i] = input[child]; input[child] = temp; i = child; } else break; } }
相关文章推荐
- C语言——几种经典的排序算法
- Java的几种经典排序算法
- 几种经典排序算法
- 几种经典排序算法的总结
- java的几种经典排序算法
- C/C++几种经典排序算法
- 几种经典排序算法的JS实现方法
- 几种经典排序算法的JS实现方法
- C++实现几种排序算法
- 几种常见的排序算法及实现(一)
- 经典排序算法--插入排序 希尔排序 归并排序
- java中常用的几种排序算法
- 几种经典的二值化方法及其vb.net实现
- 几种常见的排序算法实现
- JS几种排序算法
- 几种排序算法与运用实例
- C语言8大经典排序算法(2)
- 常见的几种排序算法-插入、选择、冒泡、快排、堆排等
- 经典排序算法 - 希尔排序Shell sort
- 几种常见的排序算法