排序算法的学习(Java实现)

计划最近总结下之前排序算法

1.冒泡排序

  1. 比较相邻的元素。如果前一个元素比后一个元素大,就交换这两个元素的位置
public class Bubble {
    /**
     * 对数组a中的元素进行排序
     * @param a
     */
    public static void sort(Comparable[] a){
        //i控制多少个元素参与冒泡
        for (int i = a.length-1; i > 0; i--) {
            for (int j=0;j<i;j++){
                if (greater(a[j],a[j+1])){
                    exch(a,j,j+1);
                }
            }
        }
    }

    /**
     * 比较v是否大于w
     * @param v
     * @param w
     * @return
     */
    public static boolean greater(Comparable v, Comparable w){
        int result = v.compareTo(w);
        if (result>=0){
            return true;
        }
        return false;
    }
    public static void exch(Comparable[] a,int i,int j){
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}

2.插入排序

  1. 每一次遍历的过程中,都假定第一个索引处的元素是最小值,和其他索引处的值依次进行比较,如果当前索引处的值大于其他某个索引处的值,则假定其他某个索引出的值为最小值,最后可以找到最小值所在的索引
  2. 交换第一个索引处和最小值所在的索引处的值
public class Insertion {
    /**
     * 插入排序
     * @param a
     */
    public static void sort(Comparable[] a){
        for (int i = 1; i < a.length; i++) {
            for (int j=i;j>0;j--){
                if (greater(a[j],a[j-1])){
                    break;
                }else {
                    exch(a,j,j-1);
                }

            }
        }
    }
    /**
     * 比较v是否大于w
     * @param v
     * @param w
     * @return
     */
    public static boolean greater(Comparable v, Comparable w){
        int result = v.compareTo(w);
        if (result>=0){
            return true;
        }
        return false;
    }
    /**
     * 交换两个值
     * @param a
     * @param i
     * @param j
     */
    public static void exch(Comparable[] a,int i,int j){
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}

3.选择排序

  1. 把所有的元素分为两组,已经排序的和未排序的
  2. 找到未排序的组中的第一个元素,向已经排序的组中进行插入;
  3. 倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他的元素向后移动一位;
public class Selection {
    public static void sort(Comparable[] a){
        for (int i = 0; i < a.length-2; i++) {
            //假设最小值所在的索引为i
            int min_index=i;
            for (int j=i+1;j<a.length;j++){
                if (greater(a[min_index],a[j])){
                    min_index=j;
                }
            }
            exch(a,i,min_index);
        }
    }
    /**
     * 比较v是否大于w
     * @param v
     * @param w
     * @return
     */
    public static boolean greater(Comparable v, Comparable w){
        int result = v.compareTo(w);
        if (result>=0){
            return true;
        }
        return false;
    }
    public static void exch(Comparable[] a,int i,int j){
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}

4.快速排序

快速排序是对冒泡排序的一种改进。

  1. 首先设定一个分界值,通过该分界值将数组分成左右两部分;
  2. 将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边。此时左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值;
  3. 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
  4. 重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当
    左侧和右侧两个部分的数据排完序后,整个数组的排序也就完成了。
public int[] MySort (int[] arr) {
        // write code here
        quick(arr,0,arr.length-1);
        return arr;
    }
    public void quick(int[] arr,int left,int right){
        if(left<right){
            int p=partion(arr,left,right);
            quick(arr,left,p-1);
            quick(arr,p+1,right);
        }
        
    }
    private int partion(int[] arr, int start, int end) {
        int temp=arr[start];
        int left=start;
        int right=end;
        while (left<right){
            //从右往左找第一个小于temp的数
            while (right>left && arr[right]>=temp){
                right--;
            }
            arr[left]=arr[right];
            while (left<right && arr[left]<temp){
                left++;
            }
            arr[right]=arr[left];
        }
        //相遇的位置就是temp的排序后位置
        arr[left]=temp;
        return left;
    }

5.归并排序

  1. 尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数是1为止。
  2. 将相邻的两个子组进行合并成一个有序的大组;
  3. 不断的重复步骤2,直到最终只有一个组为止。
public class Merge {

    private static Comparable[] assist;
    /**
     * 比较v是否大于w
     * @param v
     * @param w
     * @return
     */
    public static boolean less(Comparable v, Comparable w){
        int result = v.compareTo(w);
        if (result<=0){
            return true;
        }
        return false;
    }
    /**
     * 交换
     * @param a
     * @param i
     * @param j
     */
    public static void exch(Comparable[] a,int i,int j){
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
    /**
     * 对数组a中的元素进行排序
     * @param a
     */
    public static void sort(Comparable[] a){
        //1.初始化辅助数组assist
        assist=new Comparable[a.length];
        //2.定义一个lo变量和hi变量,分别记录数组中最小的索引和最大的索引
        int lo=0;
        int hi=a.length-1;
        //3.调用sort重载方法完成数组a中,从索引lo到索引hi的元素的排序
        sort(a,lo,hi);
    }
    /**
     * 对数组a中从lo到hi的元素进行排序
     * @param a
     * @param lo
     * @param hi
     */
    public static void sort(Comparable[] a, int lo, int hi){
        //安全性校验
        if (lo>=hi){
            return;
        }
        //对lo到hi之间的数据进行分组
        int mid=lo+(hi-lo)/2;
        //分别对每一组数据进行排序
        sort(a,lo,mid);
        sort(a,mid+1,hi);
        //再把两个组中的数据进行归并
        merge(a,lo,mid,hi);
    }
    /**
     * 对数组中,从lo到mid为一组,从mid+1到hi为一组,对两组的数据进行归并
     * @param a
     * @param lo
     * @param mid
     * @param hi
     */
    public static void merge(Comparable[] a,int lo,int mid,int hi){
        //定义三个指针
        int i=lo;
        int p1=lo;
        int p2=mid+1;
		//遍历,移动p1和p2指针,比较对应索引的值,找出最小的那个放入到辅助数组中对应的地方
        while (p1<=mid && p2<=hi){
            //比较对应索引处的值
            if (less(a[p1],a[p2])){
                assist[i++]=a[p1++];
            }else {
                assist[i++]=a[p2++];
            }
        }
        //遍历,如果p1指针没有走完,那么顺序移动p1指针,把对应的元素放入辅助数组中去
        while (p1<=mid){
            assist[i++]=a[p1++];
        }
        //遍历,如果p2指针没有走完,那么顺序移动p2指针,把对应的元素放入辅助数组中去
        while (p2<=hi){
            assist[i++]=a[p2++];
        }
        //把辅助数组中的元素拷贝到原数组中对应的值
        for (int index=lo;index<hi;index++){
            a[index]=assist[index];
        }
    }
}

6.希尔排序(优化版的插入排序)

  1. 选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组;
  2. 对分好组的每一组数据完成插入排序;
  3. 减小增长量,最小减为1,重复第二步操作
public class Shell {
    public static void sort(Comparable[] a){
        int N=a.length;
        //确定增长量的最大值
        int h=1;
        while (h<N/2){
            h=2*h+1;
        }
		//当增长量小于1时,结束排序
        //希尔排序
        while (h>=1){
            for (int i=h;i<N;i++){
                for (int j=i;j>=h;j-- ){
                    if (greater(a[j],a[j-h])){
                        break;
                    }else {
                        exch(a,j,j-h);
                    }
                }
            }
            h=h/2;
        }
    }
    /**
     * 比较v是否大于w
     * @param v
     * @param w
     * @return
     */
    public static boolean greater(Comparable v, Comparable w){
        int result = v.compareTo(w);
        if (result>=0){
            return true;
        }
        return false;
    }
    /**
     * 交换两个值
     * @param a
     * @param i
     * @param j
     */
    public static void exch(Comparable[] a,int i,int j){
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值