排序2(Java)

1.冒泡排序

1.1冒泡排序的原理

在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序。
在这里插入图片描述
在这里插入图片描述

此时 有序空间在后面。

1.2冒泡排序的实现

import java.util.Arrays;
public class Sort {
public static void bubbleSort(int [] arr){
        for(int bound=arr.length-1;bound>=0;bound--){
            for(int cur=0;cur<bound;cur++){
                if(arr[cur]>arr[cur+1]){
                    swap(arr,cur,cur+1);
                }
            }
        }
    }
    public static void swap(int [] arr,int i,int j){
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }

    public static void main(String[] args) {
        int [] arr={9,5,2,7,3,6,8};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

2.快速排序

2.1快速排序的原理

快速排序的核心操作:partition
先在待排序空间选取一个“基准值”,然后把数组整理成左侧比基准值小,右侧比基准值(基准值可以取最后一个元素)大,使用左右下标两边往中间走来实现的。从左往右找一个比基准值大的元素,从右往左找一个比基准小的元素,然后交换两个元素的位置,继续往下走,进行交换两个元素,继续往下走,发现left和right重合了,此时发现重合元素的左边比基准值小,重合元素的右边比基准值大。
在这里插入图片描述
然后发现基准值左侧的值比基准值小,基准值右侧的值比基准值大。然后递归处理左右区间。

2.2快速排序的实现(递归)

import java.util.Arrays;

public class Sort {
public static void quickSort(int [] arr){
        //构造一个辅助递归的方法
        //在这个方法中明确指出争对哪个区间
        //[0,length-1]
        _quickSort(arr,0,arr.length-1);
    }

    public static void _quickSort(int [] arr,int left,int right){
        if(left>=right){
            //如果当前的空间为空,或只有一个元素
            //都不需要处理
            return;
        }
       //现针对当前的[left,right]进行partition
        //方法的返回值,表示整理完当前的区间后,基准值所在的位置
        //遍历过程中left和right重合的位置
        int index=partition(arr,left,right);
       //递归的对左侧区间进行快速排序
        _quickSort(arr,left,index-1);
       //递归的对右侧区间进行快排序
        _quickSort(arr,index+1,right);
    }

    public  static int partition(int [] arr,int left,int right){
        //选取最右侧元素作为基准值
        int v=arr[right];
        int l=left;
        int r=right;
        //若果l和r重合,说明遍历完成
        while(l<r){
            //先从左往右,找一个比基准值大的数字
            while(l<r&&arr[l]<v){
                l++;
            }
            //当循环结束了之后,l就指向了比基准值大的元素
            //从右往左找比基准值小的数字
            while(l<r&&arr[r]>=v){
                r--;
            }
            swap(arr,l,r);
        }
        //当l和r重合的时候,重合位置的元素
        //就把重合位置的元素基准值位置的元素交换位置
        swap(arr,l,right);
        //最后返回重合的位置
        return l;
    }

    public static void swap(int [] arr,int i,int j){
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }

    public static void main(String[] args) {
        int [] arr={9,5,2,7,3,6,8};
        quickSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

注意:
如果选取了最后一个位置作为基准值,必须先从左往右,再从右往左;如果选取了第一个元素作为基准值,则先从右往左,再从左往右。
快速排序的优化手段:
1)三数取中;
2)当待处理区间比较小的时候,就不继续递归了,直接针对该区域进行插入排序;
3)当递归达到一定的深度,并且当前的待处理区间比较大,还可以使用堆排序。

2.3快速排序的实现(非递归)

public static void quickSortByLoop(int [] arr){
        //1.先创建一个栈,这个栈用来处理每一个待处理区间
        Stack<Integer> stack=new Stack<>();
        //2.把根节点入栈
        stack.push(0);
        stack.push(arr.length-1);
        //循环取栈顶元素
        while(!stack.isEmpty()){
            //取得元素就是当前待处理空间
            //取得顺序正好与插入的顺序相反
            int right=stack.pop();
            int left=stack.pop();
            if(left>=right){
                //如果是空区间或者只有一个元素,不需要排序
                continue;
            }
            //调用partition方法调整当前区间
            int index=partition(arr,left,right);
            //右侧区间:[index+1,right]
            stack.push(index+1);
            stack.push(right);
            //左侧区间:[left,index-1]
            stack.push(left);
            stack.push(index-1);
        }
    }

    public  static int partition(int [] arr,int left,int right){
        //选取最右侧元素作为基准值
        int v=arr[right];
        int l=left;
        int r=right;
        //若果l和r重合,说明遍历完成
        while(l<r){
            //先从左往右,找一个比基准值大的数字
            while(l<r&&arr[l]<v){
                l++;
            }
            //当循环结束了之后,l就指向了比基准值大的元素
            //从右往左找比基准值小的数字
            while(l<r&&arr[r]>=v){
                r--;
            }
            swap(arr,l,r);
        }
        //当l和r重合的时候,重合位置的元素
        //就把重合位置的元素基准值位置的元素交换位置
        swap(arr,l,right);
        //最后返回重合的位置
        return l;
    }

    public static void swap(int [] arr,int i,int j){
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }

    public static void main(String[] args) {
        int [] arr={9,5,2,7,3,6,8};
        quickSortByLoop(arr);
        System.out.println(Arrays.toString(arr));
    }
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值