常用排序算法——插入排序,快速排序,歸併排序,堆排序,計數排序

public class SortTest {
	
	public static void swap(int[] nums, int i, int j){
		int temp = nums[i];
		nums[i] = nums[j];
		nums[j] = temp;
	}
	//插入排序,時間複雜度最差,平均O(n^2);最好O(n),空間複雜度1
	public static void InsertSort(int[] nums){
		InsertSort(nums, 0, nums.length);
	}
	private static void InsertSort(int[] nums, int start, int end){
		int s1=0,s2=0,k =0;
		for(s1 = start+1; s1 < end; s1 ++){
			//爲nums[i]在前面的nums[0...i-1]有序區間中找一個合適的位置  
	        for (s2 = s1 - 1; s2 >= 0; s2--)
	            if (nums[s2] < nums[s1])  
	                break;  	  
	        //如找到了一個合適的位置  
	        if (s2 != s1 - 1)  
	        {  
	            //將比nums[i]大的數據向後移  
	            int temp = nums[s1];  
	            for (k = s1 - 1; k > s2; k--)  
	                nums[k + 1] = nums[k];  
	            //將nums[i]放到正確位置上  
	            nums[k + 1] = temp;  
	        }  
		}
	}
	//快排,時間複雜度平均O(nlogn),最壞O(n^2),空間複雜度O(logn),時間複雜度體現在遞歸棧上
	public static void QuickSort(int[] nums){
		QuickSort(nums,0,nums.length);
	}
	private static void QuickSort(int[] nums, int start, int end){
		int i = start;
		int j = end-1;
		//start爲描點數據
		while(i<j){
			while(i<j && nums[i] <= nums[j])j--;
			if(i<j){
				swap(nums,i,j);
			}
			while(i<j && nums[i] <= nums[j])i++;
			if(i<j){
				swap(nums,i,j);
			}
		}//分割數組,迭代排序
		if(i-start > 1){
			if(i-start < 10){//當數據量較小時,使用插入排序效率更高
				InsertSort(nums, start, i);
			}
			else
				QuickSort(nums, start, i-1);
		}
		if(end-i > 1){
			if(end-i < 10){
				InsertSort(nums, i+1, end);
			}
			else
				QuickSort(nums, i+1, end);
		}
	}
	//歸併排序,時間複雜度	最差,平均O,最好O(nlogn),空間複雜度 O(n)
	public static void MergeSort(int[] nums){
		MergeSort(nums,0,nums.length);
	}
	private static void MergeSort(int[] nums, int start, int end){
		if(start+10<end){
			int mid = (start+end)/2;
			MergeSort(nums, start, mid);
			MergeSort(nums, mid, end);
			//合併歸併項
			int i = start, j = mid;
			int[] arrayTemp = new int[end-start];//額外申請空間
			int k = 0;
			while(i < mid && j < end){
				if(nums[i] > nums[j]){
					arrayTemp[k++] = nums[j++];
				}
				else{
					arrayTemp[k++] = nums[i++];
				}
			}
			if(i<mid){
				for(j = i; j < mid; j ++)arrayTemp[k++]=nums[j];
			}
			if(j<end){
				for(i = j; i < end; i ++)arrayTemp[k++] = nums[i];
			}
			System.arraycopy(arrayTemp, 0, nums, start, arrayTemp.length);//複製數組
		}
		else{
			InsertSort(nums, start, end);
		}
	}
	//堆排序,時間複雜度最差,平均O(n),最好O(nlogn),空間複雜度  1
	public static void HeapSort(int[] nums){
		for (int i = nums.length / 2 - 1; i >= 0; i--)  
	        HeapSortFixup(nums, i, nums.length);//生成最大堆
		for (int i = nums.length - 1; i >= 1; i--){  
		    swap(nums, i, 0);  //每次將最大數nums[0]放在最後,遍歷可使得數組從下到大有序
		    HeapSortFixup(nums, 0, i);  
		}  
	}
	private static void HeapSortFixup(int a[], int i, int n) //從下向上整理堆
	{  
	    int j, temp;  
	  
	    temp = a[i];  
	    j = 2 * i + 1;  
	    while (j < n)  
	    {  
	        if (j + 1 < n && a[j + 1] > a[j]) //在左右孩子中找最小的  
	            j++;  
	  
	        if (a[j] <= temp)  
	            break;  
	  
	        a[i] = a[j];     //把較小的子結點往上移動,替換它的父結點  
	        i = j;  
	        j = 2 * i + 1;  
	    }  
	    a[i] = temp;  
	} 
	//計數排序,時間複雜度複雜度爲Ο(n+k)(其中k是整數的範圍),空間複雜度O(n)
	public static void CountSort(int[] nums){
		CountSort(nums, 0, nums.length, 10);
	}
	private static void CountSort(int[] nums, int start, int end, int count){//count是nums數組的值域
		int[] c = new int[count];//c[i]=值域範圍內nums數組值爲i的個數
		int[] b = new int[end-start];//額外空間,用於數組值的複製
		for(int i=0; i < count; i ++)
			c[i]=0;
		for(int j=start; j < end; j ++)//計算相應元素的個數
			c[nums[j]] = c[nums[j]]+1;
		for(int i=1; i < count; i ++)//計算元素的順序
			c[i]=c[i]+c[i-1];
		for(int j=end-1; j >= start; j --){//從後向前,將數組元素插入相應位置
			b[c[nums[j]]-1] = nums[j];
			c[nums[j]] -= 1;
		}
		System.arraycopy(b, 0, nums, start, b.length);
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] nums = {1,3,4,5,2,7,6,9};
		//QuickSort(nums);
		//InsertSort(nums);
		//MergeSort(nums);
		//HeapSort(nums);
		//CountSort(nums);
		for(int i = 0; i < nums.length; i ++){
			System.out.print(nums[i]+" ");
		}

	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章