Java数据结构--排序

本文在技术沙龙中详细介绍了基础的排序算法,包括插入排序、冒泡排序、快速排序和选择排序的实现原理。重点解析了快速排序的分区操作,并通过示例说明了其工作过程。此外,还提到了归并排序,以及各种排序算法的时间和空间复杂度。
摘要由CSDN通过智能技术生成

最近实验室的技术沙龙开展起来了,我想着讲点基础的,讲讲最基本的排序算法吧。相比于画图讲思想,我更喜欢实现了的代码,所以我就根据代码写一下。(代码默认升序排列)


插入排序:

//插入排序
    public static void InsertSort(int[] num){
        if (num.length<=0) {   //判断数组是否为空
            return;
        }
        //插入排序的思想是:将选取的元素插入到有序序列,依次插入,直到所有元素有序
        for (int i = 1; i < num.length; i++) {
            int tmp = num[i];
            int j=i-1;
            while(num[j]>tmp){
                num[j+1]=num[j];  //如果比tmp大,则后移
                j--;
                if (j<0) {
                    break;
                }
            }

            num[j+1]=tmp;       //直到找到一个比tmp小或者到了起始点,将其插入
        }
    }

冒泡排序:

//冒泡排序
    public static void BubbleSort(int[] num) {
        if(num.length<=0) return;
        //冒泡排序的思想在于取其中一个元素与相邻元素比较,较大者上浮,直到最大的浮到底部
        boolean change = true; //此变量为优化算法的比较次数,当有一趟所有元素都未发生交换说明已有序
        for (int i = 0; i < num.length&&change; i++) {
            change = false;
            for (int j = 0; j < num.length-i-1; j++) {
                if(num[j]>num[j+1]){
                    int tmp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = tmp;
                    change = true;
                }
            }
        }
    }

快速排序:(由于比较重要,解释的清楚些)

快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。

举例说明一下吧,这个可能不是太好理解。假设要排序的序列为

2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移

2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置

2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面

2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变

经过第一轮的快速排序,元素变为下面的样子

[1] 2 [4 9 3 6 7 5]

之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束。右边进行快排,递归进行,最终生成最后的结果。

//快速排序
    public static void QuickSort(int[] num,int left,int right) {
        if(num.length<=0) return;
        //快拍是一种分治思想的排序,每次选取一个元素p,把序列分为两个部分,比p小的和比p大的,然后迭代
        //直到有序为止
        if(left<right) {
            int p = num[left];
            int low,high;
            low = left;
            high = right;
            while (low<high) {
                while (low<high&&num[high]>p) {
                    high--;
                }
                num[low] = num[high];
                while (low<high&&num[low]<p) {
                    low++;
                }
                num[high] = num[low];
            }
            num[low] = p;
            QuickSort(num, left, low-1);
            QuickSort(num, low+1, right);
        }
    }

选择排序:

//选择排序
    public static void SelectSort(int[] num) {
        if(num.length<=0) return;
        //选择排序是选取一个临时变量来记录每一躺的最大值,然后放在序列的尾端
        for(int i =0;i<num.length;i++){
            int x=num[i];
            int y=i;
            int j;
            for (j = i; j < num.length; j++) {
                if(num[j]<x){
                    x=num[j];
                    y=j;
                }
            }
            num[y]=num[i];
            num[i]=x;

        }
    }

归并排序:

//归并排序
    public static void MergeArray(int[] num,int left,int mid,int right) {
        int i=left,j=mid+1,k=0;
        int[] tmp = new int[right-left+1];
        while (i<=mid&&j<=right) {
            if (num[i]>num[j]) {
                tmp[k++] = num[j++];
            }
            else {
                tmp[k++] = num[i++];
            }
        }
        while (i<=mid) {
            tmp[k++] = num[i++];
        }
        while (j<=right) {
            tmp[k++] = num[j++];
        }
        int m=0;
        for (int l = left; l < right+1; l++) {
            num[l] = tmp[m++];
        }
    }
    public static void MergeSort(int[] num,int left,int right) {
        //归并排序的思想是将序列划分成两段,然后用递归,直到序列只有两个元素,然后将有序的序列进行合并
        if(left<right){
            int mid = (left+right)/2;
            MergeSort(num, left, mid);
            MergeSort(num, mid+1, right);
            MergeArray(num, left, mid, right);
        }
    }

下面是每种算法的时间复杂度和空间复杂度:
各种排序算法的属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值