各种排序算法
1.快速排序
- 1.i = L; j = R; 将基准数挖出形成第一个坑 a[i]。
- 2.j-- 由后向前找比它小的数,找到后挖出此数填前一个坑 a[i] 中。
- 3.i++ 由前向后找比它大的数,找到后也挖出此数填到前一个坑 a[j] 中。
- 4.再重复执行 2,3 二步,直到 i==j,将基准数填入 a[i] 中。
public static int partition(int[] arr,int left,int right) {
int prov = arr[left];
while (left<right) {
while(arr[right] >= prov && left<right) {
right--;
}
//右边元素小于prov
if(left<right) {
arr[left] = arr[right];
left++;
}
while (arr[left] <= prov && left<right){
left++;
}
//左边元素大于prov
if(left<right){
arr[right] = arr[left];
right--;
}
}
//将prov放入最终位置
arr[left] = prov;
return left;
}
public static void quickSorted(int[] arr,int left,int right) {
if(arr == null || left>=right || arr.length <= 1){
return;
}
int mid = partition(arr,left,right);
quickSorted(arr,left,mid);
quickSorted(arr,mid+1,right);
}
- 时间复杂度:O(N log N),这里 N 是数组的长度;
- 空间复杂度:O(log N),这里占用的空间主要来自递归函数的栈空间。
2.归并排序
归并排序是建立在归并操作上的一种有效的排序算法,
该算法是采用分治法的一个非常典型的应用。即先使每个子序列有序,
再将已有序的子序列合并,得到完全有序的序列。
public int[] sortArray(int[] nums) {
sortArray1(nums,0,nums.length-1);
return nums;
}
//递归函数
public void sortArray1(int[] nums,int left, int right) {
//递归终止条件
if(nums == null || left == right) {
return;
}
int mid = left + (right-left)/2;
sortArray1(nums, left,mid);
sortArray1(nums, mid+1,right);
merge(nums,left,right,mid);
}
//合并两个有序数组
public void merge(int[] nums, int left,int right, int mid) {
int[] arr = new int[right-left+1];
int lpoint = left;
int rpoint = mid+1;
int index = 0;
while(lpoint <= mid && rpoint <= right){
if(nums[lpoint] <= nums[rpoint]) {
arr[index++] = nums[lpoint++];
}else{
arr[index++] = nums[rpoint++];
}
}
//左边还有剩余
while(lpoint <= mid) {
arr[index++] = nums[lpoint++];
}
//右边还有剩余
while(rpoint <= right){
arr[index++] = nums[rpoint++];
}
//将辅助数组中的元素填充回原数组
for(int i = 0;i<arr.length;i++) {
nums[left+i] = arr[i];
}
}
- 间复杂度为O(nlogn)。此外在最坏、最佳、平均情况下归并排序时间复杂度均为O(nlogn)。
- 空间复杂度分析:在排序过程中使用了一个与原数组等长的辅助数组,估空间复杂度为O(n)。
- 稳定性分析:由排序过程可以知道,归并排序是一种稳定排序。
- 是否原地排序:排序过程中用到了辅助数组,所以是非原地排序。
3.插入排序
思路:每次将一个数字插入一个有序的数组里,
成为一个长度更长的有序数组,有限次操作以后,数组整体有序。
public int[] sortArray(int[] nums) {
for(int i=1;i<nums.length;i++) {
int temp = nums[i];
int j=i;
while(j>0 && nums[j-1] > temp) {
nums[j] = nums[j-1];
j--;
}
nums[j] = temp;
}
return nums;
}
- 时间复杂度: O(N2)
- 空间复杂度:O(1),使用到常数个临时变量。