排序算法笔记_____2(选择排序和插入排序)

本文详细介绍了选择排序和两种插入排序算法的原理及实现过程,对比了不同算法的特点与应用场景,通过实验验证了不同情况下算法的性能表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选择排序

package com.chapter_two;

/***
 * 选择排序的思想:
 * 
 * 在所有的元素中找出最小的元素,与数组的第一个元素进行交换,
 * 
 * 再在剩下的元素中找出最小的元素,与数组的第二个元素进行交换,
 * 
 * 如此往复,最终使整个数组有序。
 * 
 * 特点:
 * 
 * ①运行时间和输入无关 ②相比其他排序算法,数据移动是最小的
 * 
 * 命题:
 * 
 * 对于数组长度为 N 的数组,交换的次数为 N 次,比较次数大约为 N*N/2 次
 * 
 * @author LuodiJack
 */
public class Selection {
    public static void sort(Comparable[] a) {

        int N = a.length;
        for (int i = 0; i < N; i++) {// 升序排列
            int min = i;
            for (int j = i + 1; j < N; j++) {
                if (Template.less(a[j], a[min])) {// 找出最小的元素
                    min = j;
                }
            }

            Template.exch(a, min, i);// 交换元素
        }
    }

    // less()、exch()见排序算法类的模板

    public static void main(String[] args) {
        Integer[] a = { 11, 7, 3, 6, 8, 9, 2, 10 };
        sort(a);
        for (Integer i : a) {
            System.out.print(i+" ");
        }
    }
}

插入排序

package com.chapter_two;
/***
 * 思想:
 * 
 * 通常人们整理桥牌的方法是一张一张的来,
 * 
 * 将每一张牌插入到其他已经有序的牌中的适当位置。
 * 
 * 在计算机的实现中们为了给要插入的元素腾出空间,我们需要将其余的所有元素在插入之前都向右移动一位。
 * 
 * 时间:
 * 
 * 插入排序所需要的时间取决于输入中元素的初始顺序。
 * 
 * 事实上,当数组中的倒置的元素的数量很少时,插入排序的速度还是很快的。
 * 
 * 另外,插入排序对部分有序数组很有效。
 * 
 * (
 * 几个典型的部分有序数组:
 * 
 * 一、数组中每个元素距离它的最终位置都不远
 * 
 * 二、一个有序的大数组接一个小数组
 * 
 * 三、数组中只有几个元素的位置不正确。
 * )
 * 
 * @author LuodiJack
 *
 */

public class Insertion {
    public static void sort(Comparable[] a) {// 升序排列
        for (int i = 1; i < a.length; i++) {
            for (int j = i; j > 0 && Template.less(a[j], a[j - 1]); j--) {//内循环为交换两个元素
                Template.exch(a, j, j - 1);
            }
        }
    }

    public static void sortTwo(Comparable[] a) {//升序排列
        for (int i = 1; i < a.length; i++) {
            Comparable num = a[i];
            int j = i;
            //内循环:将较大的元素向右移而不是交换两个元素,这样做的目的可以提高插入排序的速度(访问数组的次数减半)。
            for (j = i; j > 0; j--) {
                if (Template.less(num, a[j - 1])) {
                    a[j] = a[j - 1];
                } else {
                    break;
                }
            }
            a[j] = num;
            ;
        }
    }

        @SuppressWarnings("rawtypes")
    public static void sortThree(Comparable[] a) {// 升序排列
        // 先将最小的元素移到 a[0] 处,起哨兵的作用,
        // 可以将内循环中的 j>0 的条件去掉,减少了交换次数,经过测试       可知, 这种做法确实缩短了运行时间
        int indexOfMin = 0;
        for (int i = 1; i < a.length; i++) {
            if (Template.less(a[i], a[indexOfMin])) {
                indexOfMin = i;
            }
        }

        Template.exch(a, 0, indexOfMin);

        for (int i = 1; i < a.length; i++) {
            for (int j = i; Template.less(a[j], a[j - 1]); j--) {
                Template.exch(a, j, j - 1);
            }
        }
    }

}

两种插入排序的测试:
用随机函数随机生成一百万个数字赋值给两个数组,分别用两种插入排序进行排序,并记下各自的运行时间。sort()运行了7903554ms,sortTwo()运行了6799631ms,两者相差1103923ms(约18分钟)。看见没,这就是差距(随后进行了许多次试验,都验证了sortTwo() 比sort()快)。
但是,当所有的元素都相等时,即所有主键都一样的时候,第二种排序方法就比第一种慢了很多

文中用到的less()、exch()方法,详见类模板。(排序算法笔记____1)
http://blog.youkuaiyun.com/a199581/article/details/50651401

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值