您的位置:首页 > 其它

几种经典排序算法

2013-07-30 21:16 176 查看
为了对以下各个算法进行方便的测试,我首先写好了测试主方法体。如下(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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息