java排序算法 —— 冒泡排序和快速排序的代码实现

时间复杂度:一个算法执行所耗费的时间

空间复杂度:运行完一个程序所需内存的大小

其中,稳定和不稳定是针对数组中有相同元素而说的

(1)稳定:如果a原本在b的前面,而且a=b,排序之后a仍然在b的前面

(2)不稳定:如果a原本在b的前面,而且a=b,排序之后a可能会出现在b的后面

冒泡排序

平均时间复杂度,最好情况,最坏情况,空间复杂度依次是
在这里插入图片描述
稳定性:稳定

package dataStructure;

public class bubbleSort {
    public static void main(String[] args) {
        int[] a = {3,22,11,34,16,6,43};
        int temp;
        for(int i=0;i<a.length-1;i++){
            for(int j=0;j<a.length-1-i;j++){
                if(a[j+1]<a[j]){
                    temp = a[j+1];
                    a[j+1] = a[j];
                    a[j] = temp;
                }
            }
            System.out.print("第"+i+"次外层循环  ");
            for(int n:a){
                System.out.print(n+" ");
            }
            System.out.println();
        }
    }
}

在这里插入图片描述
内层for循环用于让数组里面的元素两两比较,较大的元素就通过元素交换的方式移动到数组的后面,每轮内层for循环都会让一个最大的数字沉底,即最大的元素在数组的最后面。第二轮内层for循环会排除掉已经沉底的元素,在剩下的元素里面找到最大值,然后排在数组的倒数第二个位置。以此类推。

外层for循环用来指明总共需要进行几次内层for循环,总共需要进行 数组长度减一 次的元素沉底,因为最后一个元素不需要再经过内层for循环的两两比较了。

在这里插入图片描述

快速排序

平均时间复杂度,最好情况,最坏情况,空间复杂度依次是
在这里插入图片描述
稳定性:不稳定

public class quickSort {
    public static void main(String[] args) {
        int[] arr = {3,5,12,6,45,31,3};
        qsort(arr,0,arr.length-1);
        for (int i : arr) {
            System.out.print(i+" ");
        }

    }

    public static void qsort(int[] arr,int low,int high){
        if(low<high){
            int index = getIndex(arr,low,high);
			//对某一个数字的排序完成后,根据此数字将数组分为左半区和右半区
            qsort(arr,low,index-1);  //对左半区再一次应用qsort
            qsort(arr,index+1,high); //对右半区再一次应用qsort
            //直到low = high,说明半区里面只有一个元素,则无需排序了
            //注意这里的low和high是根据传入qsort函数里面的参数而实时变化的
        }

    }

    public static int getIndex(int[] arr,int low,int high){
        int tmp=arr[low];
        while(low<high){
            //这里要加上low<high是因为如果数组一开始就是排好顺序的
            //那么high会一直减一,如果没有low<high的限制,high会减到负数

            //使用while循环,满足了high一直左移或者low一直右移的情况,直到分别找到了小于tmp和大于tmp的值
            //arr[high]>=tmp则一直左移
            while(low<high && arr[high]>=tmp){
                high--;
            }
            //直到发现arr[high]<tmp,交换
            arr[low] = arr[high];
            //arr[low]<=tmp则一直右移
            while(low<high && arr[low]<=tmp){
                low++;
            }
            //直到发现arr[low]>tmp,交换
            arr[high]=arr[low];

        }
        //low<high的条件不满足时,说明low=high,当前索引就是tmp值的正确索引
        //将tmp存储的值放入这个索引位置
        arr[low]=tmp;
        return low;
    }
}

这里主要的思想是low指针先指向第一个数字,high指向最后一个数字,tmp设置为第一个数字
low向右移动,high向左移动,当两者指向相同位置时,这个位置就是tmp的正确位置
low和high指向的位置都有可能是tmp的正确位置,因此low左边都是小于tmp的数字,high右边都是大于tmp的数字。大于tmp的数字应该放在右边,小于tmp的数字应该放在左边。

首先是high开始判断,

  1. arr[high]>=tmp,说明位置正确,就是在tmp的右边,因此high- -左移
  2. arr[high]<tmp,说明位置错误,应该在tmp的左边,因此arr[low]=arr[high]

为什么可以arr[low]=arr[high]呢?
因为第一次必定先比较移动high,此时arr[low]的值就是tmp,那么arr[low]=arr[high],
只是把第一个位置给覆盖掉了,而第一个位置的值还在tmp里面,tmp的值最后会给low和high相遇的位置,因此没有数字丢失

只要满足arr[high]>=tmp的条件,high就会一直向左移动,直到遇到了arr[high]<tmp,然后arr[low]=arr[high]之后,就换为low开始比较移动

  1. arr[low]<=tmp,说明位置正确,小于tmp就在tmp的左边,因此low++右移
  2. arr[low]>tmp。说明位置错误,比tmp大的数应该放在tmp的右边,因此arr[high]=arr[low]

经过上一轮high将值放在了arr[high],此时会有两个arr[high],所以arr[high]=arr[low],
只是把high指向的重复值换掉,没有数字丢失

直到 low = high 则当前位置是正确位置
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一纸春秋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值