本科生码农应该会的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实现,不包含变换!