• 算法:排序


    一些约定

    • java命令行程序
      算法的学习和语言无关,下面使用一个java命令行程序来作为实例程序。

    • 一个算法一个类
      排序算法使用一个方法就可以表示,不需要是一个对象。但为了让各种排序算法的表示相互独立,接下来分别为它们定义不同的类型,并提供一些工具类来产生随机数序列,打印数字序列,对数列进行校验等。

    • 以整数序列升序为例
      对应java程序,任何可比较的类型——实现接口Comparable<T>的类型,都是可排序的。所以一个排序方法的签名大致可以是这样的public <T extends Comparable<? super T>> void sort(T[] items) ,不过为了演示的简单,下面使用int[] numbers作为需要排序的数列,并且排序算法对它进行升序排序。

    排序方法抽象接口

    使用下面的接口SortMethod来抽象表达排序算法:

    interface SortMethod {
        /**
         * sort numbers.
         */
        void sort(int[] numbers);
    }
    

    工具类

    定义下面的SortingTools类来提供需要的辅助功能。

    public final class SortingTools {
        private static Random random = new Random();
    
        public static void testSort(SortMethod method, int numberSize) {
            int[] numbers = new int[numberSize];
    
            for (int i = 0; i < numbers.length; i++) {
                numbers[i] = random.nextInt(1000);
            }
    
            SortingTools.printNumbers(numbers);
            Log.println("before sort. isAscending = " + SortingTools.isAscending(numbers));
    
            method.sort(numbers);
    
            SortingTools.printNumbers(numbers);
            Log.println("after sort. isAscending = " + SortingTools.isAscending(numbers));
        }
    
        public static void printNumbers(int[] numbers) {
            for (int i = 0; i < numbers.length; i++) {
                Log.print(numbers[i] + ", ");
            }
    
            Log.print("
    ");
        }
    
        public static boolean isAscending(int[] numbers) {
            int prev = numbers[0];
            for (int i = 1; i < numbers.length; i++) {
                if (numbers[i] < prev) {
                    return false;
                }
    
                prev = numbers[i];
            }
    
            return true;
        }
    }
    
    • printNumbers(int[] numbers)
      用来打印输出numbers,方面查看。Log.print()方法简单封装了下显示打印的逻辑。

    • isAscending(int[] numbers)
      用来校验指定序列numbers是否为升序。

    • testSort()
      测试method所表示的某种排序算法,对于将要学习的各种不同排序算法,测试的过程是一样的。
      先随机生成numberSize大小的int[]数组,然后排序前后分别打印输出数组各项,并且对数组是否为升序进行验证。

    冒泡排序

    先从一个简单的“冒泡排序”开始,实际上即使冒泡排序也有许多高级的变种,这里仅实现基础的算法。

    算法思路

    假设是N个数字,要完成升序排列,每次从第一个元素开始,依次将较大数字放置到第N、N-1、N-2...位置处。

    编码

    下面算法的时间效率属于O(N²):

    public class BubbleSort implements SortMethod {
    
        @Override
        public void sort(int[] numbers) {
            bubbleSort(numbers);
        }
    
        public static void bubbleSort(int[] numbers) {
            int swap;
            for (int end = numbers.length - 1; end > 0; end--) {
                for (int i = 0; i < end; i++) {
                    if (numbers[i] > numbers[i + 1]) {
                        swap = numbers[i + 1];
                        numbers[i + 1] = numbers[i];
                        numbers[i] = swap;
                    }
                }
            }
        }
    }
    

    实际的排序方法可以是静态的,然后重写的sort()方法简单地调用它来完成排序。

    测试

    在main()方法中:

    public static void main(String[] args) {
        SortingTools.testSort(new BubbleSort(), 20);
    }
    

    一次输出如下:

    246, 558, 286, 652, 470, 905, 11, 102, 705, 498, 695, 769, 86, 189, 986, 317, 957, 471, 406, 625,
    before sort. isAscending = false
    11, 86, 102, 189, 246, 286, 317, 406, 470, 471, 498, 558, 625, 652, 695, 705, 769, 905, 957, 986,
    after sort. isAscending = true
    

    (本文使用Atom编写)

  • 相关阅读:
    SDUT2389Ballot evaluation
    POJ2941 SDUT2371Homogeneous squares
    SDUT1570 C旅行
    应用jQuery实现表格数据的动态添加与统计
    抢火车票利器:分享一个抓取火车票转让信息的小程序
    10款精选的用于构建良好易用性网站的jQuery插件
    数据库拷贝的问题
    sqlserver 2008手工修改表结构,表不能保存的问题与解决方法
    mysql 1067错误的处理
    40个有用的jQuery技术和教程
  • 原文地址:https://www.cnblogs.com/everhad/p/6246880.html
Copyright © 2020-2023  润新知