八大排序算法模板,拿去吧你

191 阅读2分钟

本文的内容是对算法(Algorithms)第四版中的算法源码的总结及部分补充

主类(排序的通用函数)

public class Example {
	private static boolean less(Comparable v, Comparable w) {
		return v.compareTo(w) < 0;
	}
	private static void exch(Comparable[] a, int i, int j) {
		Comparable t = a[i];
		a[i] = a[j];
		a[j] = t;
	}
	private void show(Comparable[] a) {
		//在单行中打印数组
		for(int i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}
		System.out.println();
	}
	public static boolean isSorted(Comparable[] a) {
		for(int i = 1; i < a.length; i++) {
			if(less(a[i], a[i - 1])) {
				return false;
			}
		}
		return true;
	}
    
    /***  
    public static class Select{
    }
    public static class Insert{
    }
    ......
    ****/
    
}

1、选择排序-select_sort

public static class Select{
		public static void sort(Comparable[] a) {
			int N = a.length;
			for(int i = 0; i < N; i++) {
				int min = i;
				for(int j = i + 1; j < N; j++) {
					if(less(a[min], a[j])) {
						min = j;
					}
				}
				exch(a, i, min);
			}
		}
	}

2、插入排序-insert_sort

public static class Insert{
		public static void sort(Comparable[] a) {
			int N = a.length;
			for(int i = 1; i < N; i++) {
				for(int j = i; j > 0 && less(a[j], a[j - 1]); j--) {
					exch(a, j ,j - 1);
				}
			}
		}
	}

3、冒泡排序-bubble_sort

public static class Bubble{
		public static void sort(Comparable[] a) {
			int N = a.length;
			for(int i = 0; i < N - 1; i++) {
				for(int j = 0; j < N - 1 - i; j++) {
					if(less(a[j + 1], a[j])) {
						exch(a, j, j +1);
					}
				}
			}
		}
	}

4、希尔排序-shell_sort

public static class Shell{
		public static void sort(Comparable[] a) {
			int N = a.length;
			int h = 1;
			while(h < N / 3) {
				h = h * 3 + 1;
			}
			while(h >= 1) {
				for(int i = h; i < N; i++) {
					for(int j = h; j >= h && less(a[j], a[j - h]); j -= h) {
						exch(a, j, j - h);
					}
				}
				h /= 3;
			}
		}
	}

5、归并排序-merge_sort

5.1、归并排序-(递归实现)

public static class Merge{
		private static Comparable[] aux;     //归并需要的辅助数组
		public static void sort(Comparable[] a) {
			aux = new Comparable[a.length];
			sort(a, 0, a.length - 1);
		}
		private static void sort(Comparable[] a, int lo, int hi) {
			if(lo >= hi) {
				return;
			}
			int mid = lo + (hi - lo) / 2;
			sort(a, lo, mid);         //将左半边排序
			sort(a, mid + 1, hi);     //将右半边排序
			merge(a, lo, mid, hi);    //归并
		}
		/*** 原地归并所需要的算法  ***/
		private static void merge(Comparable[] a, int lo, int mid, int hi) {
			int i = lo, j = mid + 1;
			for(int k = lo; k <= hi; k++) {
				aux[k] = a[k];
			}
			for(int k = lo; k <= hi; k++) {
				if(i > mid) {
					a[k] = aux[j++];
				}else if(j > hi) {
					a[k] = aux[i++];
				}else if(less(aux[i], aux[j])) {
					a[k] = aux[i++];
				}else {
					a[k] = aux[j++];
				}
			}
		}
	}

5.2、归并排序-自底向上

public static class MergeBu{
		private static Comparable[] aux;    //归并所需要的辅助数组
		public static void sort(Comparable[] a) {
			//进行lgN次两两归并
			int N = a.length;
			aux = new Comparable[N];
			for(int sz = 1; sz < N; sz = sz + sz) {
				for(int lo = 0; lo < N - sz; lo += sz + sz) {
					merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1));
				}
			}
		}
		/*** 原地归并所需要的算法  ***/
		public static void merge(Comparable[] a, int lo, int mid, int hi) {
			//代码同上
		}
	}

6、快速排序-quick_sort

public static class Quick{
		public static void sort(Comparable[] a) {
			//Collections.shuffle(a);   消除对输入的依赖  a类型需为List
			sort(a, 0, a.length - 1);
		}
		public static void sort(Comparable[] a, int lo, int hi) {
			if(lo >= hi) {
				return;
			}
			int j = partition(a, lo, hi); //找出切分元素的位置
			sort(a, lo, j - 1);           //将左半部分a[lo..j - 1]排序
			sort(a, j + 1, hi);           //将右半部分a[j + 1..hi]排序
		}
		public static int partition(Comparable[] a, int lo, int hi) {
			//将数组切分为a[lo..i - 1], a[i], a[i + 1, hi]
			int i = lo, j = hi + 1; //左右扫描的指针
			Comparable v = a[lo];   //切分元素
			while(true) {
				//扫描左右, 检查扫描是否结束并交换元素
				while(less(a[++i], v)) {
					if(i == hi) {
						break;
					}
				}
				while(less(v, a[--j])) {
					if(j == lo) {
						break;
					}
				}
				if(i >= j) {
					break;
				}
				exch(a, i, j);
			}
			exch(a, lo, j);   //将v = a[i]放入正确的位置
			return j;
		}
	}

三向切分的快速排序-quick3way

避免大量重复数字对函数的调用

public static class Quick3way{
		private static void sort(Comparable[] a) {
			sort(a, 0, a.length - 1);
		}
		private static void sort(Comparable[] a, int lo, int hi) {
			if(lo >= hi) {
				return;
			}
			int lt = lo, i = lo + 1, gt = hi;
			Comparable v = a[lo];
			while(i <= gt) {
				int cmp = a[i].compareTo(v);
				if(cmp < 0) {
					exch(a, lt++, i++);
				}else if(cmp > 0) {
					exch(a, i, gt--);
				}else {
					i++;
				}
			}   //满足 a[lo..lt - 1] < v = a[lt..gt] > a[gt + 1..hi]
			sort(a, lo, lt - 1);
			sort(a, gt + 1, hi);
		}
	}

7、堆排序-heap_sort

//大多数情况下堆排序下标是从1开始的,这样更方便,而且下标为0的地方也可以作为哨兵
	public static class Heap{
		private static void sort(Comparable[] a) {
			int N = a.length - 1;
			for(int k = N / 2; k >= 0; k--) {    //构造堆
				sink(a, k, N);
			}
			while(N > 0) {                       //销毁堆
				exch(a, 0, N--);
				sink(a, 0, N);
			}
		}
		//下沉    (自顶向下堆的有序化的实现) (小元素移至数组右端)
		private static void sink(Comparable[] a, int k, int N) {
			while(2 * k + 1 <= N) {
				int j = 2 * k + 1;
				if(j + 1 <= N && less(a[j], a[j + 1])) {
					j++;
				}
				if(!less(a[k], a[j])) {
					break;
				}
				exch(a, k , j);
				k = j;
			}
		}
	}

8、桶排序-bucket_sort

public static class Bucket{
		private final static int N = 100;  //假如数字大小在1-100之间
		private static int[] aux;
		public Bucket(){
			aux = new int[N + 1];
		}
		public void sort(int a[]) {
			for(int i : a) {
				aux[i]++;
			}
			int k = 0;
			for(int i = 0; i <= N; i++) {
				if(aux[i] > 0) {
					while(aux[i]-- > 0) {
						a[k++] = i;
					}
				}
			}
		}
	}

9、基数排序-radix_sort

基数排序在字符串的排序算法中用的比较多,后期的内容会涉及到···