排序算法实现【选择、插入、希尔、归并、快速、堆】

本文介绍了五种常见的排序算法:选择排序通过逐次选择最小元素放置首位;插入排序通过对比插入位置保持有序;希尔排序改进了插入排序的效率;归并排序采用分治思想递归合并子序列;快速排序通过一趟划分实现排序。每种算法的实现细节和核心原理都有所不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选择排序

每次遍历选择最小的往前排

    public int[] sort(int []a){
        for (int i = 0; i < a.length; i++) {
            int min = i;
            for (int j = i+1; j < a.length; j++) {
                if(sortMain.less(a[i],a[j])){
                    min = j;
                }
            }
            sortMain.exch(a,i,min);
        }
        return a;
    }


    //比较
    public boolean less(int a,int b){
        return a>b;
    }
    //交换
    public void exch(int []array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

插入排序

每次遍历与前面已经排好的有序排练进行对比,不断的交换,插入到合适的位置

    public void sort(int []a){
        int n = a.length;
        for (int i = 0; i < n; i++) {
            int tmp = a[i];
            for (int j = i-1; j >=0; j--) {
                if(a[j]>tmp){
                    a[j+1] = a[j];
                    a[j]=tmp;
                }else {
                    a[j+1] = tmp;
                    break;
                }
            }
        }
    }

希尔排序

插入排序的变种,增加希尔增量用于排成局部有序的状态(插入排序),最后增量为1时和插入排序时一样的,这样做减少了交换的次数。

    public int[] sort(int[] a) {
        int n = 1;
        int size = a.length;
        //希尔增量
        while (n > size / 3) {
            n = n * 3 + 1;
        }
        while (n >= 1) {
            for (int i = n; i < size; i++) {
                for (int j = i; j >= n && a[j] < a[j - n]; j -= n) {
                    int tmp = a[j];
                    a[j] = a[j - n];
                    a[j - n] = tmp;
                }
            }
            n /= 3;
        }
        return a;
    }

归并排序

根据start-end进行拆分,分别排序各个子序列,最后归并子序列完成排序

package leetcode.May;

/**
 * @description:
 * @author: qiangyuecheng
 * @date: 2022/5/24 18:26
 */
public class MergesSort {
    static SortMain sortMain = new SortMain();

    /**
     * 归并排序
    */
    public int []tmp;
    public int[] sort(int []a){
        int n = a.length;
        //临时数组
        tmp = new int[n];
        marges(a,0,n-1);
        return a;
    }

    /**
     * 递归
    */
    public void marges(int []a,int start,int end){
        if(start==end){
            return;
        }
        int mid = start+(end-start)/2;
        int l = start;
        int r = mid+1;
        marges(a,l,mid);
        marges(a,r,end);
        int index = start;
        for (int i = start; i <= end; i++) {
            if(r>end){
                tmp[index++] = a[l++];
            }else if(l>mid){
                tmp[index++]=a[r++];
            }else if(a[l]>a[r]){
                tmp[index++]=a[r++];
            }else {
                tmp[index++]=a[l++];
            }
        }
        for (int i = start; i <= end; i++) {
            a[i] = tmp[i];
        }
    }




    public static void main(String[] args) {
        MergesSort MergesSort = new MergesSort();
        int[] a = new int[]{2, 3, 1,4,7,5,10,9,6};
        sortMain.show(MergesSort.sort(a));
    }
}

快速排序

package leetcode.May;

/**
 * @description:
 * @author: qiangyuecheng
 * @date: 2022/5/20 15:03
 */
public class QuickSort {
    static SortMain sortMain = new SortMain();

    /**
     * 快速排序
     */
    public int[] quick(int[] a) {
        sort(a,0,a.length-1);
        return a;
    }
    public void sort(int []a,int start,int end){
        //边界条件
        if(start>=end){
            return;
        }
        int j = getJ(a,start,end);
        sort(a,start,j-1);
        sort(a,j+1,end);
    }

    public int getJ(int []a,int start,int end){
        int i = start;
        int j = end+1;
        int index = a[start];
        while (true){
            while (a[++i]<index){
                if(i==end){
                    break;
                }
            }
            while (a[--j]>index){
                if(j==start){
                    break;
                }
            }
            if(i>=j){
                break;
            }
            exch(a,i,j);
        }
        exch(a,start,j);
        return j;
    }

    public void exch(int []a,int i,int j){
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }




    public static void main(String[] args) {
        int[] a = new int[]{2, 3, 1, 4, 7, 5, 10, 9, 6,8};
        QuickSort quickSort = new QuickSort();
        sortMain.show(quickSort.quick(a));
    }
}

三向切分

package leetcode.May;

/**
 * @description:
 * @author: qiangyuecheng
 * @date: 2022/5/25 20:06
 */
public class QuickSortPro {
    static SortMain sortMain = new SortMain();

    /**
     * 快速排序 三向切分
     */
    public int[] quick(int[] a) {
        sort(a,0,a.length-1);
        return a;
    }
    public void sort(int[]a,int start,int end){
        if(start>=end){
            return;
        }
        int i = start;
        int j = start+1;
        int gt = end;
        int index = a[start];
        while (j<=gt){
            int cmp = a[j]>index?1:a[j]<index?-1:0;
            if(cmp<0){
                exch(a,i++,j++);
            }else if(cmp>0){
                exch(a,j,gt--);
            }else {
                j++;
            }
        }
        sort(a,start,i-1);
        sort(a,gt+1,end);
    }


    public void exch(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }




    public static void main(String[] args) {
        int[] a = new int[]{2, 3, 1, 4, 7, 5, 10, 9, 6};
        QuickSortPro quickSort = new QuickSortPro();
        sortMain.show(quickSort.quick(a));
    }
}

堆排序

堆排序的思路和优先队列是一样的,保证大根堆的父结点大于俩个子结点,主要分2部分组成

1、init初始化,把数组初始化为有序(符合大根堆规范)

2、下沉 把头结点与最后的结点交换,然后完成下沉操作保持堆有序

package leetcode.May;

/**
 * @description:
 * @author: qiangyuecheng
 * @date: 2022/5/27 13:24
 */
public class HeapsSort {
    static SortMain sortMain = new SortMain();

    public int[] sort(int a[]) {
        init(a);
        downSort(a, a.length - 1);
        return a;
    }

    /**
     * init
     */
    public void init(int a[]) {
        int n = a.length - 1;
        int size = n;
        //第一次标识 对第一次的n进行处理
        int bool = 0;
        while (n > 1) {
            if (n % 2 == 0 && bool == 0) {
                if (a[n] > a[n / 2]) {
                    exchange(a, n, n / 2);
                    down(a, n, size);
                }
            }
            if (bool == 1) {
                if (bool == 0) {
                    n -= 1;
                }
                int index = a[n] > a[n + 1] ? n : n + 1;
                if (a[index] > a[n / 2]) {
                    exchange(a, index, n / 2);
                    down(a, index, size);
                }
            }
            n = n - 2;
            bool = 1;

        }
    }

    /**
     * down sort
     */
    public void downSort(int[] a, int index) {
        while (index>1){
            exchange(a, 1, index);
            down(a, 1, --index);;
        }
    }


    /**
     * 下沉
     */
    public void down(int a[], int x, int n) {
        int i = x;
        //要对n进行判断,如果为偶数则最后只有一个,如果为奇数,则最后有俩个子节点
        while (2 * i <= n) {
            if (2 * i + 1 <= n) {
                int index = a[2 * i] > a[2 * i + 1] ? 2 * i : 2 * i + 1;
                if (a[i] < a[index]) {
                    exchange(a, i, index);
                }
                i = index;
            }else {
                if (a[i] < a[2*i]) {
                    exchange(a, i, 2*i);
                }
                i = 2*i;
            }
        }
    }


    /**
     * 交换
     */
    public void exchange(int a[], int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }

    public static void main(String[] args) {
        int[] a = new int[]{0, 2, 3, 1, 4, 7, 5, 10, 9, 6, 8};
        HeapsSort heapsSort = new HeapsSort();
        sortMain.show(heapsSort.sort(a));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值