常见的排序方法

 

目录

一、直接插入排序

二、希尔排序

三、选择排序

四、堆排序

五、冒泡排序

六、快速排序

七、归并排序


排序是指根据某一特定标准,将一组“无序”的数据元素调整为“有序”的数据元素的过程。排序是计算机内经常进行的一种操作,其目的是按照一定的规则(如数字大小、字母顺序等)对数据元素进行重新排列,以便更有效地进行搜索、比较和其他数据处理操作。

   常见的排序方法有7种,直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序。

先定义一个交换的方法:

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

一、直接插入排序

直接插入排序逻辑:

  从一组数据的第二个元素开始,依次和前面的元素进行比较,找到合适的位置进行插入。

代码如下:

 public static void insertSort(int[]array){

        for (int i = 1; i < array.length; i++) {

            int tmp=array[i];

            int j=i-1;

            for (; j >=0 ; j--) {

                if (array[j]>tmp){

                    array[j+1]=array[j];

                }else {

                    break;
                }
            }
            array[j+1]=tmp;
        }

    }

二、希尔排序

希尔排序的逻辑:

     希尔排序是对直接插入排序的优化,先把数据分组进行预排序,然后再整体排序,可以让排序速度加快。

代码如下:

  public static  void shellSort(int[]array){
        //分组
        int gap=array.length;
        while (gap>1){
            gap/=2;
            shell(array,gap);
        }
    }
    //排序
    private static void shell(int[] array, int gap) {
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = i - gap;
            for (; j >= 0; j-=gap) {
                if (array[j] > tmp) {
                    array[j + gap] = array[j];
                } else {
                    break;
                }
            }
            array[j + gap] = tmp;
        }
    }

三、选择排序

选择排序有单向选择排序和双向选择排序。

单向选择排序逻辑:

    对数组进行遍历,找到数组中最小的值,将最小值放到数组最前面,然后再找到除这个值之外的最小值放到上一个最小值的后面,以此类推遍历整个数组。

代码如下:

  public static void selectSort(int[]array){
        for (int i = 0; i < array.length; i++) {
            int mindex=i;
            for (int j = i+1; j < array.length; j++) {
                if (array[j]<array[mindex]){
                    mindex=j;
                }
            }
            Swap(array,i,mindex);
        }
    }

双向选择排序逻辑:

  对数组进行遍历,找到数组中的最大值和最小值,将它放在数组的最前面和最后面,然后对剩下数据再进行同样的操作。

代码如下:

 public static void DselectSort(int[]array){

        int left=0;

        int right=array.length-1;

        while (left<right){
            int minIndex=left;
            int maxIndex=left;

            for (int i = left+1; i <=right; i++) {
                if (array[i] < array[minIndex]) {
                    minIndex = i;
                }
                if (array[i] > array[maxIndex]) {
                    maxIndex = i;
                }
            }

                Swap(array,minIndex,left);

                if (maxIndex==left){

                    maxIndex=minIndex;
                }
                Swap(array,maxIndex,right);
                left++;
                right--;
            }
        }

四、堆排序

堆排序逻辑:

     创建一个大根堆,堆顶元素是最大的,让最大值的元素和最后一个元素进行互换,最大值的元素就被移到了最后,然后把其余元素再排成大根堆,将这次堆顶最大值元素和倒数第二个元素进行互换,以此类推,遍历整个大根堆。

代码如下:

//创建大根堆 
public static void createHeap(int[]array){
            for (int parent = (array.length-1-1)/2; parent >=0; parent--) {
                siftDown(array,parent,array.length);
            }
        }

        //向下调整
        private static void siftDown(int[]array, int parent, int length) {
            int child = 2 * parent + 1;
            while (child < length) {
                if (child + 1 < length && array[child] < array[child + 1]) {
                    child = child + 1;
                }
                if (array[child] > array[parent]) {
                    Swap(array, child, parent);
                    parent = child;
                    child = 2 * parent + 1;
                } else {
                    break;
                }
            }
        }
            //堆排序
            public static void heapSort (int[] array){
                createHeap(array);
                int end = array.length - 1;
                while (end > 0) {
                    Swap(array, 0, end);
                    siftDown(array, 0, end);
                    end--;
                }
            }

五、冒泡排序

冒泡排序的逻辑:

  遍历一组数据,从第一个值开始往后进行遍历,如果顺序错误就进行交换。

代码如下:

 public static void bobbleSort(int[]array){
        for (int i = 0; i < array.length-1; i++) {
            boolean flag=false;
            for (int j = 0; j < array.length-i-1; j++) {
                if (array[j]>array[j+1]){
                    Swap(array,j,j+1);
                    flag=true;
                }
            }
            if (flag==false){
                break;
            }
        }
    }

六、快速排序

快速排序的逻辑:

  在数组中,以第一个值为基准,从后往前找到比基准小的值,然后从前往后找到比基准大的值,然后将这两个值进行交互,当从后往前找和从前往后找相遇时,将相遇的值和基准值进行交换,然后再对数组进行递归。

代码如下:

public static void quickSort(int[]array){
        quick(array,0,array.length-1);
    }

    //快速排序
    private static void quick(int[]array,int start,int end){
        if (start>=end){
            return;
        }
        int pivot=partitionHoare(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }

 private static int partitionHoare(int[]array,int left,int right){
        int tmp=array[left];
        int i=left;
        while (left<right){
            while (left<right&&array[right]>=tmp){
                right--;
            }
            while (left<right&&array[left]<=tmp){
                left++;
            }
            Swap(array,left,right);
        }
        Swap(array,i,left);
        return left;
    }

七、归并排序

归并排序的逻辑:

  将数组进行不断拆分,拆分到只有一个元素时,然后对元素进行有序的组合。

代码如下:

   public static void mergeSort(int[]array){
        mergeSortFun(array,0,array.length-1);
     }

    private static void mergeSortFun(int[] array, int start, int end) {
        if (start>=end){
            return;
        }
        int mid=(start+end)/2;
        mergeSortFun(array,start,mid);
        mergeSortFun(array,mid+1,end);

        merge(array,start,mid,end);

    }

    private static void merge(int[] array, int left, int mid, int right) {
        int s1=left;
        int e1=mid;
        int s2=mid+1;
        int e2=right;

        int[]tmpArr=new int[right-left+1];
        int k=0;

        while (s1<=e1&&s2<=e2){
            if (array[s1]<=array[s2]){
                tmpArr[k++]=array[s1++];
            }else {
                tmpArr[k++]=array[s2++];
            }
        }
        while (s1<=e1){
            tmpArr[k++]=array[s1++];
        }
        while (s2<=e2){
            tmpArr[k++]=array[s2++];
        }
        for (int i = 0; i < tmpArr.length; i++) {
            array[i+left]=tmpArr[i];
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值