主要排序算法java实现

整理一下主要的内部排序算法,脑子快秀逗了~

/**
 * java内部排序
 * @author leefelix
 *
 */
public class Sort {
	
	/**
	 * 冒泡排序
	 * 原理:从头扫描待排序元素,依次对相邻元素进行比较,将大值后移。每经过一趟排序后,最大值处于最尾端,下一次排序就比较到该元素即可。
	 * 注:对n个元素进行冒泡排序,总共进行n-1趟。第1趟需要比较n-1次,第2趟需要n-2次...
	 * 时间复杂度:O(N2)
	 * @param t
	 */
	public static <T extends Comparable<? super T>> void bubbleSort(T[] t){
		for(int i=0;i<t.length;i++){
			for(int j=0;j<t.length-i-1;j++){
				if(t[j].compareTo(t[j+1])>0){
					T tmp = t[j];
					t[j]=t[j+1];
					t[j+1] = tmp;
				}
			}
		}
	}

	/**
	 * 插入排序
	 * 原理:插入排序由n-1趟排序组成。对于p=1到n-1趟,插入排序保证从位置0到位置p上的元素为已排序状态。
	 * 时间复杂度:O(N2)
	 * @param t
	 */
	public static <T extends Comparable<? super T>> void insertSort(T[] t){
		int j;
		for(int i=0;i<t.length;i++){
			T tmp = t[i];
			for(j=i;j>0&&tmp.compareTo(t[j-1])<0;j--){
				t[j] = t[j-1];
			}
			t[j]=tmp;
		}
	}
	
	/**
	 * 希尔排序(缩减增量排序)
	 * 原理:希尔排序通过比较一定间隔的元素来工作;各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。
	 * 注:希尔排序的远行时间依赖于增量序列的选择。
	 * 时间复杂度:使用希尔增量的最坏情形运行时间为O(N2)
	 * @param t
	 */
	public static <T extends Comparable<? super T>> void shellSort(T[] t){
		int j;
		for(int gap = t.length/2;gap>0;gap /= 2)
			for(int i=0;i<t.length;i++){
				T tmp = t[i];
				for(j=i;j>gap&&tmp.compareTo(t[j-gap])<0;j -=gap){
					t[j] = t[j-gap];
				}
				t[j]=tmp;
			}
	}
	
	/**
	 * 归并排序
	 * 原理:合并两个已排序的表
	 * 时间复杂度:最坏运行时间O(N*logN)
	 * @param t
	 */
	public static <T extends Comparable<? super T>> void mergeSort(T[] t){
		T[] tmpArray = (T[])new Comparable[t.length];
		mergeSort(t, tmpArray, 0, t.length-1);
	}
	
	private static <T extends Comparable<? super T>> void mergeSort(T[] t, T[] tmpArray, int left, int right){
		if(left<right){
			int center = (left+right)/2;
			mergeSort(t, tmpArray, left, center);
			mergeSort(t, tmpArray, center+1, right);
			merge(t, tmpArray, left, center+1, right);
		}
	}
	
	private static <T extends Comparable<? super T>> void merge(T[] t, T[] tmpArray, int leftPos, int rightPos, int rightEnd){
		int leftEnd = rightPos - 1;
		int tmpPos = leftPos;
		int numElements = rightEnd - leftPos +1;
		
		while(leftPos<=leftEnd&&rightPos<=rightEnd){
			if(t[leftPos].compareTo(t[rightPos])<0)
				tmpArray[tmpPos++]=t[leftPos++];
			else
				tmpArray[tmpPos++]=t[rightPos++];
		}
		
		while(leftPos<=leftEnd){
			tmpArray[tmpPos++] = t[leftPos++];
		}
		
		while(rightPos<=rightEnd){
			tmpArray[tmpPos++] = t[rightPos++];
		}
		
		//具体实现时,可以考虑用native方法实现数组拷贝
		for(int i=0;i<numElements;i++,rightEnd--){
			t[rightEnd] = tmpArray[rightEnd];
		}
	}
	
	/**
	 * 快速排序
	 * 原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的数据都要小,然后再按此方法对这两部分数据进行快速排序,整个过程递归进行。
	 * 时间复杂度:快速排序的运行时间等于两个递归调用的运行时间加上花费在分割上的线性时间(枢纽元的选取仅花费常数时间)
	 * 平均运行时间:O(N*logN)
	 * 最坏运行时间:O(N2)
	 * @param t
	 */
	public static <T extends Comparable<? super T>> void quickSort(T[] t){
		quickSort(t,0,t.length-1);
	}
	
	private static <T extends Comparable<? super T>> void quickSort(T[] t, int left, int right){
		final int CUTOFF = 3;
		if(left + CUTOFF <= right){
			T pivot = median3(t, left, right);
			int i = left, j = right - 1;
			for(;;){
				while(t[++i].compareTo(pivot)<0){}
				while(t[--j].compareTo(pivot)>0){}
				if(i<j)
					swap(t, i, j);
				else
					break;
			}
			
			swap(t, i, right-1);//restore pivot
			
			quickSort(t, left, i-1);
			quickSort(t, i+1, right);
		}else{
			insertSort(t);
		}
	} 
	
	private static <T extends Comparable<? super T>> T median3(T[] t, int left, int right){
		int center = (left + right)/2;
		if(t[center].compareTo(t[left])<0)
			swap(t,left,center);
		if(t[right].compareTo(t[left])<0)
			swap(t,left,right);
		if(t[right].compareTo(t[center])<0)
			swap(t,center,right);
		
		swap(t,center,right-1);
		return t[right-1];
	}
	
	/**
	 * 堆排序
	 * 原理:堆排序是一种选择排序方法,是树型选择排序的改进;根结点的值大于左右子树,称之为大顶堆,若根结点都小于左右子树,称之为小顶堆
	 * 堆是一个完全二叉树,堆排序过程(1):初建堆(2):调整堆
	 * 调整堆:第一次,取出堆顶元素与R[n]进行交换,然后从根结点开始调整堆,根结点与左右孩子中较大者交换,这样,左右子树的堆会被破坏,继续进行上述操作,直到叶子结点为止。第二次,取出堆顶元素与R[n-1]交换,然后调整堆。
	 * 时间复杂度:O(N*logN)
	 * @param t
	 */
	public static <T extends Comparable<? super T>> void heapSort(T[] t){
		for(int i=t.length/2;i>=0;i--)
			percDown(t, i, t.length);
		for(int i=t.length-1;i>0;i--){
			swap(t,0,i);
			percDown(t, 0, i);
		}
	}
	
	private static <T extends Comparable<? super T>> void swap(T[] t,int start, int max){
		T tmp = t[start];
		t[start] = t[max];
		t[max] = tmp;
	}
	
	private static int leftChild(int i){
		return 2*i+1;
	}
	private static <T extends Comparable<? super T>> void percDown(T[] t, int i, int n){
		int child;
		T tmp;
		for(tmp=t[i];leftChild(i)<n;i=child){
			child = leftChild(i);
			if(child!=n-1&&t[child].compareTo(t[child+1])<0)
				child++;
			if(tmp.compareTo(t[child])<0)
				t[i]=t[child];
			else
				break;
		}
		t[i]=tmp;
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] a = {"lrq","hello","word","addidas"};
		
		Sort.quickSort(a);
		for(String tmp:a){
			System.out.println(tmp);
		}
	}

}

点赞