以下算法选用的描述语言均为Java语言
1、冒泡排序:
时间复杂度为O(n^2)
一开始交换区间为0~N-1,然后第一个数跟第二个数进行比较,哪个大哪个就放后面。然后是第二个数和三个数比较,哪个大哪个就放后面。依次交换,最终最大的数在最后面。然后把范围从0~N-1到0~N-2。这样第二大的数会放在倒数第二位,依次下去,最终只剩下一个数,冒泡排序完成。
例题:
对于一个int数组,请编写一个冒泡排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
import java.util.*;
public class BubbleSort {
public int[] bubbleSort(int[] A, int n) {
// write code here
for(int i = 0 ; i < n - 1; i++){
for(int j = 0 ; j < n - 1 - i ; j++){
if(A[j] > A[j+1]){
int temp = A[j+1];
A[j+1] = A[j];
A[j] = temp;
}
}
}
return A;
}
}
2、选择排序:
时间复杂度为O(n^2)
在范围0~N-1上选出一个最小值,把它放到位置0上,然后在1~N-1的范围上选出最小值,把它放到位置1上。依次下去,最后只包含一个数的时候选择排序完成。
对于一个int数组,请编写一个选择排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
import java.util.*;
public class SelectionSort {
public int[] selectionSort(int[] A, int n) {
for (int i = 0; i < n - 1; i++)//控制趟数
{
int min = A[i];//始终默认最大的一个数在末尾
for (int j = i + 1; j < n; j++)
{
if(A[j] < min)
{
min = A[j];
int temp;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
return A;
}
}
3、插入排序:
时间复杂度为O(n^2)
位置0上的数和位置1上的数进行比较,如果位置1上的数更小,就和位置0上的数交换。位置2上的数依次和位置0、位置1上的数交换,如果比位置1小,和位置1交换,继续和位置0比较,如果更小,和位置0交换,依次下去,一直到N-1,自此插入排序完成。
import java.util.*;
public class InsertionSort {
public int[] insertionSort(int[] A, int n) {
// write code here
int exchange;
int tmp;
for(int i=1;i<n;i++){
exchange=i;
for(int j=i-1;j>=0;j--){
if(A[j]<=A[exchange])
break;
else{
tmp=A[exchange];
A[exchange]=A[j];
A[j]=tmp;
exchange=j;
}
}
}
return A;
}
}
4、归并排序
时间复杂度:O(N*logN)
import java.util.*;
public class MergeSort {
public int[] mergeSort(int[] A, int n) {
// write code here
int[] temp = new int[n];
mergeSortRecurrence(A, 0, n - 1, temp);
return A;
}
public void mergeSortRecurrence(int[] A, int left, int right, int[] temp){
if(left < right){
int mid = (left + right) / 2;
mergeSortRecurrence(A, left, mid, temp);
mergeSortRecurrence(A, mid + 1, right, temp);
mergeArrays(A, left, mid, right, temp);
}
}
public void mergeArrays(int[] A, int left, int mid, int right, int[] temp){
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right) {
if(A[i] <= A[j]){
temp[k++] = A[i++];
}else {
temp[k++] = A[j++];
}
}
while (i <= mid) {
temp[k++] = A[i++];
}
while (j <= right) {
temp[k++] = A[j++];
}
for (i = 0; i < k; i++) {
A[left + i] = temp[i];
}
}
}
让数组中的每一个数单独成为长度为1的有序区间,然后把相邻的长度为1的有序区间之间进行合并,得到最大长度为2的有序区间。然后再把相邻有限区间进行合并,得到最大长度为4的有序区间。依次下去,直到让数组中所有的数合并成一个有序区间,归并排序结束。
5、快速排序
时间复杂度:O(N*logN)
快速排序是随机的在数组中选择一个数,小于等于这个数的统一放在这个数的左边,大于这个数的统一放在这个数的右边。接下来对左右两个部分分别进行递归的调用快速排序的过程,这样使得整个数组都有序了。
import java.util.*;
public class QuickSort {
public int[] quickSort(int[] A, int n) {
// write code here
process(A,0,n-1);
return A;
}
private void process(int[] aar,int left,int right){
if(left<right){
int mun=aar[left];
int l=left,r=right;
while(l<r){
while(aar[r]>=mun&&r>l)
r--;
if(l<r){
int a=aar[r];
aar[r]=mun;
aar[l]=a;
l++;
}
while(aar[l]<mun&&l<r){
l++;
}
if(l<r){
int a=aar[l];
aar[l]=mun;
aar[r]=a;
// r--;
}
}
//aar[l]=mun;
process(aar,left,l-1);
process(aar,r+1,right);
}
}
}
6、堆排序
时间复杂度:O(N*logN)
把数组中的N个数建成大小为N的大根堆。堆顶元素为最大值,把堆顶元素与堆的最后一个元素互换,然后把最大值脱离出整个结构,放在数组的最后的位置。然后再把N-1大小的堆从堆顶开始进行调整。在调整出一个N-1的数的最大值放在堆顶定位位置。接下来把堆顶的位置和整个堆的最后一个位置互换,同样作为堆的有序部分。依次继续,堆的大小每次减1,有序部分每次加1。这样,整个数组就变的有序了。
7、希尔排序
时间复杂度:O(N*logN)
关键在于步长的选择:
插入排序的改良,只是步长由大到小依次交换。