一篇博客解决常见的排序

排序

冒泡排序

在这里插入图片描述

遍历n次数组,如果当前数比后一个数大则将当前
数与后一个数交换位置,每遍历一次可排好一个数
的位置,直到n次,时间复杂度为O(N2),排序满足稳定性

public class BubbleSort {
    public int[] bubbleSort(int[] ints){
        for (int i = 0; i < ints.length; i++) {
            for (int j = 1; j < ints.length-i; j++) {
                int tmp = ints[j];
                if (ints[j]<ints[j-1]){
                    ints[j] = ints[j-1];
                    ints[j-1] = tmp;
                }
            }
        }
        return ints;
    }

    public static void main(String[] args) {
        int[] ints = {2,5,5};
        new BubbleSort().bubbleSort(ints);
        for (int i = 0; i < ints.length; i++) {
            System.out.println(ints[i]);
        }
    }
}

选择排序

在这里插入图片描述

遍历数组,每一次遍历都会从当前位置之后寻找最小的数,并记录最小数的位置,然后将当前值和最小值交换,完整遍历后可以得到一个顺序列表,时间复杂度为O(N2),排序满足稳定性

public class SelectionSort {
    public int[] selectionSort(int[] ints){
        for (int i = 0; i < ints.length; i++) {
            int first = ints[i];
            int tmp = first;
            int index = i;
            for (int j = i+1; j < ints.length; j++) {
                if (ints[j]<tmp){
                    tmp = ints[j];
                    index = j;
                }
            }
            ints[i] = ints[index];
            ints[index] = first;
        }
        return ints;
    }

    public static void main(String[] args) {
        int[] ints = {8,6,9,0,8,3,5,7,7};
        new SelectionSort().selectionSort(ints);
        for (int i = 0; i < ints.length; i++) {
            System.out.println(ints[i]);
        }
    }
}

快速排序

在这里插入图片描述

每次排序前先选择一个基准数,然后把比基准数小的放左边,比基准书大的放右边,具体方法是用两个指针,一个从左到右,一个从右到左,左指针找到比基准数大的数时,将左指针的数和右指针的数交换,然后右指针开始向左找比基准书小的数,找到后和左指针的数交换,直到两个指针相遇,此时数组被分成两个区域,再对这两个区域进行快排递归,直到所有数都排好为止
时间复杂度为O(nlogn),在最坏的情况下为O(N2),且不能保证稳定性

public class QuickSort {
    public int[] quickSort(int[] ints,int left,int right){
        if (left<right){
            int baseNum = ints[left];
            int l = left;
            int r = right;
            while (l<r){
                while (ints[r]>=baseNum&&l<r){
                    r--;
                }
                if (l<r){
                    ints[l] = ints[r];
                }
                while (ints[l]<=baseNum&&l<r){
                    l++;
                }
                if (l<r){
                    ints[r] = ints[l];
                }
            }
            ints[l] = baseNum;
            quickSort(ints,left, r-1);
            quickSort(ints,l+1,right);
        }
        return ints;
    }

    public static void main(String[] args) {
        int[] ints = {2,5,5};
        new QuickSort().quickSort(ints,0,ints.length-1);
        for (int i = 0; i < ints.length; i++) {
            System.out.println(ints[i]);
        }
    }
}

归并排序

在这里插入图片描述

分治的思想,先将整个数组一分为二,再二分为四…直到分成一个部分只有一个元素为止,这是分的思想。将分出来的部分合并为一个有序的部分,两个已经排好序的部分合并就比较容易了,每一次只需要比较头元素的大小,然后选择小的那个加入到中间数组里即可,用递归的方法可以很好的实现这个思想
时间复杂度稳定为O(nlogn),并且能保证稳定性

public class MergeSort {
    public void sort(int[] ints,int left, int right){
        int[] tmp = new int[ints.length];
        if (left<right){
            int mid = (left+right)/2;
            sort(ints,left,mid);
            sort(ints,mid+1,right);
            merge(ints,left,mid,right,tmp);
        }
    }
    private void merge(int[] ints,int left,int mid,int right,int[] tmp){
        int l = left;
        int r = mid+1;
        int index = 0;
        while (l<=mid||r<=right){
            if (l>mid){
                tmp[index++] = ints[r++];
                continue;
            }
            if (r>right){
                tmp[index++] = ints[l++];
                continue;
            }
            if (ints[l]<ints[r]){
                tmp[index++] = ints[l++];
            }
            else {
                tmp[index++] = ints[r++];
            }
        }
        index = 0;
        for (int i = left; i <= right; i++) {
            ints[i] = tmp[index++];
        }
    }

    public static void main(String[] args) {
        int[] ints = {8,6,9,0,8,3,5,7,7};
        new MergeSort().sort(ints,0,ints.length-1);
        for (int i = 0; i < ints.length; i++) {
            System.out.println(ints[i]);
        }
    }
}

堆排序

在这里插入图片描述

将数据重新排列成一个最小堆,即每个结点的父节点都小于其子结点,这样顶部的元素一定是当前堆的最小值,将顶部元素取出并将叶子结点放置到顶部元素,这样操作后可能会破坏最小堆的结构,所以此时需要重新生成最小堆,这样又可以得出这个堆的最小值,这样重复操作,直到所有数都被取出
时间复杂度稳定为O(nlogn),并且保证稳定性

public class HeapSort {
    public void heapSort(int[] ints){
        //形成最小堆
        for (int i = ints.length-1; i > 0;) {
            //只有一个子结点且为左子结点
            if (i%2!=0){
                int father = i/2;
                if (ints[father]>ints[i]){
                    int tmp = ints[father];
                    ints[father] = ints[i];
                    ints[i] = tmp;
                }
                i--;
            }
            else {
                int father = (i-1)/2;
                int small = ints[i]<ints[i-1]?ints[i]:ints[i-1];
                int smallIndex = ints[i]<ints[i-1]?i:i-1;
                if (small<ints[father]){
                    int tmp = ints[father];
                    ints[father] = ints[smallIndex];
                    ints[smallIndex] = tmp;
                    arrange(ints,smallIndex, ints.length);
                }
                i-=2;
            }
        }
        int lastIndex = ints.length-1;
        for (int i = 0; i < ints.length; i++) {
            int tmp = ints[lastIndex];
            ints[lastIndex--] = ints[0];
            ints[0] = tmp;
            arrange(ints,0,lastIndex+1);
        }
    }
    private void arrange(int[] ints,int index,int intsLength){
        int leftChildIndex;
        int rightChildIndex;
        //判断有无左子节点
        if (index*2+1<intsLength){
            leftChildIndex = index*2+1;
            //有两个结点的情况
            if ((index+1)*2<intsLength){
                rightChildIndex = (index+1)*2;
                int small = ints[leftChildIndex]<ints[rightChildIndex]?ints[leftChildIndex]:ints[rightChildIndex];
                int smallIndex = ints[leftChildIndex]<ints[rightChildIndex]?leftChildIndex:rightChildIndex;
                if (small<ints[index]){
                    int tmp = ints[index];
                    ints[index] = ints[smallIndex];
                    ints[smallIndex] = tmp;
                }
                arrange(ints,smallIndex,intsLength);
            }
            //只有一个子节点的情况
            else {
                if (ints[leftChildIndex]<ints[index]){
                    int tmp = ints[index];
                    ints[index] = ints[leftChildIndex];
                    ints[leftChildIndex] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {
        int[] ints = {1,2,3,4,5,6,7,8,9,10,11};
        new HeapSort().heapSort(ints);
        for (int i = 0; i < ints.length; i++) {
            System.out.println(ints[i]);
        }
    }
}

更多内容

更多内容请看我的个人网站,新建网站,目前内容较少,敬请期待

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值