(算法导论)第二章笔记2:算法基础

一.插入排序
  本节讨论插入排序。算法实现以伪代码的形式,以java语言运行该算法。
  通常用伪代码描述算法。
1.伪代码
  使用最清晰、最简洁的表示方法来说明给定的算法。
  伪代码不管徐软件工程的问题,为了更简洁的表达算法的本质,常忽略数据抽象、模块性和错误处理的问题。
  插入排序的伪代码为:

  for j = 2 to  A.length
      key = A[j]
      i = j - 1
      while i > 0 and A[i] > key
          A[i + 1] = A[i]
          i = i - 1
       A[i + 1] = key

2.自己没看之前谢了一段插入排序代码,与下面代码的区别就是while部分用的for,我发现用for比while花的时间长(排序1000个数)。
用java代码实现如下:

public class InsertSort {
    public static void main(String[] args) {
        System.out.println("请输入数组长度:");
        int lengthOfArray = (new Scanner(System.in)).nextInt();

        int[] array = getArray(lengthOfArray);

        int[] insertSortArray = insertSortMethod(array);
        System.out.println("插入排序为:");
        for(int i = 0; i < insertSortArray.length; i++) {
            System.out.printf("%5d",insertSortArray[i]);
            if((i + 1) % 10 == 0)
                System.out.println();
        }
    }

    /**                 生成一个指定长度的随机数组                   */
    public static int[] getArray(int lengthOfArray) {
        int[] array = new int[lengthOfArray];
        for(int i = 0; i < array.length; i++) {
            array[i] = (int) (1 + Math.random()*100);
        }

        System.out.println("随机数字为:");
        for(int i = 0; i < array.length; i++) {
            System.out.printf("%5d",array[i]);
            if((i + 1) % 10 == 0)
                System.out.println();
        }
        System.out.println(" ---------------------------------------------------------------- ");
        return array;
    }


    /**                     插入排序方法                  */
    public static int[] insertSortMethod(int[] sortArray) {
        int key;
        int moveNum = 0;
        long starttime = System.currentTimeMillis();
        System.out.println(starttime);
        for(int i = 0; i < sortArray.length; i++) {
            key = sortArray[i];
            int j = i - 1;
            while(j >= 0 && key < sortArray[j]) {
                moveNum += 1;
                sortArray[j + 1] = sortArray[j];
                j--;
            }
            sortArray[j + 1] = key;
        }
        System.out.println(System.currentTimeMillis());
        System.out.println("花费时间为:" + (System.currentTimeMillis() - starttime));
        System.out.println("移动次数:" + moveNum);
        return sortArray;
    }
}

  关于循环不等式,我们必须证明三条性质:
  初始化:循环的第一次迭代,为真
  保持:循环的某次迭代之前他为真,下次迭代之前还为真
  终止:有利于证明算法是正确的
二.分析算法
  这里先来谈几个概念。
  输入规模:依赖于研究的问题
  算法运行时间:执行的基本操作数或步数。
  最坏情况:对规模为n的任何输入,算法的最长运行时间
  
  我们往往集中于求最坏情况,其原因为:
    1.一个算法的最坏情况运行时间给出了任何输入的运行时间的一个上界。
    2.对某些算法,最坏情况经常出现。
    3.“平均情况”往往与最坏情况大致一样差。
  这里再给出书中课后习题的答案。

题目:存储在数组A中的n个数,首先找出最小的一个数与A[1]进行交换,再找出次小的与A[2]交换,直到数组以升序排列?

for i = 1 to A.length - 1
    index = i
    for j = i + 1 to A.length
        if A[index] > A[j]
            index = j
    exchange A[i] with A[index]

分治法的思想:将原问题分解为几个规模较小的类似原问题的子问题,递归的解决这些子问题,然后合并这些子问题,然后再合并这些子问题的解来建立原问题的解。

猜你喜欢

转载自blog.csdn.net/u010986518/article/details/80474031