常见排序(java实现)

插入排序

图解

在这里插入图片描述

代码实现

public class TestDemo {

    public static void main(String[] args) {
        int[] array = {5,4,3,2,1};  //定义数组
        insertSort(array);
        System.out.println(Arrays.toString(array));
    }

    public static void insertSort(int[] array){ 
        for (int i = 1; i < array.length; i++) {
            int j = i - 1; //
            int tmp = array[i]; // 记录i下标的值
            for(;j >= 0;j--){  //从j位置往后遍历,
                if(array[j] > tmp){
                    array[j + 1] = array[j]; //大的放到前面
                }else{
                    break;
                }
            }
            array[j + 1] = tmp;//最后最小的给放到前面,(j一直在减减)
        }
    }
}

在这里插入图片描述

希尔排序

图解

在这里插入图片描述

代码实现

public class ShellSort {

    public static void main(String[] args) {
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        shellSort(array);
        System.out.println(Arrays.toString(array));
    }

    public static void shell(int[] array,int gap){
        for (int i = gap; i < array.length; i++) {  //先按分组排
            int j = i - gap;
            int tmp = array[i]; //记录i下标值
            for(;j >= 0;j -= gap){
                if(array[j] > tmp){
                    array[j + gap] = array[j]; //交换
                }else{
                    break;
                }
            }
            array[j + gap] = tmp; //还回去
        }
    }


    public static void shellSort(int[] array){
        int gap = array.length; //分组
        while(gap > 1){ //这里是循环条件
            shell(array,gap);
            gap /= 2;
        }
        shell(array,1); //最后就是分成一组最后的排序
    }
}

在这里插入图片描述

选择排序

图解

在这里插入图片描述

代码实现

public class SelectSort {

    public static void main(String[] args) {
        int[] array = {1,4,12,6,7};
        selectSort(array);
        System.out.println(Arrays.toString(array));
    }

    public static void selectSort(int[] array){
        for (int i = 0; i < array.length; i++) {
            int min = i;  //记录最小的值下标
            for (int j = i+1; j < array.length; j++) {
                if(array[j] < array[min]){  //比较当前下标值得大小
                    min = j;
                }
            }
            swap(array,i,min);   //交换最小值在前面去
        }
    }

    private static void swap(int[] array, int a, int b) {   //交换函数
        int tmp = array[a];
       array[a] = array[b];
       array[b] = tmp;
    }
}

在这里插入图片描述

冒泡排序

图解

在这里插入图片描述

代码实现

public class MaoPaoSort {
    public static void main(String[] args) {
        int[] array = {6,12,10,3,5};
        bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }

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


    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            boolean flg = false;  //优化,
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j] > array[j+1]) {
                    swap(array,j+1,j);
                    flg = true; //说明这里进入了交换语句,把flg改成true
                }
            }
            if(flg == false) {  //说明这里并没有进入交换语句,说明这个数组已经有序了,直接返回
                break;
            }
        }
    }

}

堆排

图解

在这里插入图片描述详情见代码

代码实现

public class HeapSort {

    public static void main(String[] args) {
        int[] array = {27,15,19,18,28,34,65,49,25,37};
        heapSort(array);
        System.out.println(Arrays.toString(array));
    }

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

    public static void heapSort(int[] array) {
        //1、建堆  O(N)
        createHeap(array);
        int end = array.length-1;
        //2、交换然后调整 O(N * log N)
        while (end > 0) {
            swap(array,0,end);
            shiftDown(array,0,end);
            end--;
        }
    }

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

    public static void shiftDown(int[] array,int parent,int len) {  //大根堆
        int child = 2*parent+1;//左孩子下标
        while (child < len) {
            if(child+1 < len && array[child] < array[child+1]) {
                child++;
            }
            //child下标 就是左右孩子最大值的下标
            if(array[child] > array[parent]) {
                swap(array,child,parent);
                parent = child;
                child = 2*parent+1;
            }else {
                break;
            }
        }
    }

}

在这里插入图片描述

快排

图解

在这里插入图片描述

代码实现(挖坑法)

public class QuickSort {

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

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

    public static void quick(int[] array,int left,int right){ //递归

        if(left >= right){  //递归结束条件
            return;
        }
        int pivot = partition(array,left,right);  //基准值
        quick(array,left,pivot - 1);  //递归左边的
        quick(array,pivot + 1,right);  //递归右边的
    }

    public static int partition(int[] array,int start,int end){  //基准值
        int tmp = array[start];  //让开始下标放到tmp中
        while(start < end){  //循环条件
            if(start < end && array[end] >= tmp){   //start < end是大前提,所以又要写一遍
                end--;
            }
            array[start] = array[end];  //放到前面
            if(start < end && array[start] <= tmp){
                start++;
            }
            array[end] = array[start]; //放到后面
        }
        array[start] = tmp; //放回tmp值
        return start;  //返回下标(基准值)
    }
}

在这里插入图片描述
优化一下这个代码,我们这样一直找第一个并不确定这个数是大是小,我们用三数取中法找到中间值与start交换后再快排.详情见代码

快排优化(三数取中法)

public class QuickSort {

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

    public static void swap(int[] array,int a,int b){
        int tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }

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

    public static void quick(int[] array,int left,int right){ //递归

        if(left >= right){  //递归结束条件
            return;
        }

        //1、找基准之前,我们找到中间大小的值-使用三数取中法
        int midValIndex = findMidValIndex(array,left,right);  //这样有可能大大提升了代码的效率
        swap(array,midValIndex,left);

        int pivot = partition(array,left,right);  //基准值
        quick(array,left,pivot - 1);  //递归左边的
        quick(array,pivot + 1,right);  //递归右边的
    }

    private static int findMidValIndex(int[] array,int start,int end) {  //找到这三个数的中间值
        int mid = start + ((end-start) >>> 1);  //(start + end) / 2;
        if(array[start] < array[end]) {
            if(array[mid] < array[start]) {
                return start;
            }else if(array[mid] > array[end]) {
                return end;
            }else {
                return mid;
            }
        }else {
            if(array[mid] > array[start]) {
                return start;
            }else if(array[mid] < array[end]) {
                return end;
            }else {
                return mid;
            }
        }
    }


    public static int partition(int[] array,int start,int end){  //基准值
        int tmp = array[start];  //让开始下标放到tmp中
        while(start < end){  //循环条件
            if(start < end && array[end] >= tmp){   //start < end是大前提,所以又要写一遍
                end--;
            }
            array[start] = array[end];  //放到前面
            if(start < end && array[start] <= tmp){
                start++;
            }
            array[end] = array[start]; //放到后面
        }
        array[start] = tmp; //放回tmp值
        return start;  //返回下标(基准值)
    }
}

非递归实现

在这里插入图片描述

public class Demo1 {

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

    public static void quickSort(int[] array) {
        Stack<Integer> stack = new Stack<>();
        int left = 0;
        int right = array.length - 1;
        int pivot = partiton(array, left, right); //基准值
        if (pivot > left + 1) {   //左边是不是只有一个了
            stack.push(left);
            stack.push(pivot - 1);
        }
        if (pivot < right - 1) {
            stack.push(pivot + 1);
            stack.push(right);
        }
        while (!stack.isEmpty()) {
            right = stack.pop();  //新的右下标
            left = stack.pop();  //新的左下标
            pivot = partiton(array, left, right); //新的基准值
            if (pivot > left + 1) {
                stack.push(left);
                stack.push(pivot - 1);
            }
            if (pivot < right - 1) {
                stack.push(pivot + 1);
                stack.push(right);
            }
        }
    }

    public static int partiton(int[] array, int start, int end) {
        int tmp = array[start];
        while (start < end) {
            while (start < end && array[end] >= tmp) {
                end--;
            }
            array[start] = array[end];
            while (start < end && array[start] <= tmp) {
                start++;
            }
            array[end] = array[start];
        }
        array[start] = tmp;
        return start;
    }

}

在这里插入图片描述

归并排序

在这里插入图片描述

代码实现

import java.util.Arrays;

public class Demo4 {
    /*
     * 时间复杂度:N * log2 N
     * 空间复杂丢:O(N)
     * 稳定性:稳定
     * */
    public static int[] mergeSort(int[] array){
        if(array == null){
            return array;
        }
        mergeSortFunc(array,0,array.length-1);
        return array;
    }
    private static void mergeSortFunc(int[] array,int low,int high){
        if(low >= high){
            return;
        }
//       int mid = (high + low) >>> 1
        int mid = low + ((high - low) >>> 1);
        mergeSortFunc(array,low,mid);// 左边
        mergeSortFunc(array,mid+1,high);// 右边
        merge(array,low,mid,high);
    }

    private static void merge(int[] array,int low,int mid,int high){
        int[] arr = new int[high - low +1];
        int start1 = low;
        int end1 = mid;
        int start2 = mid+1;
        int end2 = high;
        int i = 0;
        while (start1 <= end1 && start2 <= end2){
            if(array[start1] > array[start2]){
                arr[i++] = array[start2++];
            }else{
                arr[i++] = array[start1++];
            }
        }
        while(start1 <= end1){
            arr[i++] = array[start1++];
        }
        while(start2 <= end2){
            arr[i++] = array[start2++];
        }
        for (int j = 0; j < arr.length; j++) {
            array[low++] = arr[j];
        }
    }

    public static void main(String[] args) {
        int[] array = {1,6,7,10,2,3,4,9};
        mergeSort(array);
        System.out.println(Arrays.toString(array));
    }
}

在这里插入图片描述

非递归

import java.util.Arrays;

public class MergeSortNonRecursion {
    public static void mergeSort(int[] array){
        //归并排序非递归实现
        int groupNum = 1;// 每组的数据个数
        while(groupNum < array.length){
            // 无论数组含有几个元素, 数组每次都需要从下标 0位置,开始遍历。
            for(int i = 0;i<array.length;i+= groupNum * 2){
                int low = i;
                int mid = low + groupNum -1;

                // 防止越界【每组的元素个数,超过了数组的长度】
                if(mid >= array.length){
                    mid = array.length-1;
                }
                int high = mid + groupNum;

                // 防止越界【超过了数组的长度】
                if(high >= array.length){
                    high = array.length-1;
                }
                merge(array,low,mid,high);
            }
            groupNum *= 2;//每组的元素个数扩大到原先的两倍。
        }
    }
    public static void merge(int[] array,int low,int mid,int high){
    // high 与 mid 相遇,说明 此时数组分组只有一组,也就说没有另一组的数组与其合并
    // 即数组已经有序了,程序不用再往下走。
         if(high == mid){
            return;
        }
        int[] arr = new int[high -low + 1];
        int start1 = low;
        int end1 = mid;
        int start2 = mid+1;
        int end2 = high;
        int i = 0;
        while(start1 <= end1 && start2 <= end2){
            if(array[start1]>array[start2]){
                arr[i++] = array[start2++];
            }else{
                arr[i++] = array[start1++];
            }
        }
        while (start1 <= end1){
            arr[i++] = array[start1++];
        }
        while(start2 <= end2){
            arr[i++] = array[start2++];
        }
        for (int j = 0; j < arr.length; j++) {
            array[low++] = arr[j];
        }
    }

    public static void main(String[] args) {
        int[] array = {12,5,8,7,3,4,1,10};
        mergeSort(array);
        System.out.println(Arrays.toString(array));
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

粉色的志明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值