排序算法

1、冒泡排序:
* i和i+1位置的数比较,如果nums[i]>nums[i+1],就交换
* 第一趟:i从0~N,i和i+1依次比较交换,最大值会出现在最后位置
* 第二趟:i从0~N-1,i和i+1依次比较交换,最大值会出现在倒数第二个位置
* ......
* 经过第N-1趟比较,最后的得到排好序的数组
*
* 时间复杂度为O(N^2)
* 稳定排序
public class BubbleSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1,3,2,7,4,2};
        bubbleSort(nums);
        for (int num: nums) {
            System.out.print(num);
        }
    }
    public static void bubbleSort(int[] nums){
        int isChange;//如果isChange == 0,这一趟没有进行交换,说明已经排好序了
        //外层循环控制需要排序的趟数
        for(int i=0; i<nums.length-1; i++){
            isChange = 0;
            for(int j=0; j<nums.length-i-1; j++){
                if(nums[j] > nums[j+1]){
                    swap(nums, j, j+1);
                    isChange = 1;
                }
            }
            if(isChange == 0){
                break;
            }
        }
    }
    public static void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

2、选择排序

选择排序:每一趟比较中都选出最大值,记录该最大值的位置,与最后一个元素交换
*
* 时间复杂度O(N^2)
* 不稳定排序
public class SelectSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1,3,2,7,4,2};
        selectSort(nums);
        for (int num: nums) {
            System.out.print(num+" ");
        }
    }
    public static void selectSort(int[] nums){
        int max;//最大值
        int pos;//最大值位置
        //外层循环控制排序的趟数,因为排序到最后,第一个元素就不需要交换了,所以i到nums.length-1;
        for(int i=0; i<nums.length-1; i++){
            max = nums[0];
            pos = 0;
            //每一趟比较,将第0个元素作为初始最大值,从第一个位置开始,直到最后一个元素寻找最大值
            for(int j=1; j<nums.length-i;j++){
                if(nums[j] > max){
                    max = nums[j];
                    pos = j;
                }
            }
            swap(nums, pos, nums.length-i-1);
        }
    }
    public static void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

3、插入排序

*插入排序:每次将当前元素插入到前面已经排好序的数组中
*
* 时间复杂度O(N^2):小样本情况下,排序很快,因为常数项很低
* 稳定排序
public class InsertSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1,3,2,7,4,2};
        selectSort(nums);
        for (int num: nums) {
            System.out.print(num+" ");
        }
    }
    public static void selectSort(int[] nums){
        for(int i=0; i<nums.length; i++){
            int j=i;
            while(j>0 && nums[j]<nums[j-1]){
                swap(nums, j, j-1);
                j--;
            }
        }
    }
    public static void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

4、归并排序

*归并排序:先分后合

* 时间复杂度O(NlogN)
* 稳定排序
public class MergeSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1,3,2,7,4,2};
        mergeSort(nums,0, nums.length-1);
        for (int i=0; i<nums.length; i++) {
            System.out.print(nums[i]+" ");
        }
    }
    public static void mergeSort(int[] nums, int start, int end){
        if(start < end){
            int mid = (start+end)/2;
            mergeSort(nums, start, mid);
            mergeSort(nums, mid+1, end);
            merge(nums, start, mid+1, end);
        }
    }
    public static void merge(int[] nums, int start, int mid, int end){
        int i=start;
        int j=mid;
        int k=0;
        int[] help = new int[end-start+1];
        while (i < mid && j <=end){
            if(nums[i] < nums[j]){
                help[k++] = nums[i++];
            }else{
                help[k++] = nums[j++];
            }
        }
        while(i < mid){
            help[k++] = nums[i++];
        }
        while(j <= end){
            help[k++] = nums[j++];
        }
        for(int t=0; t<help.length; t++){
            nums[start++] = help[t];
        }
    }
}

5、快排

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int[] arrays = new int[]{3,543,542,45,78,8};
        quickSort(arrays, 0, arrays.length-1);
        System.out.println(Arrays.toString(arrays));
    }
    public static void quickSort(int[] arrays, int l, int r){
        if(l<r){
            int[] qujian = partition(arrays, l, r);
            quickSort(arrays, l, qujian[0]-1);
            quickSort(arrays, qujian[1]+1, r);
        }
    }

    private static int[] partition(int[] arrays, int l, int r) {
        int less = l-1;
        int more = r;
        while(l < more){
            if(arrays[l] <arrays[r]){
                swap(arrays, ++less, l++);
            }else if(arrays[l] > arrays[r]){
                swap(arrays, l, --more);
            }else{
                l++;
            }
        }
        swap(arrays, more, r);
        return new int[]{less+1, more};
    }

    private static void swap(int[] arrays, int cur, int r) {
        int temp = arrays[cur];
        arrays[cur] = arrays[r];
        arrays[r] = temp;
    }
}

6、堆排

*树是一个逻辑结构,实际上为一个数组存储
第i位置的左孩子的位置为2*i+1
第i位置的右孩子的位置为2*i+2
第i位置的父亲的位置为(i-1)/2
heapInsert():首先将数据形成一个大根堆,从数组的第一个数开始依次寻找父节点的位置,如果比父节点的值大,则交换,直到没有大于该节点的值
heapify():如果一个大根堆,由于一些元素发生了变化,而需要重新整理成大根堆,这个时候用heapify()函数
在快排的过程中,每一次将堆顶最大元素跟数组中最后一个元素交换,下一次循环排除最后一个元素,
在交换之后,需要使用heapify()函数重新找现在根节点的左孩子和右孩子,找到三者中最大的那个值,与之交换,直到数组末尾
*
* 不稳定排序
* 时间复杂度为O(NlogN)
package sort;

public class HeapSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1,45,23,53,32,32,23};
        heapSort(nums);
        for (int n: nums){
            System.out.print(n+" ");
        }
    }
    public static void heapSort(int[] nums){
        if(nums==null || nums.length<2){
            return;
        }
        for (int i=1; i<nums.length; i++){
            heapInsert(nums, i);
        }
        int heapSize = nums.length;
        swap(nums, 0, --heapSize);

        while (heapSize>0){
            heapify(nums, heapSize);
            swap(nums, 0, --heapSize);
        }
    }
    public static void heapInsert(int[] nums, int i){
        if(nums[i]>nums[(i-1)/2]){
            swap(nums, i, (i-1)/2);
            i = (i-1)/2;
        }
    }
    public static void heapify(int[] nums, int heapSize){
        int i=0;
        int left = 2*i+1;
        int right = 2*i+2;
        while (left < heapSize){
            int largest = right< heapSize && nums[right]>nums[left] ? right:left;
            largest = nums[largest]>nums[i]?largest:i;
            if(largest == i){
                break;
            }
            swap(nums, largest, i);
            i=largest;
            left = 2*i+1;
            right = left+1;
        }
    }
    public static void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

7、桶排序(基数排序)

//时间复杂度为O(Nlog(r)M)
//r为基数、M为堆数
//不稳定排序
public class BasicSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1,3,2,7,4,2};
        basicSort(nums);
        for (int num: nums) {
            System.out.print(num);
        }
    }
    public static void basicSort(int[] nums){
        int[][] buckets = new int[nums.length][10];
        int max = getMax(nums);
        //获取每一位数字装到桶中
        for (int i=1; max/i>0; i=i*10){
            for(int j=0; j<nums.length; i++){
                int digit = nums[j]/10;
                buckets[j][digit] = nums[j];
            }
            //将桶中的数据回收,回收出来的数是按照当前装桶位置的元素顺序排列的
            int k = 0;
            for(int l=0; l<10; l++){
                for(int j=0; j<nums.length; j++){
                    if(buckets[j][l] != 0){
                        nums[k++] = buckets[j][l];
                    }
                }
            }
        }
    }
    public static int getMax(int[] nums){
        int max = nums[0];
        for(int i=1; i<nums.length; i++){
            max = Math.max(max, nums[i]);
        }
        return max;
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值