数据结构--Java实现几种常见排序

第一次在CSDN上写博客,今天晚上刚好复习了一下排序相关的东西,就写一写这个吧。(话说markdown还不熟悉。。)

冒泡排序:复杂度o(n^2) 可以增加一个flag标记减少比较趟数 稳定
public static void bubbleSort(int[] arr) {        //时间复杂度:O(n*2)
        int count = 0;
        for(int i = 0;i<arr.length;i++){           //循环遍历,每次找出最大值放在数组最后
            int flag = 0;
            for(int j = 1;j<arr.length-i;j++){          //子循环每次比较相邻的两个数,逐个的推到最后 
                if (arr[j]<arr[j-1]) {  //只是在小于时才交换,所以是稳定的排序,也就是说不会改变相对位置
                    flag=1;
                    count++;
                    int temp = arr[j-1];
                    arr[j-1] = arr[j];
                    arr[j] = temp;
                }
            }
            if (flag == 0) {            //flag记录了单次遍历是否有过交换,若没有则说明在这之后都没有
                System.out.println(count);  //打印出我们共进行了多少次遍历
                break;
            }
        }

    }

由上述代码可以知道冒泡排序的要点:第n次冒泡会将第n小或第n大的找出来。

插入排序:复杂度o(n^2). 稳定
   public static void insertSort(int[] a) {  
        for(int i=1;i<a.length;i++){//从头部第一个当做已经排好序的,把后面的一个一个的插到已经排好的列表中去。  
            if(a[i]<a[i-1]){     //稳定的排序
                int j;  
                int x=a[i];//x为待插入元素  
                //a[i]=a[i-1];  
                for(j=i-1;  j>=0 && x<a[j];j--){//通过循环,逐个后移一位找到要插入的位置。  
                    a[j+1]=a[j];  
                }  
                a[j+1]=x;//插入  
            }  

        }  

    }  

插入排序每次找到一个元素相对应的位置,但不是最终位置。

快速排序: o(logn) 最坏:退化成o(n^2) 不稳定
    public static void quickSort(int[] arr,int low,int high) {
            if(low<high){
            int p = partition2(arr, low, high);
            quickSort(arr,low,p-1);   //使用递归分别对左子数组,右子数组进行排序
            quickSort(arr, p+1,high);
        }
    }

上面是快排的递归代码,每次确定一个数在整个数组中的位置,小的在左边,大的在右边。要注意的是快排不是稳定的,就是因为在分治代码块中将相等的情况也进行了交换。

分治代码:
public static int partition(int [] arr,int low,int high){  //将数组进行分治,即小于关键字放在左边,大于关键字放在右边,关键字每次选择为数组的第一个数
        int temp = arr[low];                                //返回值为当前关键字的下标
        while(low<high){
            while(low<high&&arr[high]>temp){
                high--;
            }
            arr[low] = arr[high];                   //查找到比关键字小的数时把它放到左边来,此时arr[high]仍为以前的值
            while(low<high&&arr[low]<=temp){
                low++;
            }
            arr[high] = arr[low];               //从左边找到比当前关键字大的数放到右边来,即之前的arr[high]改成此较大数。保证了数组的一致性
        }
        arr[low] = temp;         //此时low==high,关键字赋值给此下标,返回下标。
        return low;
    }
    public static int partition2(int [] arr,int low,int high){ //这里介绍一个不抽象的分治,即我们实时都知道关键字的位置
        int temp = arr[low];
        while(low<high){
            while(low<high&&arr[high]>temp){
                high--;
            }           
            arr[low] = arr[high];    //找到较小值后放到右边
            arr[high] = temp;           //这时将关键字赋值给arr[high]
            while(low<high&&arr[low]<=temp){
                low++;
            }
            arr[high] = arr[low];       //与之前相反,较大值放到左边,并且arr[low]保持为关键字
            arr[low] = temp;
        }
        arr[high] = temp;
        return low;
    }

上面两种分治代码是一样的,只是第一种比较抽象,但代码简洁,第二种能够实时的看出我们的temp值在数组的哪个位置,便于理解,熟练后就用第一种就好了。

好了,以上就是我在csdn上写的第一篇博客,也不知道以后自己会不会坚持写,还是希望写下去吧,记录自己的一些时光也是挺好的

那还是给我的第一篇博客加上一张gakki的美照留个纪念!!(之前在博客园写的时候也加了这张图,哈哈~)
gakki

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值