【数据结构与算法】浅析八大排序

选择排序

最佳情况:T(n) = O(n2) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)

把第一位和其他所有的进行比较,只要比第一位小的,就换到第一个位置来 比较完后,第一位就是最小的 然后再从第二位和剩余的其他所有进行比较,只要比第二位小,就换到第二个位置来 比较完后,第二位就是第二小的

public class 选择排序 {
    public static void main(String[] args) {
        int a [] = new int[]{18,62,68,68,65,9,80};
​
        for(int i=0;i<a.length-1;i++){
        for(int j=i+1;j<a.length;j++){
            if(a[i]>a[j]){
                int temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
    }
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
        System.out.println(" ");
​
    }

冒泡排序

最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)

冒泡法排序的思路: 第一步:从第一位开始,把相邻两位进行比较 如果发现前面的比后面的大,就把大的数据交换在后面,循环比较完毕后,最后一位就是最大的 第二步: 再来一次,只不过不用比较最后一位 以此类推

public class 冒泡排序 {
    public static void main(String[] args) {
        int a[] = new int[]{18, 62, 68, 68, 65, 9, 80};
​
        for(int i=0;i< a.length;i++){
            for(int j=0;j<a.length-i-1;j++){
                if(a[j]>a[j+1]){
                    int temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                }
            }
        }
        for (int i:a) {
            System.out.print(i + " ");
        }
        System.out.println(" ");
    }
}

快速排序

时间复杂度:**最佳情况:T(n) = O(nlogn) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(nlogn)**

空间复杂度:最好情况:O(logn) 最差情况O(n)

快速排序是一种基于“分而治之(divide-and-conquer)”策略的排序算法。分而治之的策略为递归地将一个对象集合分为两个或两个以上的子集,直到每个子集上的问题规模都变得非常简单,可以直接进行求解为止。在快速排序中,算法会先从数据集中挑出一个元素,该元素被称为基准(pivot),然后将所有小于该基准的元素移动至基准之前,将所有大于该基准的元素移动至基准之后,用这种方式来进行排序。将元素移动至基准之前或之后的操作是整个快速排序算法中的主要组件,称为分区(partition)。分区操作会递归地在不断缩小的子集上重复执行,直到每个子集中只含有0到1个元素,从而完成整个集合的排序。

(从数组右边开始)

1.选择一个比较值c,以数组的第一个为例。 2.从右边开始查找比c小的值,再从左边开始查找比c大的值,进行互换。 3.当左边和右边同时指向一个值v(比c小,因为是从右边开始递减的),会退出当前循环。 4.交换c和v的值,返回v所在的地址。 5.递归,以此类推

public class QuickSort {
    public static void quickSort(int[] arr,int low,int high){
        int i,j,temp,t;
        if(low>high){
            return;
        }
        i=low;
        j=high;
        //temp就是基准位
        temp = arr[low];
 
        while (i<j) {
            //先看右边,依次往左递减
            while (temp<=arr[j]&&i<j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp>=arr[i]&&i<j) {
                i++;
            }
            //如果满足条件则交换
            if (i<j) {
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
 
        }
        //最后将基准为与i和j相等位置的数字交换
         arr[low] = arr[i];
         arr[i] = temp;
        //递归调用左半数组
        quickSort(arr, low, j-1);
        //递归调用右半数组
        quickSort(arr, j+1, high);
    }
 
 
    public static void main(String[] args){
        int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
        quickSort(arr, 0, arr.length-1);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

插入排序

时间复杂度:最佳情况:T(n) = O(n) 最坏情况:T(n) = O(n2) 平均情况:T(n) = O(n2) 空间复杂度:O(1)

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

原文链接:十大经典排序算法总结(Java实现+动画)_meibenxiang的博客-优快云博客_java排序算法

package leet;
​
import java.util.Arrays;
​
public class 插入排序 {
    public static void main(String[] args) {
        int[] nums=new int[]{2,4,3,6,1,8,5};
        System.out.println("-------------排序前--------------");
        System.out.println(Arrays.toString(nums));
        for(int i=1;i<nums.length;i++){
            for(int j=i-1;j>-1;j--){
                if(nums[j]>nums[j+1]){
                    int temp=nums[j+1];
                    nums[j+1]=nums[j];
                    nums[j]=temp;
                }
            }
        }
        System.out.println("-------------排序后--------------");
        System.out.println(Arrays.toString(nums));
    }
}
 

希尔排序

最佳情况:T(n) = O(nlog2 n) 最坏情况:T(n) = O(nlog2 n) 平均情况:T(n) =O(nlog2n) 

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

希尔排序是把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

原文链接:十大经典排序算法总结(Java实现+动画)_meibenxiang的博客-优快云博客_java排序算法

public class 希尔排序 {
    public static void sort(int[] nums) {
​
        int flag=nums.length/2;
        while(flag!=0){
            for(int i=flag;i<nums.length;i++){
                int temp =nums[i];
                int index = i-flag;
​
                while(index>=0 &&nums[index]>=temp){
                    nums[index+flag]=nums[index];
                    index=index-flag;
                }
                index=index+flag;
                nums[index]=temp;
            }
            flag/=2;
        }
        System.out.println("-------------排序后--------------");
        System.out.println(Arrays.toString(nums));
    }
​
    public static void main(String[] args) {
        int[] nums = new int[]{5,2,8,7,1,4};
        System.out.println("----------排序前-----------");
        System.out.println(Arrays.toString(nums));
        System.out.println("----------排序后-----------");
        sort(nums);
    }
​
}

无图:java实现八大经典排序(冒泡、选择、插入、归并、快速排序、堆排序、希尔排序、桶排序)_爱玲姐姐的博客-优快云博客

有图:十大经典排序算法总结(Java实现+动画)_meibenxiang的博客-优快云博客_java排序算法

归并排序

最佳情况:T(n) = O(n) 最差情况:T(n) = O(nlogn) 平均情况:T(n) = O(nlogn)

归并排序就是利用归并的思想实现的排序方法。而且充分利用了完全二叉树的深度是log2n的特性,因此效率比较高。其基本原理如下:对于给定的一组记录,利用递归与分治技术将数据序列划分成为越来越小的半子表,在对半子表排序,最后再用递归方法将排好序的半子表合并成为越来越大的有序序列。 经过第一轮比较后得到最小的记录,然后将该记录的位置与第一个记录的位置交换;接着对不包括第一个记录以外的其他记录进行第二次比较,得到最小记录并与第二个位置记录交换;重复该过程,

原文链接:【排序算法】归并排序原理及Java实现_简约人生的博客-优快云博客_归并排序原理

这里写图片描述

public class MergeSort {
​
    public static void merge(int[] a, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;// 左指针
        int j = mid + 1;// 右指针
        int k = 0;
        // 把较小的数先移到新数组中
        while (i <= mid && j <= high) {
            if (a[i] < a[j]) {
                temp[k++] = a[i++];
            } else {
                temp[k++] = a[j++];
            }
        }
        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = a[i++];
        }
        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = a[j++];
        }
        // 把新数组中的数覆盖nums数组
        for (int k2 = 0; k2 < temp.length; k2++) {
            a[k2 + low] = temp[k2];
        }
    }
​
    public static void mergeSort(int[] a, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            // 左边
            mergeSort(a, low, mid);
            // 右边
            mergeSort(a, mid + 1, high);
            // 左右归并
            merge(a, low, mid, high);
            System.out.println(Arrays.toString(a));
        }
​
    }
​
    public static void main(String[] args) {
        int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
        mergeSort(a, 0, a.length - 1);
        System.out.println("排序结果:" + Arrays.toString(a));
    }
}

堆排序

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小树ぅ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值