几种排序算法代码+动态图(2020/6/11更新)

https://blog.csdn.net/Hodge_Z/article/details/84673439 该大佬的博文,有代码和动态图。非常棒。

下边是我的理解(精心研究啊QAQ):

1、冒泡排序:(每趟比较都能把未排序元素中最大的沉到最底部)

1·依次比较相邻的两个元素,如:若第一个大于第二个,则交换两个元素的位置。

2·然后比较第二个和第三个元素,以此类推,直到排序完成。

每趟排序都会把最大的放到最后。排序完成时小的数就会“浮”到上面,大的“沉”到下面。

package com.download.demo.SuanFa;

/**
 * @author:tongys
 * @createTime:2020/6/9 8:16
 * 冒泡排序:两两比较,符合条件则交换位置。该操作进行“元素个数-1”次。
 */
public class MaoPao {
    public static void main(String[] args) {
        int[] array = {8,3,1,2,7,0};//5个
        int temp = 0;
        for (int i = 1;i<array.length;i++){//“遍历数组两两比较”这个操作的循环次数 【元素个数-1】次
            for (int k = 0;k<array.length-i;k++){ //遍历数组两两比较,每一趟需要比较的元素组数依次减少。↓
                                                    // 因为每趟排序都能把“最大的”沉到底部,这个最大的不参与下趟比较。第一趟比较【元素个数-1】次
                if (array[k]>array[k+1]){
                    //交换
                    temp = array[k];
                    array[k] = array[k+1];
                    array[k+1] = temp;
                }
            }
        }
        System.out.println("排序完成后的结果:");
        for (int i = 0;i<array.length;i++){
            System.out.println(array[i]+",");
        }
    }
}

2、选择排序:(每趟比较都能找出未排序元素中最小的)

1·拿到第一个元素,向后逐个比较直到找到比它小的元素,记录该元素下标和数值。

2·然后用新的较小元素,继续向后比较,寻找比它小的元素,记录其下标和数值。

3·直到全部比较一遍,然后交换第一个元素和本次比较中发现的最小元素的位置。

4·然后拿到第二个元素,重复以上步骤,直到全部排序一遍,需要比较【元素个数-1】趟。

package com.download.demo.SuanFa;

/**
 * @author:tongys
 * @createTime:2020/6/9 9:10
 * 选择排序:每趟排序都能选出最小的元素,然后把它放到参与排序的元素中的第一位,它在下一趟不参与排序。那么一共需要比较【元素个数-1】趟
 */
public class Xuanze {
    public static void main(String[] args) {
        int[] array = {8,3,1,2,7,0};//6个
        int flag = 0;//记录更小的那个元素的位置
        int temp = 0;//中介
        for (int i =0;i<array.length-1;i++){//一共要排序【元素个数-1】趟
            flag = i;
            for (int k = i+1;k<array.length;k++){
                if (array[flag]>array[k]){
                    //如果出现了更小的,就拿这个更小的去往下比较
                    flag = k;
                }
            }
            //把这一趟找出来的最小元素,放到本次排序元素的最前头
            temp = array[i];
            array[i] = array[flag];
            array[flag] = temp;
        }
        System.out.println("排序完成后的结果:");
        for (int i = 0;i<array.length;i++){
            System.out.print(array[i]+",");
        }
    }
}

3、插入排序:

1、理念:将数组分为左右两部分,认为左部分已经排序,右部分没有排序。

2、初始默认数组的第一个元素已经被排序。

3、拿到未排序部分的第一个元素A,向左比较直到找到小于等于A的元素,然后把A元素插到它后边。如果没有找到,则位置不变认为已被排序。

4、重复第三步。直到所有元素均被排序。

package com.download.demo.SuanFa;

/**
 * @author:tongys
 * @createTime:2020/6/9 9:54
 * 插入排序:分为已排序(初始默认第一个元素已排序)和未排序两组,然后将未排序组中的第一个元素向左进行比较,↓
 * 左边的大于它则交换位置,直到遇到小于等于它的,此时它被作为已排序的元素。
 * 【注:插入排序它每次排序都能确定一个元素的位置】
 */
public class ChaRu {
    public static void main(String[] args) {
        int[] array = {8,3,1,2,7,0};//6个
        int temp;//中介
        for (int i=1;i<array.length;i++){ //插入【元素个数-1】次
            int k = i-1;
            temp = array[i];//保存 当前这个正在排序的元素
            while (k>=0){//左边还有元素
                if (array[k]>temp){//如果左边的比它大,则交换位置。然后继续向左比较
                    array[k+1] = array[k];
                    array[k] = temp;
                    k--;//继续向左
                }else{//如果左边的小于等于它,则保持当前位置不动。认为该元素已排序完成,接下来排序下一个。
                    break;
                }
            }
        }

        System.out.println("插入排序完成后的结果:");
        for (int i = 0;i<array.length;i++){
            System.out.print(array[i]+",");
        }
    }
}

4、快速排序

 * 快速排序:说白了就是给基准值找到它正确的位置,只要我们让左边的都小于它,右边的都大于他,那么它此时的位置就是排序完成后应在的位置。(这是一次基准定位的操作)
 
 * 注意!个人理解!(想了好久!):

    我更认为每一次调用KuaiSuSort()方法都是在以某个元素为基准,在将数据切分为左右半组(左半组都小于基准,右半组都大于基准)。
    每一次递归调用KuaiSuSort()方法我们着眼的元素组都在变小,直到无法再进行切分(只有一个元素),该小组元素排序就完成了。所有小组都无法再切分时,整个数组就排序完成了。

package com.download.demo.SuanFa;

/**
 * @author:tongys
 * @createTime:2020/6/9 14:45
 * 快速排序:说白了就是给基准值找到它正确的位置,只要我们让左边的都小于它,右边的都大于他,那么它此时的位置就是排序完成后应在的位置。(这是一次基准定位的操作)
 *
 * 注意!个人理解!(想了好久!):我更认为每一次调用KuaiSuSort()方法都是在以某个元素为基准,在将数据切分为左右半组(左半组都小于基准,右半组都大于基准)。
 * 每一次递归调用KuaiSuSort()方法我们着眼的元素组都在变小,直到无法再进行切分,该小组元素排序就完成了。所有小组无法在切分(只有一个元素)时,整个数组就排序完成了。
 */
public class KuaiSu {
    public static void main(String[] args) {
        int[] array = {8,3,1,2,7,0,6,5};//6个

        //外部调用为启动第一次基准位置确认与左右半组的切分。然后内部就开始通过递归,确认基准位置和不断的切分左右半组,直到无法切分左右半组,此时排序完成。
        KuaiSuSort(array,0,array.length-1);

        System.out.println("快速排序完成后的结果:");
        for (int i = 0;i<array.length;i++){
            System.out.print(array[i]+",");
        }
    }
    static void KuaiSuSort(int[] array,int left,int right){
        //每一次执行getIndex()可以确定一个元素的最终位置,利用迭代确定所有元素位置
        if (left<right){
            System.out.println("调用getIndex前-left:"+left);//xxxxxxxxx
            System.out.println("调用getIndex前-right:"+right);//?为什么right和left会一直在变呢??xxxxxxxxxxxx
            int index = getIndex(array,left,right);
            System.out.println("\n");
            /*下边这两行想简单一点,可以通过分析想到:不管怎么分,只要我们最终定下了index(基准值)的位置,
            那么以基准值来把我们关注的这一部分元素(不要着眼于初始的整组元素)分为
            两组的话,左边半组的left永远是最初传进来的left,右边半组的right永远是最初传进来的right。
            在变化的只有左半组的right(为index-1),和右半组的left(为index+1)。
            */
            KuaiSuSort(array,left,index-1);//负责左半部分
            KuaiSuSort(array,index+1,right);//负责右半部分

            System.out.println("调用自己后-left:"+left);//
            System.out.println("调用自己后-right:"+right);
        }

    }
    static int getIndex(int[] array,int left,int right){ //基准值会不断的与其他元素通过比较大小来交换位置,直到左边的元素都大于基准,右边的元素都小于基准
//        System.out.println("right:"+right);
        //已最左边的元素为基准,将数组进行重新分区,将小于基准的元素放到基准左边,大于基准的元素放到右边。
            int temp = array[left];//基准
            while (left<right){
                //从最右边向左开始找,如果right位置的值大于基准,则继续向左寻找
                while (left<right&&array[right]>temp){
                    right--;
                }
                //当array[right]<temp时,将array[left]赋值给array[right]
                array[left] = array[right];
                //紧接着,换到从左边向右开始找,如果left位置的值小于基准值,则继续向右寻找
                while (left<right&&array[left]<temp){
                    left++;
                }
                if (left == right){
                    break;
                }
                //当找到array[left]>temp时,将array[left]的值赋值给array[right]
                array[right] = array[left];
                //利用while循环以上步骤,直到left=right,此时left和right指向的位置就是基准值应该在的最终位置。
            }
            //基准最后应在的位置
            int index = left;
            array[index] = temp;//确定位置后将基准值赋值到指定位置
//        System.out.println("left:"+left);
//        System.out.println("index:"+index);
//        System.out.println("right:"+right);
        return index;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值