排序算法(归并排序、快速排序)
给你n个乱序的整数,让你将它们按照从小到大的顺序排列,这个问题看起来很简单,今天我来介绍几种非常著名的排序算法
归并排序
归并排序是经典的分治思想,要一下子完成n个数的排序不容易,可以把它从中间分割开,分别对左半部分和由半部分的数字排序,然后将两个有序的数组合并起来就得到最终的有序数组
同理,如果左右部分还是很长怎么办?继续分,直到只有一个数的时候,这个局部数组是有序的直接返回
伪代码
归并排序思想的伪代码如下:
递归函数:
如果当前只有一个元素,返回
递归排序左半部分
递归排序右半部分
合并两边的数组
假设有一组样例 7,2,4,5,1,8
依照归并排序的思想可以将数组作以下划分
当数组递归到只有一个元素返回后,它的上一层递归就可以将两个有序数组合并,然后继续返回到上一次,以此合并两个有序数组并返回的过程如下图:
代码
//归并排序
public class MergerSort {
int[] b;
public MergerSort(int[] b) {
//初始化中间数组
this.b = b;
}
public void sort(int[] a,int left,int right) {
//只有一个元素不用排序
if(left==right) {
return;
}
//大于1个元素
int mid=(left+right)/2;
//分治策略,将数组分成两半分别排序
sort(a,left,mid);
sort(a,mid+1,right);
//左右两部分都排序完毕,将它们合并
//左半部分数组的下标
int l_index=left;
//右半部分数组的下标
int r_index=mid+1;
//中间数组b的下标
int index=left;
//将两个有序数组合并到一起,直到一个数组为空
while(l_index<=mid&&r_index<=right) {
if(a[l_index]<a[r_index]) {
b[index]=a[l_index];
l_index++;
}else{
b[index]=a[r_index];
r_index++;
}
index++;
}
//剩下的数组是有序的直接插入到数组b的后面即可
while(l_index<=mid){
b[index++]=a[l_index++];
}
while(r_index<=right){
b[index++]=a[r_index++];
}
//将有序的数组复制到原数组中
for(int i=left;i<=right;i++){
a[i]=b[i];
}
}
}
快速排序
快速排序和归并排序很像,也是利用分治的思想,快速排序每次从数组中选一个数当作中间值,把小于这个中间值的数组放到数组的左边,把大于这个数的值放到数组的右边,然后递归调用自己分别对左半部分和右半部分执行如上操作
中间值的选取
只是说了要选一个中间值,那么到底该选数组中的哪个数作为中间值呢?
常用的就是选择数组中的第一个数当作中间值,不过在极端情况下时间复杂度会退化到n方。
也可以随机选取数组中的一个数当作中间值
还有一种,就是比较左右两端和中间的数字,选介于中间的那个数当作中间值
这里我就用第一种,选择数组中的第一个数当作中间值
伪代码
快速排序:
如果当前只有一个元素,返回
设置两个指针变量(i,j)分别指向数组头和尾
选择第一个数当作中间值 pivot
while(i<j){
从后往前找到第一个小于pivot的
从前往后找到第一个大于pivot的
如果i<j,交换这两个数
}
将下标j对应的数和数组第一个数交换
递归对左半部分数组做同样操作
递归对右半部分数组做同样操作
代码
public class QuickSort {
public void sort(int[] a,int low,int high) {
if(low>=high) {
return;
}
int partition = partition(a, low, high);
sort(a,low,partition-1);
sort(a,partition+1,high);
}
//选第一个元素当标准,并划分左右两部分数组
public int partition(int[] a,int low,int high) {
int pivot = a[low];
int i = low;
int j = high;
while(i<j) {
while(i<j&&a[j]>=pivot) j--;
while(i<j&&a[i]<=pivot) i++;
//交换
if(i<j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
//将数组中第一个元素即中间值和下标j对应的元素交换
a[low] = a[j];
a[j] = pivot;
return j;
}
}
原文地址:https://blog.csdn.net/weixin_74141526/article/details/145042419
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!