常用排序算法——插入排序,快速排序,归并排序,堆排序,计数排序

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]+" ");
		}

	}

}

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