您的位置:首页 > 其它

各种基本排序算法总结

2015-12-20 00:20 246 查看
虽然我们用的语言中有排序的函数,我们用的时候直接调用就可以,不过这些经典排序算法中的许多思想以及实现它们过程中的一些编程技巧在我们实际编程中还是被频繁被用到的,作为一个程序员,这是基本功,还是很有必要掌握的。

下面算法全部最终按从小到大排序。

1.冒泡排序

思想:相邻两个数进行比较,如果前一个更大,就和后一个交换,这样每次将未排序部分的最大的数添加到已排好序的部分的第一个,进行n-1次即可。

代码如下:

public int[] mp(int[] a) {
if (a == null || a.length == 0) {
return null;
}
int temp;
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
return a;
}


平均时间复杂度O(N^2),最坏O(N^2),最好O(N),辅助存储O(1),是稳定的排序算法。

2.选择排序

思想:每次将未排好序的部分的最小的数添加到已排好序的部分的末尾。

代码如下:

public int[] selectionSort(int[] a) {
if (a == null || a.length == 0) {
return null;
}
int k,temp;
for(int i = 0;i < a.length - 1;i++) {
k = i;
for(int j = i+1;j < a.length;j++) {
if(a[j] < a[k]) {
k = j;
}
}
if(k != i) {
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
return a;
}


平均时间复杂度O(N^2),最坏O(N^2),最好O(N^2),辅助存储O(1),不稳定(看下 2,2,1就知道了,开始在前面的2,排好序后到后面去了)。

3.直接插入排序

思想:直接插入排序的思想是每次将未排序部分的第一个数插入到已排好序的部分,并使已排好序的部分依旧有序。

代码如下:

public int[] insertionSort(int[] a) {
if(a == null || a.length == 0) {
return null;
}
int j,temp;
for(int i = 1;i < a.length;i++) {
temp = a[i];//a[i]会被a[j+1] = a[j]覆盖掉,所以先用一个变量存起来
j = i-1;
while(j >= 0 && a[j] > temp) {
a[j+1] = a[j];
j--;
}
a[j+1] = temp;
}
return a;
}


平均时间复杂度O(N^2),最坏O(N^2),最好O(N),辅助存储O(1),是稳定的排序算法。

4.快速排序

思想:把比某个数(一般取序列的第一个元素)小的数移到它的左边,大的数移到右边,分治递归这个过程,到序列只剩一个数自然就排好了。。

代码如下:

void quickSort(int[] a,int low,int high) {
if (low >= high) {//不要用low == high,下面i-1会小于low的
return;
}
int i = low,j = high,temp = a[low];
while (i < j) {
while (i < j && a[j] >= temp) {
j--;
}
if (i < j) {
a[i++] = a[j];
}
while (i < j && a[i] <= temp) {
i++;
}
if (i < j) {
a[j--] = a[i];
}
}
a[i] = temp;
quickSort(a, low, i - 1);
quickSort(a, i + 1, high);
}


可以稍微简化下:

void quickSort(int[] a,int low,int high) {

if (low >= high) {
return;
}

int i = low,j = high;
int temp = a[low];
while (i < j) {
while (i < j && a[j] >= temp) {
j--;
}
if (i < j) {
a[i++] = a[j];
}
while (i < j && a[i] <= temp) {
i++;
}
a[j--] = a[i];
}
a[i] = temp;
quickSort(a, low, i - 1);
quickSort(a, i + 1,high);

}


时间复杂度O(N*lg(N)),最坏O(N^2),最好O(N*lg(N)),辅助存储O(lg(N)),不稳定。

5.归并排序

思想:先一层层的往下【递推】到每个区间只有一个数,然后在【回归】的时候不断合并【区间内已经有序的区间】,并保证合并后的区间有序。

#include<stdio.h>

void merge(int a[],int s,int mid,int e,int temp[]) {
int i = s,j = mid + 1,k = 0;
while(i <= mid && j <= e) {
if(a[i] <= a[j]) {
temp[k++] = a[i++];
} else {
temp[k++] = a[j++];
}
}
while(i <= mid) {
temp[k++] = a[i++];
}
while(j <= e) {
temp[k++] = a[j++];
}
for(int i = 0;i < k;i++) {
a[s + i] = temp[i];
}
}

void mergeSort(int a[],int s,int e,int temp[]) {
if(s < e) {
mergeSort(a,s,(s + e) / 2,temp);
mergeSort(a,(s + e) / 2 + 1,e,temp);
merge(a,s,(s + e) / 2,e,temp);
}
}

int main() {
int a[] = {4,2,7,9,1,3,10,5};
int temp[8];
mergeSort(a,0,7,temp);
for(int i = 0;i < 8;i++) {
printf("%d ",a[i]);
}
free(temp);
}


速度仅次于快速排序,一般用于总体无序,但是各子项相对有序的数列。

平均时间复杂度O(N*lg(N)),最坏O(N*lg(N)),最好O(N*lg(N)),稳定,辅助存储O(N)。

下次接着写。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: