本科生码农应该会的6种基本排序算法(《数据结构与算法》)

  如题,本文就《数据结构与算法》书中的7种基本算法做了一个java工程,此处结合工程启发大家其实很多东西做起来并不难,关键在于思想;工程利用coding中常用的继承思想使coder只需关注最重要的算法编码,而不用为每个算法的test一遍遍的复制粘贴:

1.工具类:

ReadFromCmd
package util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;



public class ReadFromCmd {
    private BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
    private BufferedWriter bout = new BufferedWriter(new OutputStreamWriter(System.out));
    public int[] read(){
        int[] res = null;
        try {
            String str = bin.readLine();
            String[] strs = str.split(" ");
            res = new int[strs.length];
            for (int i = 0; i < strs.length; i++) {
                res[i] = Integer.valueOf(strs[i]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;
    }
    
    public void write(String out){
        try {
            bout.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public void close(){
        try {
            bin.close();
            bout.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.基类:

ISort
package sorts;

import java.util.Arrays;

import util.ReadFromCmd;

public abstract class ISort {
    protected int[] needSort = new int[10];

    public String getPrint(){
        return Arrays.toString(needSort);
    }

    public ISort(int[] needSort) {
        super();
        this.needSort = needSort;
    }
    
    public ISort() {
    }
    
    abstract void sort(int[] sortArray);
    
    public void test(){
        ReadFromCmd util = new ReadFromCmd();
        System.out.println("please give a int array using \" \" to split to test:");
        this.needSort = util.read();
        long startTime = System.currentTimeMillis();
        sort(needSort);
        long endTime = System.currentTimeMillis();
        System.out.println("the result is:"+getPrint()+" cose time is "+(endTime-startTime)+" ms");
        util.close();
    }
    
    public void test(int[] sortArray){
        long startTime = System.currentTimeMillis();
        this.needSort = sortArray;
        sort(needSort);
        long endTime = System.currentTimeMillis();
        System.out.println("the result is:"+getPrint()+" cose time is "+(endTime-startTime)+" ms");
    }
}

3.各种排序子类:

  1).冒泡:

BubbleSort
package sorts;

public class BubbleSort extends ISort {

    public BubbleSort() {
        super();
    }
    
    public void sort(int[] sortArray){
        for (int i = sortArray.length - 1; i > 0; i --) {
            for (int j = 0; j < i; j++) {
                if(sortArray[j] > sortArray[j + 1]){
                    int tmp = sortArray[j];
                    sortArray[j] = sortArray[j + 1];
                    sortArray[j + 1] = tmp;
                }
            }
        }
    }
    
    public static void main(String[] args) {
        BubbleSort bsort = new BubbleSort();
        bsort.test();
    }
}

  2).插入:

InsertSort
package sorts;

public class InsertSort extends ISort{

    @Override
    void sort(int[] sortArray) {
        for (int i = 0; i < sortArray.length; i++) {
            //记录i出错
            int j = i;
            int base = sortArray[i];
            
            while(j > 0 && sortArray[j - 1] > base){
                sortArray[j] = sortArray[j - 1];
                j --;
            }
            
            sortArray[j] = base;
        }
    }
    
    public static void main(String[] args) {
        InsertSort sort = new InsertSort();
        sort.test();
    }
}

  3).归并排序

MergeSort
package sorts;

public class MergeSort extends ISort{
    private int[] theArray;
    
    @Override
    void sort(int[] sortArray) {
        theArray = new int[sortArray.length];
        recMergeSort(sortArray, 0, sortArray.length - 1);
    }
    
    /**
     * 对数组一份为2进行递归排序,同时,当两个小组排序完成后,对整体进行归并排序
     * 
     * 典型的递归格式
     * @param sortArray
     * @param off
     * @param end
     */
    private void recMergeSort(int[] sortArray, int off, int end){
        //off == end的判断条件出错
        if(off == end){
            return;
        } else {
            int mid = (off + end) / 2;
            recMergeSort(sortArray, off, mid);
            recMergeSort(sortArray, mid + 1, end);
            
            mergeSort(sortArray, off, mid, end);
        }
    }
    
    private void mergeSort(int[] sortArray, int off, int mid, int end){
        int index = 0;
        int firstIndex = off;
        int secondIndex = mid + 1;
        int len = end - off + 1;
        /**
         * 如果完成全部的归并,则:
         *     判断第一段数组中的值跟第二段中的大小,取小的存入中间数据
         * 
         * 如果第一段全部排序完,则直接拷贝第二段的数据至中间数组
         */
        while(index < len - 1){
            if(sortArray[firstIndex] > sortArray[secondIndex]){
                theArray[index ++] = sortArray[secondIndex ++];
            } else {
                theArray[index ++] = sortArray[firstIndex ++];
            }
            
            if(firstIndex > mid){
                for (int i = secondIndex; i <= end; i++) {
                    theArray[index ++] = sortArray[secondIndex ++];
                }
            }
            
            if(secondIndex > end){
                for (int i = firstIndex; i <= mid; i++) {
                    theArray[index ++] = sortArray[firstIndex ++];
                }
            }
        }
        
        /**
         * 将中间数组中的值拷贝到原数组中去
         */
        for (int i = 0; i < len; i++) {
            sortArray[off + i] = theArray[i];
        }
    }
    
    public static void main(String[] args) {
        MergeSort sort = new MergeSort();
        sort.test();
    }
}

  4).快速排序

QuickSort
package sorts;

public class QuickSort extends ISort{

    @Override
    void sort(int[] sortArray) {
        quickSort(sortArray, 0, sortArray.length - 1);
    }
    
    public void quickSort(int[] needSort, int left, int right){
        int preLeft = left;
        int preRight = right;
        int base = needSort[left];

        while(left < right){
            while(left < right && needSort[right] > base){
                right --;
            }
            needSort[left] = needSort[right];
            
            while(left < right && needSort[left] < base){
                left ++;
            }
            needSort[right] = needSort[left];
        }
        needSort[left] = base;
        
        //这里的大小注意,如果left前面只有一个了 也不用比较
        if(left > preLeft + 1){
            quickSort(needSort, preLeft, left - 1);
        }
        
        if(right < preRight - 1){
            quickSort(needSort, left + 1, preRight);
        }
    }
    
    public static void main(String[] args) {
        QuickSort test = new QuickSort();
        test.test();
    }
}

  5).选择排序

SelectSort
package sorts;

/*
 * 每一次选出最大的那个与尾部数据进行交换
 */
public class SelectSort extends ISort{

    @Override
    void sort(int[] sortArray) {
        for (int i = sortArray.length - 1; i > 0; i --) {
            int base = 0;
            for (int j = 0; j <= i; j++) {
                if(sortArray[base] < sortArray[j]){
                    base = j;
                }
            }
            
            if(base != i){
                int tmp = sortArray[i];
                sortArray[i] = sortArray[base];
                sortArray[base] = tmp;
            }
        }
    }

    public static void main(String[] args) {
        SelectSort sort = new SelectSort();
        sort.test();
    }
}

  6).希尔排序:

ShellSort
package sorts;

public class ShellSort extends ISort{

    @Override
    void sort(int[] sortArray) {
        int len = sortArray.length;
        int h = 0;
        if(len < 5){
            h = 1;
        } else if(len < 14){
            h = 4;
        } else if(len < 41){
            h = 13;
        } else if(len < 122){
            h = 40;
        } else if(len < 365){
            h = 121;
        } else if(len < 1093){
            h = 364;
        } else if(len < 3281){
            h = 1093;
        } else if(len < 9842){
            h = 3280;
        } else if(len < 29523){
            h = 9841;
        } else {
            System.out.println("the array's length is too big to sort, please up the h");
            return;
        }
        shellSort(sortArray, h);
    }
    
    private void shellSort(int[] sortArray, int h){
        while(h != 0){
            for (int i = 0; i < sortArray.length; i++) {
                int j = i;
                
                for (;j < sortArray.length; j = j + h){
                    int k = j;
                    //用base存下要比较的数,以免移动的时候被覆盖
                    int base = sortArray[j];
                    
                    //k >= h这里出错过
                    while(k >= h && sortArray[k - h] > base){
                        sortArray[k] = sortArray[k - h];
                        
                        k -= h;
                    }
                    
                    //找到所在的位置后,赋值
                    sortArray[k] = base;
                }
                
                if(1 == h){
                    return;
                }
            }
            h = (h - 1) / 3;
        }
        
        
    }
    
    public static void main(String[] args) {
        ShellSort sort = new ShellSort();
        sort.test();
    }
}

4.所有方法为原始思想的coding实现,不包含变换!

原文地址:https://www.cnblogs.com/uttu/p/2908793.html