排序算法
归并排序
思想: 经过多次递归,变为一个个数字。再经多次merge就可以变为有序。merge 方法中只有一个 for 循环,直接就可以得出每次合并的时间复杂度为 O(n) ,而分解数组每次对半切割,属于对数时间 O(log n) ,合起来等于 O(log2n) ,也就是说,总的时间复杂度为 O(nlogn) 。
public static void sort(int[] arr) {
int[] tempArr = new int[arr.length];//只定义一个临时数组,空间复杂度降低
sort(arr, tempArr, 0, arr.length-1);
}
/**
* 归并排序
* @param arr 排序数组
* @param tempArr 临时存储数组
* @param startIndex 排序起始位置
* @param endIndex 排序终止位置
*/
private static void sort(int[] arr,int[] tempArr,int startIndex,int endIndex){
if(endIndex <= startIndex){
return;
}
//中部下标
int middleIndex = startIndex + (endIndex - startIndex) / 2;
//分解
sort(arr,tempArr,startIndex,middleIndex);
sort(arr,tempArr,middleIndex + 1,endIndex);
//归并
merge(arr,tempArr,startIndex,middleIndex,endIndex);
}
/**
* 归并
* @param arr 排序数组
* @param tempArr 临时存储数组
* @param startIndex 归并起始位置
* @param middleIndex 归并中间位置
* @param endIndex 归并终止位置
*/
private static void merge(int[] arr, int[] tempArr, int startIndex, int middleIndex, int endIndex) {
//复制要合并的数据
for (int s = startIndex; s <= endIndex; s++) {
tempArr[s] = arr[s];
}
int left = startIndex;//左边部分首位下标
int right = middleIndex + 1;//右边部分首位下标
for (int k = startIndex; k <= endIndex; k++) {
if(left > middleIndex){
//如果左边的首位下标大于中部下标,证明左边的数据已经排完了。
arr[k] = tempArr[right++];
} else if (right > endIndex){
//如果右边的首位下标大于了数组长度,证明右边的数据已经排完了。
arr[k] = tempArr[left++];
} else if (tempArr[right] < tempArr[left]){
arr[k] = tempArr[right++];//将右边的首位排入,然后右边的下标指针+1。
} else {
arr[k] = tempArr[left++];//将左边的首位排入,然后左边的下标指针+1。
}
}
}
快速排序
思想: 定义第一个为基准数,先从右边扫描,找到第一个小于他的数,再从左边扫描,直到找到一个比他大的。交换,直到两个指针相遇。3,1,2,5,4到2,1,3,5,4
#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right) {
int i, j, t, temp;
if(left > right)
return;
temp = a[left]; //temp中存的就是基准数
i = left;
j = right;
while(i != j) { //顺序很重要,要先从右边开始找
while(a[j] >= temp && i < j)
j--;
while(a[i] <= temp && i < j)//再找右边的
i++;
if(i < j)//交换两个数在数组中的位置
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//最终将基准数归位
a[left] = a[i];
a[i] = temp;
quicksort(left, i-1);//继续处理左边的,这里是一个递归的过程
quicksort(i+1, right);//继续处理右边的 ,这里是一个递归的过程
}
int main() {
int i;
//读入数据
scanf("%d", &n);
for(i = 1; i <= n; i++)
scanf("%d", &a[i]);
quicksort(1, n); //快速排序调用
//输出排序后的结果
for(i = 1; i < n; i++)
printf("%d ", a[i]);
printf("%d\n", a[n]);
return 0;
}