排序算法

package com.example.lib.sort;

/**
 * Created by mengjk on 18-4-28.
 */

public class Sort {

    public static void main(String[] args){

        int[] array={7,12,1,6,3,10,8,26,5,3,11};
        maopao1(array);
        printResult("-result",array);

    }


    //最前便利冒泡
    private static void maopao1(int[] array){
        System.out.println("mapao1");
        //普通方式,从前面遍历,比较交换
        for(int i=0;i<array.length;i++){
            for (int j=i+1;j<array.length;j++){
                if(array[i]>array[j]){
                    swap(array,i,j);
                }
            }
        }

    }

    //从后便利冒泡
    private static void maopao2(int[] array){
        System.out.println("mapao2");
        //从后往前遍历,比较并交换,减少比较次数
        for(int i=0;i<array.length;i++){
            for (int j=array.length-1;j>=i;j--){
                if(array[i]>array[j]){
                    swap(array,i,j);
                }
            }
        }
    }


    //直接选择排序
    private static void select1(int[] array){
        System.out.println("select1");
        for(int i=0;i<array.length;i++){
            //每次找出当前项的剩余序列中最小/最大值跟当前项交换。
            int min=i;
            for (int j=i+1;j<array.length;j++){
                if(array[min]<array[j]){
                    min=j;//记下最小/最大值
                }
            }

            if(min!=i){//如果发现有这样的值,则交换
                swap(array,i,min);
            }

        }
        printResult("-result",array);
    }


    //直接插入排序
    private static void inser(int[] array){
        System.out.println("inser2");
        for (int i = 1; i < array.length; i++) {
            int j=0;
            int temp = array[i]; // 取出第i个数,和前i-1个数比较后,插入合适位置
            // 因为前i-1个数都是从小到大的有序序列,所以只要当前比较的数(list[j])比temp大,就把这个数后移一位
            for (j = i - 1; j >= 0 && temp < array[j]; j--) {
                array[j + 1] = array[j];
            }
            array[j + 1] = temp;
        }
        printResult("-result",array);
    }

    //希尔排序
    private static void shell(int[] array) {
        System.out.println("shell");
        /*
        gap 9/2=4
        12-10,1-8,6-26,3-5,10-3 4个间隔为一组,排完是
        10,1,6,3,3,12,8,26,5

        gap 4/2=2  相隔是2个间隔的数据为一组,
        10-6-3-8-5,1-3-12-26,。。。把这些排序一下。

        * */
        //增量gap,并逐步缩小增量
        for (int gap = array.length / 2; gap > 0; gap /= 2) {
            //从第gap个元素,逐个对其所在组进行直接插入排序操作
            for (int i = gap; i < array.length; i++) {
                int j = i;
                while (j - gap >= 0 && array[j] < array[j - gap]) {
                    //插入排序采用交换法
                    swap(array, j, j - gap);
                    j -= gap;
                    //这是一个组,对每一个gap生成的一组数据进行排序,j-=gap能确保是本组中往前一个对比,直到对比完
                }
            }
        }

        printResult("-result", array);
    }

    //堆排序
    private static void heap(int[] array) {
        System.out.println("shell");

        int len = array.length -1;
        for(int i = len/2 - 1; i >=0; i --){ //堆构造,只有len/2-1之前的节点才有子结点。
            heapAdjust(array,i,len);
        }
        while (len >=0){
            swap(array,0,len--);    //将堆顶元素与尾节点交换后,长度减1,尾元素最大
            heapAdjust(array,0,len);    //再次对堆进行调整
        }

        printResult("-result", array);
    }

    public static  void heapAdjust(int[] arr,int i,int len){
        int left,right,j ;
        while((left = 2*i+1) <= len){    //判断当前父节点有无左节点(即有无孩子节点,left为左节点)
            right = left + 1;  //右节点
            j = left;   //j"指针指向左节点"
            if(j < len && arr[left] < arr[right])    //右节点大于左节点
                j ++;     //当前把"指针"指向右节点
            if(arr[i] < arr[j])    //将父节点与孩子节点交换(如果上面if为真,则arr[j]为右节点,如果为假arr[j]则为左节点)
                swap(arr,i,j);
            else         //说明比孩子节点都大,直接跳出循环语句
                break;
            i = j;
        }
    }

    //归并排序
    public static void guibin(int []arr){
        System.out.println("sort");
        int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
        sort(arr,0,arr.length-1,temp);
        printResult("-result", arr);
    }
    private static void sort(int[] arr,int left,int right,int []temp){
        if(left<right){//不断的把数组拆分,直到只有一个数为止
            int mid=(left+right)/2;
            sort(arr,left,mid,temp);
            sort(arr,mid+1,right,temp);
            merge(arr,left,mid,right,temp);
        }

    }
    private static void merge(int[] arr,int left,int mid,int right,int[] temp){
        //把拆分的数组有序的合并起来
        int index=left;
        int i=left,j=mid+1;//用于标识左右两个数组,因为要把这两个数组并成一个有序的数组,
        while (i<=mid&&j<=right){//方式就是从从左右开始,谁最小就把谁捡到Temp中,并把它的index往前加1
            if(arr[i]<=arr[j]){
                temp[index]=arr[i];
                index++;
                i++;
            }else{
                temp[index]=arr[j];
                index++;
                j++;
            }
        }

        //上面选择完后,如果还有数据,说明肯定是最大或者最小的有序组,直接把剩下的都放到temp中。

        //把左边剩下的都拷贝到数组中
        while (i<=mid){
            temp[index]=arr[i];
            index++;
            i++;
        }

        //把右边剩下的都拷贝到数组中

        while (j<=right){
            temp[index]=arr[j];
            index++;
            j++;
        }

        index--;//因为while中多操作了一步,把它还原回来
        //把temp复制到arr中
        while (index>=0){
            arr[index]=temp[index];
            index--;
        }
        //printResult("",temp);

    }

    //快速排序
    private static void quik(int[] array){
        //对每一次数组,都以第一个下标的数据为中枢,然后把数组中的所有数据,小的都放到中枢左边,大的都放到中枢的右边
        //然后再把中枢的左边当成一个新的数组再排序,中枢右边的数组也是一样
        System.out.println("quik");
        qsort(array,0,array.length-1);
        printResult("-result",array);
    }

    private static void qsort(int[] arr, int low, int high){

        if (low < high){
            int pivot=partition(arr, low, high);        //将数组分为两部分
            qsort(arr, low, pivot-1);                   //递归排序左子数组
            qsort(arr, pivot+1, high);                  //递归排序右子数组
        }
    }
    //不需要交换的快排
    private static int partition(int[] arr, int low, int high){
        int pivot = arr[low];     //枢轴记录
        while (low<high){
            //相当于把这个中枢当成一个空位就对了。
            while (low<high && arr[high]>=pivot) --high;//只要遍历到的数比中枢大,说明是不用交换的,继续向下找,这样做能省效率
            // 如果找到那么就停止并交换
            arr[low]=arr[high];             //交换比枢轴小的记录到左端
            while (low<high && arr[low]<=pivot) ++low;//同理,
            arr[high] = arr[low];           //交换比枢轴小的记录到右端
        }
        //扫描完成,枢轴到位
        arr[low] = pivot;
        //返回的是枢轴的位置
        return low;
    }

    //使用交换来实现,快排
    private static int partition2(int[] arr, int low, int high){
        int pivot = low;     //枢轴记录
        while (low<high){

            while (low<high){
                if(arr[high]<arr[pivot]){
                    swap(arr,high,pivot);
                    pivot=high;
                    high--;
                    break;
                }
                high--;
            }

            while (low<high){
                if(arr[low]>arr[pivot]){
                    swap(arr,low,pivot);
                    pivot=low;
                    low++;
                    break;
                }
                low++;
            }
        }
        //返回的是枢轴的位置
        return pivot;
    }

    private static void swap(int[] array,int i,int j){
        int temp=array[i];
        array[i]=array[j];
        array[j]=temp;
    }


    private static void printResult(String index,int[] array){
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<array.length;i++){
            if(i==array.length-1){
                sb.append(""+array[i]);
            }else{
                sb.append(""+array[i]+",");
            }
        }
        System.out.println("sort"+index+": "+sb.toString());
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值