排序算法总结
归并排序
- 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
- 归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。java 中 Arrays.sort()采用了一种名为 TimSort 的排序算法,就是归并排序的优化版本。从上文的图中可看出,每次合并操作的平均时间复杂度为 O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为 O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为 O(nlogn)。
public int[] MySort (int[] arr) {
// write code here
mergeSort(arr,0,arr.length-1);
return arr;
}
public void mergeSort(int[] arr,int l,int r){
if(l==r){
return;
}
int mid = l+(r-l)/2;
mergeSort(arr,l,mid);
mergeSort(arr,mid+1,r);
merge(arr,l,mid,r);
}
public void merge(int[] arr,int l,int mid,int r){
int [] help= new int[r-l+1]; //辅助数组
int i=0;
int p1=l; //左半数组的下标
int p2=mid+1; //右半数组的下标
//判断是否越界
while(p1<=mid && p2<=r){
help[i++]=arr[p1]<arr[p2] ? arr[p1++] : arr[p2++];
}
//p1没有越界,说明p2越界了,将左边剩余元素拷贝到辅助数组
while(p1<=mid){
help[i++]=arr[p1++];
}
//p2没有越界,说明p1越界了
while(p2<=r){
help[i++]=arr[p2++];
}
//将辅助数组元素拷贝会原数组
for(i=0;i<help.length;i++){
arr[l+i]=help[i];
}
快速排序
快速排序(Quick Sort):是对冒泡排序的一种改进方法,在冒泡排序中,进行元素的比较和交换是在相邻元素之间进行的,元素每次交换只能移动一个位置,所以比较次数和移动次数较多,效率相对较低。而在快速排序中,元素的比较和交换是从两端向中间进行的,较大的元素一轮就能够交换到后面的位置,而较小的元素一轮就能交换到前面的位置,元素每次移动的距离较远,所以比较次数和移动次数较少,y 速度较快,故称为“快速排序”。
快速排序的基本思想是:
- 在待排序的元素任取一个元素作为基准(通常选第一个元素,但最的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
- 将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
- 对左右两个分区重复以上步骤直到所有元素都是有序的
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
public int[] MySort (int[] arr) {
quickSort(arr , 0 , arr.length-1);
return arr;
}
public void quickSort(int[] list, int left, int right) {
if (left < right) {
// 分割数组,找到分割点
int point = partition(list, left, right);
// 递归调用,对左子数组进行快速排序
quickSort(list, left, point - 1);
// 递归调用,对右子数组进行快速排序
quickSort(list, point + 1, right);
}
}
/**
* 分割数组,找到分割点
*/
public int partition(int[] list, int left, int right) {
// 用数组的第一个元素作为基准数
int first = list[left];
while (left < right) {
while (left < right && list[right] >= first) {
right--;
}
// 交换
swap(list, left, right);
while (left < right && list[left] <= first) {
left++;
}
// 交换
swap(list, left, right);
}
// 返回分割点所在的位置
return left;
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战