排序——交换排序

简介

交换排序是一种通过不断比较数组中两个元素的大小,如果大小顺序与要得到的排序相反,则交换位置,否则不交换的排序方法。常用的交换排序法就是冒泡排序和快速排序。

一、交换排序

假设有n个元素,则第一趟排序中,依次比较下标为0与1、1与2、2与3……n-1与n的大小,并且每次比较中,如果与目标顺序不同,则交换两个数的大小。第二趟排序中,依次比较下标为0与1、1与2、2与3……n-2与n-1的大小……一共n-1趟。

举例

注:下面的数组按升序排序

第n趟冒泡排序数组元素执行的操作
039 , 80 , 76 , 41 , 13
139 , 80 , 76 , 41 , 13比较39和80的大小
139 , 76 , 80 , 41 , 13比较80和76的大小并交换位置
139 , 76 , 41 , 80 , 13比较80和41的大小并交换位置
139 , 76 , 41 , 13 , 80比较80和13的大小并交换位置
239 , 76 , 41 , 13 , 80比较39和76的大小
239 , 41 , 76 , 13 , 80比较76和41的大小并交换位置
239 , 41 , 13 , 76 , 80比较76和13的大小并交换位置
239 , 41 , 13 , 76 , 80比较76和80的大小
339 , 41 , 13 , 76 , 80比较39和41的大小
339 , 13 , 41 , 76 , 80比较41和13的大小并交换位置
313 , 39 , 41 , 76 , 80比较39和13的大小并交换位置

至此,排序完成,最后的序列为[13 , 39 , 41 , 76 , 80]

特点

显然,冒泡排序是一种O(n2)的算法,而且它是稳定的

二、快速排序

冒泡排序虽然稳定,但是时间复杂度太高了,所以在对速度要求较高的情况下,我们更倾向于使用另一种算法——快速排序算法。
快排的基本思想是(默认升序),将数组的第一个元素作为关键码Key,并定义2个变量i、j,分别指向数组起始和末尾下标,每一趟排序,从j开始往前扫描找出第一个比Key小的元素,然后交换nums[i]和nums[j],然后从i往后扫描找出第一个比Key大的元素,交换nums[i]和nums[j]。直到i== j时跳出循环。

举例

数组太大了着不住啊~所以就用长度小一点数组举例啦。。。
键值Key = 39

第n趟快速排序数组元素ij执行的操作
039 , 80 , 4 , 503
15 , 80 , 4 , 3903从后往前找出比Key小的数,然后交换nums[i]、nums[j]
15 , 39 , 4 , 8013从前往后找出比Key大的数,然后交换nums[i]、nums[j]
25 , 4 , 39 , 8012从后往前找出比Key小的数,然后交换nums[i]、nums[j]
25 , 4 , 39 , 8022从前往后找出比Key大的数,然后交换nums[i]、nums[j]

可见,经过快速排序后,确实将比Key小的值划分到了前面,比Key大的值划分到了后面。然后我们再分别将(start, i -1)和(i+1, end)之间的数组调用快速排序,就能得到结果了

第n趟快速排序数组元素ij执行的操作
34 , 5 , 39 , 8001从后往前找出比Key小的数,然后交换nums[i]、nums[j]
34 , 5 , 39 , 8011从前往后找出比Key大的数,然后交换nums[i]、nums[j]

所以,最后的结果是[4 , 5 , 39 , 80]

特点

最优情况下,快排的时间复杂度是O(nlog2n),一般情况也是O(nlog2n),但是最坏的情况是当数组完全有序时,时间复杂度为O(n2n),而且快排是一种不稳定的算法。然而由于快排确实足够快,所以在对稳定性要求不高的时候,可以使用快排。

附代码:

1.冒泡排序

class BubbleSortTool{

    public static void bubbleSort(int[] nums){
        int swap ;//每趟的交换次数
        int temp ;
        //需要n-1趟交换
        for(int i = 0; i < nums.length -1; i ++){
            swap = 0;
            for(int j = 1; j < nums.length; j ++){
                if(nums[j] < nums[j-1]){
                    temp = nums[j];
                    nums[j] = nums[j-1];
                    nums[j-1] = temp;
                    ++swap;
                }
            }
            if(swap == 0)//如果该趟没有交换,则表明数组已经是有序的了
                break;
        }
    }

}

2.快速排序

class QuickSortTool{

    public static void quickSort(int[] nums ,int start , int end){
        if(start >= end)
            return ;
        int i = start , j = end;
        int key = nums[start];
        int temp;
        while(i < j){
//          System.out.println("sort");
            for(; i < j ; j --){
                if(key > nums[j]){
                    temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                    break;
                }
            }
            for(; i < j ; i ++){
                if(nums[i] > key){
                    temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                    break;
                }
            }
        }
        quickSort(nums,start,i-1);
        quickSort(nums,i+1,end);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值