各路排序神仙理解以及Java实现

啊啊啊啊啊啊!大话数据结构终于看到了排序这一章章啦,然而各路排序神仙,真的是看懂了!仅仅是看懂了,所以打算用两天的时间比几个常见的算法写一遍啦,加深一下印象。嘤嘤嘤

参考博客
十大经典排序算法(动图演示

冒泡排序

这个算法我记得是上C语言就接触了,他的思想是,遇到逆序对,就进行交换啊,就这样慢慢的第n个有序,第n-1个有序.......全部有序。 关键点在于如果一次遍历,都没有交换操作的话,那说明已经有序啦,跳出循环。排序完成。

package com.it592.sort;

public class BubbleSort extends Sort {
    @Override
    public void sort(int nums[]) {
        int len = nums.length;
        for (int i = 0; i < len; i++){
            boolean flag = true;
            for (int j = 0; j < len - i -1; j++){
                if(nums[j] > nums[j+1]){ // 判断是否逆序,如果逆序,说明还没找到正确的位置,继续后移
                    nums[j] += nums[j+1];
                    nums[j+1] = nums[j] - nums[j+1];
                    nums[j] -= nums[j+1];
                    flag = false;
                }
            }
            if (flag)
                break;
        }
    }
}

选择排序

选择排序,按照大话数据结构的话说,其实和冒泡排序差不多,但是这两个算法的侧重点不同,冒泡排序每次都进行交换操作,其实有很多交换是没有必要的,毕竟交换也要费点时,选择排序他只是观察,找到适合某个位置的点,然后再进行交换,这就好比炒股票,冒泡排序是看到每次涨了之后,都卖出去,然后降了再买点回来,而选择排序是看到最高点,再抛售,这就省去了中间交易的开销,也就是冒泡排序时候交换的时候开销。

package com.it592.sort;

public class SelectSort extends Sort {
    @Override
    public void sort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++){
            int key = i;
            for (int j = i + 1; j < nums.length; j++){ //找到适合i的值。
                    if (nums[key] > nums[j])
                        key = j;
            }
            if(key != i){
                nums[i] += nums[key]; //让i变为有序的
                nums[key] = nums[i] - nums[key];
                nums[i] -= nums[key];
            }
        }
    }
}

插入排序

插入排序的思想是,假设序列已经有序了,那么我们只需要把当前元素插入到正确的位置即可。首先,对于第一个元素,因为只有一个元素,所以他是有序的,对于第二个元素,则与第一个元素进行判断,如果比第一个元素小,则插到第一个元素之前,第一个元素后移;对于第三个元素,则和前两个元素进行比较,找到合适的位置,插入即可。依次类推,最终有序。

package com.it592.sort;

public class InsertSort extends Sort {
    @Override
    public void sort(int[] nums) {
        int len = nums.length;
        for(int i = 0; i < len -1 ; i++){
            int tmp = nums[i+1];
            int j = i+1;
            for(; j > 0; j--){
                if(nums[j-1] > tmp){
                    nums[j] = nums[j-1];
                }else
                    break;
            }
            nums[j] = tmp;
        }
    }
}

希尔排序

在插入排序中,由于要把某个元素放到合适的位置上,这样可能就会导致其他元素偏离他本来的位置很远,希尔排序是对插入排序的一种改进,他可以将小的元素放到前面去,而大的元素集中在尾部。方法是,将数组进行分组,例如[2,5,1,4,5,55,11,1,15,19,2,33,55,8],我们设置space=3,那么则[2,11,19,55],[5,5,1,2,8],[1,55,15,33]为三个分组,使用插入排序对他们进行排序后,就会得到以下结果[2,1,1,11,2,15,19,5,33,55,5,55,8],通过这样一轮排序之后,就会发现小的部分相对集中在前面,而大数则集中在后面。最终循环完毕,有序

package com.it592.sort;

public class ShellSort extends Sort {
    @Override
    public void sort(int[] nums) {
        int gap = nums.length / 3 + 1;

        while (true){
                for (int i = 0; i < nums.length - gap; i += gap){
                    int tmp = nums[i+gap];
                    int j = i + gap;
                    for (; j > 0; j -= gap){
                        if(nums[j-gap] > tmp)
                            nums[j] = nums[j-gap];
                        else
                            break;
                    }
                    nums[j] = tmp;
                }
                if (gap == 1)
                    break;
                gap = gap / 3 + 1;

        }
    }
}

猜你喜欢

转载自www.cnblogs.com/xmxj0707/p/9764271.html
今日推荐