常见排序的java代码

<span style="font-family: Arial, Helvetica, sans-serif;">import java.util.ArrayList;</span>


public class AllSorts {

	public static void main(String[] args) {
		int[] a = {49,38,65,97,49,76};
		print(a);
		//insertSort(a);
		//shellSort(a);
		//selectSort(a);
		//bubbleSort(a);
		//quickSort(a, 0, a.length-1);
		//heapSort(a);
		//mergerSort(a);
		radixSort(a);
		print(a);
		
		
	
	}
	
	
	public static void print(int[] a){
		String s = "";
		for(int i=0;i<a.length;i++){
			s = s+a[i];
			s = s+" ";
		}
		System.out.println(s);
	}
	
//***************************************************************************	
	//插入排序(稳定排序),时间复杂度为O(n^2),空间复杂度为O(1),
	public static void insertSort(int[] a){
		for(int i=1;i<a.length;i++){
			int j = i-1;
			int temp = a[i];
			for(;j>=0 && a[j]>temp;j--){
				a[j+1] = a[j];
			}			
			a[j+1] = temp;
		}
	}
	
	
//***************************************************************************	
	//希尔排序(不稳定),时间复杂度时间复杂度 平均时间 O(nlogn) 最差时间O(n^s) 1<s<2;其实就是分组的插入排序,
	//由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,
	//相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。
	public static void shellSort(int[] a){
	 double d1 = a.length;
	 int temp = 0;
	 while(true){
		 d1 = Math.ceil(d1/2);
		 int d = (int) d1;
		 for(int x=0;x<d;x++){
			 for(int i=x+d;i<a.length;i+=d){
				 int j = i-d;
				 temp = a[i];
				 for(;j>=0 && temp<a[j];j-=d){
					 a[j+d] = a[j];
				 }
				 a[j+d] = temp;
			 }
		 }
		 
		 if(d == 1){
			 break;
		 }
	 }
		
	}	
	
//***************************************************************************	
	//选择排序(不稳定),时间复杂度O(n^2),空间O(1)
	//就是从第二个元素开始,每次选择剩下中的最小的,和剩下中的第一个交换
	//举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,
	//所以选择排序不是一个稳定的排序算法
	public static void selectSort(int[] a){
		//position用来记录剩下元素最小值的下标
		
		for(int i=0;i<a.length-1;i++){
			 int j = i+1;
			 //temp用来记录最小值,position用来记录最小值下标
			 int position = i;
			 int temp = a[i];
			 for(;j<a.length;j++){
				if(temp>a[j]){
					position = j;
					temp = a[j]; 
				}
			 }
			 a[position] = a[i];
			 a[i] = temp;			
		}
	}
	
	
//***************************************************************************	
	//冒泡排序(稳定),时间O(n^2),空间O(1)
	public static void bubbleSort(int[] a){
		//position用来记录剩下元素最小值的下标
		//temp记录最小值
		for(int i=0;i<a.length-1;i++){
			for(int j=0;j<a.length-1-i;j++){
				if(a[j]>a[j+1]){
					int temp = a[j];
					a[j] = a[j+1];
					a[j+1] =temp;
				}
			}
		}
	}
	
//***************************************************************************	
	//快排(不稳定),时间复杂度O(nlgn),空间复杂度O(lgn)
	public static void quickSort(int[] a,int left,int right){
		if(left>right) return ;
		//temp 就是划分左右的基准值
		int temp = a[left];
		int i = left;
		int j = right;
		while(i!=j){
			//要从右向左找
			while(a[j]>=temp && i<j){
				j--;
			}
			
			while(a[i]<=temp && i<j){
				i++;
			}
			if(i<j){
				int t = a[i];
				a[i] = a[j];
				a[j] = t;
			}	
		}
		//此时i=j,交换基准值,交换后,a[i]就是分界值,再分别对a[i]左右进行快排
		a[left] = a[i];
		a[i] = temp;
		
		//对右边进行快排
		quickSort(a,i+1,right);
		//对左边进行快排
		quickSort(a, left, i-1);
	}
	
	
//***************************************************************************
	//堆排序(不稳定),时间复杂度O(nlgn),空间O(1)
	//堆排序是不稳定的:
	//比如:3 27 36 27,建最小堆
	//如果堆顶3先输出,则,第三层的27(最后一个27)跑到堆顶(即3和最后一个27交换),
	//然后堆稳定,继续输出堆顶,是刚才那个27,这样说明后面的27先于第二个位置的27输出,不稳定。
	public static void heapSort(int[] a){
		int arrayLength = a.length;
		//循环建堆,和最后一个交换,并不断缩小重建堆所需数组的大小,直到只剩下1个为止
		for(int i=0;i<arrayLength-1;i++){
			buildMaxHeap(a,arrayLength-1-i);
			swap(a,0,arrayLength-1-i);
		}
	}
	
	public static void buildMaxHeap(int[] a,int lastIndex){
		for(int i=(lastIndex-1)/2;i>=0;i--){
			int k = i;
			while(k*2+1<=lastIndex){
				int biggerIndex = 2*k+1;
				if(biggerIndex+1<lastIndex){
					if(a[biggerIndex]<a[biggerIndex+1]){
						biggerIndex++;
					}

				}
				if(a[k]<a[biggerIndex]){
					swap(a,k,biggerIndex);
					k = biggerIndex;
				}else{
					break;
				}
			}
		}
	}
	
	public static void swap(int[] a,int m,int n){
		int temp = a[m];
		a[m] = a[n];
		a[n] = temp;
	}
//***************************************************************************
	//归并排序(稳定的),时间复杂度为O(nlgn),空间复杂度为O(n)
	public static void mergerSort(int[] a){
		sort(a,0,a.length-1);
	}
	
	public static void sort(int[] a,int left,int right){
		if(left<right){
			int center = (left+right)/2;
			sort(a,left,center);
			sort(a,center+1,right);
			merge(a,left,center,right);
		}
	}
	
	public static void merge(int[] a,int left,int center,int right){
		//合并的时候用到了临时数组,所以空间复杂度才为O(n)
		int[] tmpArr = new int[a.length];
		//temp用来当合并完成后,将临时数组中的元素逐个复制覆盖原数组元素,所以temp记录开始的地方
		int temp = left;
		int mid = center+1;
		//third用来指示合并过程中,临时数组的下标
		int third = left;
		while(left<=center&&mid<=right){
			if(a[left]<=a[mid]){
				tmpArr[third++] = a[left++];
			}else{
				tmpArr[third++] = a[mid++];
			}
		}
		//将某一半里面多出来的,直接复制进去。
		while(left<=center){
			tmpArr[third++] = a[left++];
		}
		while(mid<=right){
			tmpArr[third++] = a[mid++];
		}
		
		//将临时数组中合并好的元素顺序再复制回(覆盖)原数组
		while(temp<=right){
			a[temp] = tmpArr[temp];
			temp++;
		}
	}
//***************************************************************************	
	public static void radixSort(int[] a){
		//首先确定要排序的趟数,即最大数的长度,例如最大数为100,就要排3趟
		//先找最大数
		int max = a[0];
		
		for(int i=0;i<a.length;i++){
			if(max<a[i]){
				max = a[i];
			}
		}
		//再找最大数的长度,也即需要排序的趟数
		int time = 0;
		while(max!=0){
			max = max/10;
			time++;
		}
		
		//建立10个list,即0-9
		
		ArrayList<ArrayList<Integer>> queue = new ArrayList<ArrayList<Integer>>();
		for(int i=0;i<10;i++){
			ArrayList<Integer> list = new ArrayList<Integer>();
			queue.add(list);
		}
		//进行time次重新分配排序
		for(int i=0;i<time;i++){
			for(int j=0;j<a.length;j++){
				//得到要放入的桶号
				int x = a[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);
				queue.get(x).add(a[j]);
				
			}
			int count = 0;
			//再将桶中的元素重新排成队
			for(int k=0;k<10;k++){
				while(queue.get(k).size()>0){
					a[count++] = queue.get(k).get(0);
					queue.get(k).remove(0);
					
				}
			}
		}
		
	}
}

	

猜你喜欢

转载自blog.csdn.net/huakaiba/article/details/47816445
今日推荐