java解决数据结构----排序问题-----Sorting problem

声明:基于比较的排序算法基本原理及实现为面试常考知识点,务必重视!

通过本篇文章可以掌握:

  • 掌握七大基于比较的排序算法基本原理及实现
  • 掌握排序算法的性能分析
  • 掌握 java 中的常用排序方法

文章目录:

1、排序

2、七种基于比较的排序

3、海量数据的排序问题

4、其他非基于比较的排序


1、排序

1.1、排序的概念

在这里插入图片描述

1.2、稳定性
对于稳定性的定义:

在这里插入图片描述

图解上述说法:

在这里插入图片描述

2、七种基于比较的排序

七种排序总览表:

在这里插入图片描述

2.1、 直接插入排序
①、整体思路及实现过程

在这里插入图片描述

②、直接插入排序代码:
 public static void insertSort(int[] arr){
        for (int i = 1; i < arr.length; i++) {
            int j = i - 1;
            int tmp = arr[i];
            for(; j >= 0; j--){
                if(arr[j] > tmp){
                    arr[j + 1]= arr[j];
                }else{
                    break;
                }
            }
            arr[j+1] = tmp;
        }
    }
③、直接插入排序结果:

在这里插入图片描述

④、性能分析

在这里插入图片描述

⑤、使用场景:

在这里插入图片描述

2.2、 希尔排序
①、整体思路及实现过程

在这里插入图片描述

②、希尔排序代码:
private static void shell(int gap,int[] arr){
        for (int i = gap; i < arr.length; i++) {
            int tmp = arr[i];
            int j = i - gap;
            for (; j >= 0; j = j - gap) {
                if(arr[j] > tmp){
                    arr[j+gap] = arr[j];
                }else{
                    break;
                }
            }
            arr[j+gap] = tmp;
        }
    }
    public static void shellSort(int[] arr){
        int gap = arr.length/2;
        while(gap > 1){
            shell(gap,arr);
            gap = gap / 2;
        }
        shell(1,arr);
    }
③、希尔排序结果:

在这里插入图片描述

④、性能分析

在这里插入图片描述

2.3、 选择排序
①、整体思路及实现过程

在这里插入图片描述

②、选择排序代码:
public static void selectSort(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i] > arr[j]){
                    swap(i,j,arr);
                }
            }
        }
    }
    //优化
    public static void selectSort1(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for (int j = i+1; j < arr.length; j++) {
                if(arr[minIndex] > arr[j]){
                    minIndex = j;
                }
            }
            swap(i,minIndex,arr);
        }
    }
③、性能分析

在这里插入图片描述

2.4、 堆排序
①、整体思路及实现过程

在这里插入图片描述

②、堆排序代码:
private static void shiftDown(int parent, int len,int[] arr){
        int child = 2*parent + 1;
        while(child < len){
            if(child + 1 < len && arr[child] < arr[child+1]){
                child = child + 1;
            }
            if(arr[child] > arr[parent]){
                swap(parent,child,arr);
                parent = child;
                child = 2 * parent + 1;
            }else{
                break;
            }
        }
    }
    public static void heapSort(int[] arr){
        for (int parent = (arr.length - 1 - 1) / 2; parent >= 0 ; parent--) {
            shiftDown(parent,arr.length,arr);
        }
        int end = arr.length - 1;
        while(end != 0){
            swap(0,end,arr);
            shiftDown(0,end,arr);
            end--;
        }
    }
③、性能分析

在这里插入图片描述

2.5、 冒泡排序

①、冒泡排序过于简单直接展示代码:

public static void bubbleSort(int[] arr){
        for (int i = 1; i < arr.length; i++) {
            boolean flg = false;
            for (int j = 0; j < arr.length - i - 1; j++) {
                if(arr[j+1] < arr[j]){
                    swap(j+1,j,arr);
                }
                flg = true;
            }
            if(!flg){
                break;
            }
        }
    }

②、性能分析:

在这里插入图片描述

2.6、 快速排序
①、整体思路及实现过程

基准选取方法:选取边上法
在这里插入图片描述
基准选取法:三数取中法

在这里插入图片描述
这里只展示三数取中的快速排序代码,取边法去掉三数寻找中间值和交换的步骤即可

private static int partion(int[] arr,int start,int end){
        int tmp = arr[start];
        while(start < end){
            while(start < end && arr[end] > tmp){
                end--;
            }
            arr[start] = arr[end];
            while(start < end && arr[start] < tmp){
                start++;
            }
            arr[end] = arr[start];
        }
        arr[end] = tmp;
        return end;
    }
    private static int midValueSearch(int[] arr,int start,int end){
        int mid = start + ((end - start) >>> 1);
        if(arr[start] < arr[end]){
            if(arr[mid] < arr[start]){
                return start;
            }else if(arr[mid] > arr[end]){
                return end;
            }else{
                return mid;
            }
        }else{
            if(arr[mid] < arr[end]){
                return end;
            }else if(arr[mid] > arr[start]){
                return start;
            }else{
                return mid;
            }
        }
    }
    private static void quick(int[] arr,int left,int right){
        if(left >= right){
            return;
        }
        int midValue = midValueSearch(arr,left,right);
        swap(left,midValue,arr);
        int pivot = partion(arr,left,right);
        quick(arr,left,pivot-1);
        quick(arr,pivot+1,right);
    }
    public static void quickSort(int[] arr){
        quick(arr,0,arr.length-1);
    }

上面的快速排序是使用递归方法实现的,那么非递归可以怎样去实现快速排序呢?

快速排序的非递归算法:
在这里插入图片描述

public static void quickSort1(int[] arr){
        Stack<Integer> stack = new Stack<>();
        int left = 0;
        int right = arr.length - 1;
        int pivot = partion(arr,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 = partion(arr,left,right);
            if(pivot > left + 1){
                stack.push(left);
                stack.push(pivot - 1);
            }
            if(pivot < right - 1){
                stack.push(pivot + 1);
                stack.push(right);
            }
        }
    }

②、性能分析:
在这里插入图片描述

2.7、归并排序
①、整体思路及实现过程

在这里插入图片描述

private static void mergeSortInter(int[] arr,int low,int high){
        if(low >= high){
            return;
        }
        int mid = low + ((high - low) >>> 1);
        mergeSortInter(arr,low,mid);
        mergeSortInter(arr,mid + 1,high);
        merge(arr,low,mid,high);
    }
    private static void merge(int[] arr,int low,int mid,int high){
        int[] tmp = new int[high - low + 1];
        int s1 = low;
        int e1 = mid;
        int s2 = mid + 1;
        int e2 = high;
        int i = 0;
        while(s1 <= e1 && s2 <= e2){
            if(arr[s1] <= arr[s2]){
                tmp[i++] = arr[s1++];
            }else{
                tmp[i++] = arr[s2++];
            }
        }
        while(s1 <= e1){
            tmp[i++] = arr[s1++];
        }
        while(s2 <= e2){
            tmp[i++] = arr[s2++];
        }
        for (int j = 0; j < i; j++) {
            arr[j+low] = tmp[j];
        }
    }
    public static void mergeSort(int[] arr){
        mergeSortInter(arr,0,arr.length-1);
    }

上面的代码是递归实现的,那么非递归又是怎样实现归并排序的呢?
在这里插入图片描述

public static void mergeSort1(int[] arr){
        int nums = 1;
        while(nums < arr.length){
            for (int i = 0; i < arr.length; i+=nums*2) {
                 int left = i;
                 int mid = left + nums - 1;
                 if(mid >= arr.length){
                     mid = arr.length - 1;
                 }
                 int right = mid + nums;
                 if(right >= arr.length){
                     right = arr.length - 1;
                 }
                 merge(arr,left,mid,right);
            }
            nums = nums * 2;
        }
    }

②、性能分析:
在这里插入图片描述

3、海量数据的排序问题

在这里插入图片描述

4、其他非基于比较的排序

这三个排序了解即可,附上链接,依照自身情况学习,博主只挑选了计数排序进行编写

4.1、基数排序

基数排序

4.2、计数排序

计数排序
在这里插入图片描述

public static void countingSort(int[] arr){
        int minVal = arr[0];
        int maxVal = arr[0];
        for (int j : arr) {
            if (j > maxVal) {
                maxVal = j;
            }
            if (j < minVal) {
                minVal = j;
            }
        }
        int[] count = new int[maxVal - minVal + 1];
        for (int j : arr) {
            count[j-minVal]++;
        }
        int index = 0;
        for (int i = 0; i < count.length; i++) {
            while(count[i] > 0){
                arr[index] = i + minVal;
                index++;
                count[i]--;
            }
        }
    }
4.3、桶排序

桶排序

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦の澜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值