简单排序

简单排序

  • 受我一个小伙伴的影响,开始重学数据结构

    算法的设计取决于选定的逻辑结构,算法的实现则依赖于采用的存储结构。


这里写代码片 *静态结构 * 在数据存在期间不会发生变动 : 静态数组。 *动态结构 * 在一定范围内结构的大小可以发生变动:堆栈。
  • 对于每个排序的描述,是我个人的理解,仅供参考。

    一个软件系统的框架应建立在数据之上,而不是操作之上

  • 方法声明:

    @Override
    public void swap(int a[], int i, int j) {
        int buf;
        buf = a[i];
        a[i] = a[j];
        a[j] = buf;
    }

    @Override
    public boolean isLess(int a, int b) {
        return a < b ? true : false;
    }

BubbleSort

气泡排序应该是接触最早的一种,我是在学 C 语言的时候,接触的。
气泡排序:基本思想是通过前后比较交换,思想比较简单。

代码中有接口、注解,统一在文章末尾说明。

程序清单:

不管其他,先抛异常

    /**
     * 每次在未排序的元素中,第 j 个和第j +1个比较,然后交换
     */
    @Override
    public void execute(int a[], int min, int high) throws Exception {
        int count = 0;
        int exch = 0;
        for (int i = 0; i < high; i++) {
            for (int j = 0; j < high - i - 1; j++) {
                if(isLess(a[j+1], a[j])){
                    swap(a, j + 1, j);
                    exch++;
                }
                count++;
            }
        }
        SampleUtil.print_result("This Bubblet Sort Count", a, count, exch);
    }

气泡排序实际比较简单,但是我还是调了一遍。 原因:第一层for循环的时候 length 已经是 a.length - 1 了,我想当然的 写了 “<” ,然后我就想 那最后一个元素不就被漏了。 Too young 气泡排序到最后一个已经是有序了。

SelectSort

    /**
     * 选择排序,有 N 个元素,依次取出余下N-i个元素中最小的,放入第i个位置。
     */
    @Override
    public void execute(int a[], int min, int high) throws Exception {

        int count = 0;
        int exch = 0;
        high = a.length;
        for (int i = 0; i < high; i++) {
            min = i;
            for (int j = i + 1; j < high; j++) {
                if (isLess(a[j], a[min])) {
                    min = j;
                    exch++;
                }
            }
            swap(a, i, min);
            count++;
        }
        SampleUtil.print_result("This is Select Sort", a, count, exch);
    }

内循环 For 的时候用了 <= ,外循环到最后一个的时候 如果用 < 会漏下一个元素.

很容易很起泡混淆啊,起泡是每一次遍历时前后比较交换。选择是第 i 次 跟 [ i+1 : N ] 比较交换.

QuickSort

快速排序: 看名字 就在知道 速度快

思想是 选取一个枢轴值 pivot 。 从low位置开始检索,当找到大于等于 pivot 的值时,low与high 所指的进行交换;然后开始从high开始检索找到小于等于 pivot 的值时 low与high交换。当low = high 时 基本有序。

上面是我自己理解的,仅供参考

参考代码:

private int partition(int a[], int low, int high) {

        int pivot = a[low];
        int count = 0, exch = 0;
        // initial statues
        while (low < high) {

            // this block we want to find a number which value smaller than high
            // when the express high < pivot is true then high move to low

            while (a[high] >= pivot && low < high) {
                high--;
                count++;
            }
            if (a[low] != a[high]) {
                swap(a, low, high);
                exch++;
                low++; // once have change , low must smaller than pivot
            }

            /*
             * other way , this block we want to find one which bigger than
             * pivot ,so the low continue move to high until the number bigger
             * than pivot
             */
            while (a[low] <= pivot && low < high) {
                low++;
                count++;
            }
            if (a[low] != a[high]) {
                swap(a, low, high);
                exch++;
                high--; // the same as ' low ++ '
                // SampleUtil.print_result("quick Sort : ", a, count, exch);
            }
        }
        return low;
    }

    /**
     * 选择一个枢轴值,从最高位置(high)开始访问元素,1.找到第一个元素 <= pivot 就与low位置的元素交换,此时交换后low位置的元素 <= pivot,然后 low后移。
     * 2. 然后从最低位置访问找到第一个 >= pivot 的元素就与high交换,此时high位置的元素 >= pivot,然后high 前移。
     *  分别执行上面两部,直到 low >= hight 两者相遇时退出
     * 
     */
    @Override
    public void execute(int a[], int low, int high) throws Exception {
        if (low > high) {

            // print the result of quick sort

            SampleUtil.print_result("quick Sort : ", a, 0, 0);
            return;
        }
        int pivot = partition(a, low, high);
        execute(a, low, pivot - 1);
        execute(a, pivot + 1, high);

    }

调用 partition 方法 分成两个基本有序的序列,然后再向两个基本有序的序列分别调用 partition 方法。当 low > high 时推出递归.

InsertSort

插入排序这么写有点像起泡,但是插入排序是在前 i-1 个已经基本有序的元素中插入,原来的元素后移一个位置。

/**
 * 升序:N个元素,每次访问都将第 i 个元素 插入到前 i-1 个元素中的合适位置
 */

@Override
public void execute(int[] a, int low, int end) throws Exception {
    int count = 0, exch = 0;
    for (int i = 0; i < end; i++) {
        for (int j = i; j > 0; j--) {
            // 升序
            // 如果当前元素比已经有序的小,则比当前元素大的都往后移动
            if (a[j] < a[j - 1]) {
                swap(a, j, j - 1);// 元素后移会导致覆盖 ,所以用交换 替代
                exch = 0;
            }
            count++;
        }
    }
    SampleUtil.print_result("Insert Sort : ", a, count, exch);
}

测试方法:

上面的每个方法都实现了Sort 接口。接口代码……

package com.foo._Alogrithm.SampleSort;

public interface Sort {
    public void execute(int a[], int low, int end) throws Exception;
}

测试类:



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring.xml " })
public class JunitTest {

    int a[] = { 1, 2, 43, 5, 856, 6, 78, 276, 34, 23, 69, 3, 654, 54, 65, 7, 889 };

    // @Autowired
    // private QuickSort quickSort;
    //
    // @Autowired
    // private BubbleSort bubbleSort;
    //
    // @Autowired
//   private SelectSort selectSort;

//   Sort sort = new SelectSort();
    // Sort sort = new BubbleSort();
    Sort sort = new QuickSort();

    @Test
    public void test() {

        try {
            sort.execute(a, 0, a.length - 1);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

mark 完了……
为什么用注解?
用注入的嘛 我就不用都去new 一个对象了。但是后面感觉,每次都要加@Autowired,好麻烦;后面就都实现了一个接口。多态嘛…… 然后省事二点儿……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值