算法导论 第2章 算法基础

//插入排序
package InsertionSort;

import java.util.Vector;
import java.util.Scanner;

public class InsertionSort {
    Scanner scn=new Scanner(System.in);
    Vector<Double> v=new Vector<Double>();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        InsertionSort s=new InsertionSort();
        System.out.print("请输入要排序的数以空格区分:");
        String array = s.scn.nextLine();
        String[] arraySort=array.split(" ");
        for(int i=0;i<arraySort.length;++i)
            s.v.add(Double.parseDouble(arraySort[i]));
        s.scn.close();
        s.Sort();
        System.out.print("排序后的数列为:");
        for(int i=0;i<s.v.size();++i)
            System.out.print(s.v.get(i).toString()+" ");
    }
    
    public InsertionSort(){
        
    }
    
    public InsertionSort(Vector<Double> v){
        this.v=v;
    }
    
    public void Sort(){
        for(int i=1;i<v.size();++i){
            int j=i-1;
            double key=v.get(i);
            while(j>=0 && v.get(j)>key){
                v.set(j+1, v.get(j));
                --j;
            }
            v.set(j+1, key);
        }
    }

}

/*
 写出针对这个问题的线性查找的伪代码,它顺序地扫描整个序列以查找V。
 利用循环不变式证明算法的正确性。确保所给出的循环不变式满足三个必要的性质。  
伪代码如下:  
LINEAR-SEARCH(A,V)      
    flag←0 
    for i←1 to length[A]          
        do if A[i]==V             
            then print i              
            flag←1      
        if flag==0 
            then print NIL 
 
循环不变式的证明如下:  
初始化:首先,先来证明在第一轮迭代之前,它是成立的。
此时,flag初始化为0,表示未找到这样一个小标i,使得A[i]=V.若为1,则表示已找到一个或多个这样的下标。
那么,很显然,在还未开始之前flag=0是正确的,也就证明了循环不变式在循环的第一轮迭代开始之前是成立的。  

保持:接下来证明每一轮循环都能使循环不变式保持成立。
我们看到,在第一个for循环体内,随着i逐个从1到遍历完整个数列的过程中,只要有一个下标i,使得A[i]等于V,那么在输出i的同时,将flag重新标记为1,表示已找到。
无论接下来是否还有这样满足条件的i出现,flag的值不变,仍为1,反之,若遍历完之后,没有找到这样的一个i,那么flag在这个for循环中未做任何改变,仍为0。
所以,循环不变式的第二个性质也成立。  

终止:对此线性查找算法来说,当i大于length[A]的值(即遍历完整个A数列后),for循环结束。
这时,如果flag未改变(即flag=0),则说明未能找到这样的下标i,输出NIL;反之,若已在for循环中被修改为1,则不会运行此步语句,这也就意味着该算法是正确的。
 */
//二路归并排序
package MergeSort;

import java.util.Scanner;
import java.util.Vector;

public class MergeSort {
    Scanner scn=new Scanner(System.in);
    Vector<Double> v=new Vector<Double>();
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MergeSort s=new MergeSort();
        System.out.print("请输入要排序的数以空格区分:");
        String array = s.scn.nextLine();
        String[] arraySort=array.split(" ");
        for(int i=0;i<arraySort.length;++i)
            s.v.add(Double.parseDouble(arraySort[i]));
        s.scn.close();
        s.Sort(1,s.v.size());
        System.out.print("排序后的数列为:");
        for(int i=0;i<s.v.size();++i)
            System.out.print(s.v.get(i).toString()+" ");
    }
    
    public void Merge(int p,int q,int r) {
        int pl=0;
        int pr=0;
        Vector<Double> L=new Vector<Double>();
        Vector<Double> R=new Vector<Double>();
        for(int i=0;i<q-p+1;++i)
            L.add(v.get(p+i-1));
        L.add(Double.MAX_VALUE);
        for(int i=0;i<r-q;++i)
            R.add(v.get(q+i));
        R.add(Double.MAX_VALUE);
        for(int i=p-1;i<r;++i){
            if(L.get(pl)<R.get(pr)){
                v.set(i, L.get(pl));
                ++pl;
            }
            else{
                v.set(i, R.get(pr));
                ++pr;
            }
        }
    }
    
    public void Sort(int p,int r) {
        if(p<r){
            int q=(r+p)/2;
            Sort(p,q);
            Sort(q+1,r);
            Merge(p,q,r);
        }
    }

}
原文地址:https://www.cnblogs.com/mubu/p/6297997.html