主要的排序算法——Java实现

package cn.leilei.algorithm;

public class Sort {
	
	/**
	 * 内部排序算法
	 * 插入排序类:直接插入排序,希尔排序
	 * 选择排序类:选择排序,堆排序
	 * 交换排序类:冒泡排序,快速排序
	 * 归并排序
	 */
	
	
	
	/**
	 * 交换数组中的两个元素
	 * 方法名:swap<BR>
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @param i
	 * @param j
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void swap(int[] a,int i,int j){
		int t;
		
		t=a[i];
		a[i]=a[j];
		a[j]=t;
	}
	
	
	
	/****************稳定的*****************/
	
	
	
	/**
	 * 基本冒泡排序 
	 * 方法名:bubbleSort<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void bubbleSort(int[] a){
		
		for(int i=a.length-1; i > 0 ; i--){
			
			for(int j=0; j < i ;j++){
				
				if(a[j] > a[j+1])
					swap(a,j,j+1);
				
			}
		}
	}
	
	
	
	/**
	 * 改进冒泡排序 (不做无用功)
	 * 方法名:bubbleSortII<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void bubbleSortII(int[] a){
		
		boolean flag=false;
		
		for(int i=0; i < a.length-1&&!flag ; i++){//只有在没有排序的情况下,才继续循环
			
			flag=true;//设定排序标志
			
			for(int j=0; j < a.length-1-i ;j++){
				
				if(a[j] > a[j+1]){
					
					flag=false;//如果是没有排序,就重新设定标志
					
					swap(a,j,j+1);
				}
			}
		}
		
	}
	
	
	
	/**
	 * 改进冒泡排序 (记录犯罪现场)
	 * 方法名:bubbleSortIII<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void bubbleSortIII(int[] a){
		
		int m=a.length-1;
		
		int k,j;
		
		while(m>0){
			
			for(k=0,j=0;j < m;j++){
				
				if(a[j] > a[j+1]){
					swap(a,j,j+1);
					k = j;//记录交换位置
				}
				
			}
			m = k;//记录最后一个交换的位置
		}
		
	}
	
	
	
	/**
	 * 鸡尾酒排序  (双向的冒泡排序)
	 * 方法名:cocktailSort<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void cocktailSort(int[] a){
	    
	    for(int i = 0 ; i < a.length/2 ; i++){
	    	//将最小值排到队头
	        for(int j = i ; j < a.length-i-1 ; j++){
	        	
	            if(a[j] > a[j+1])
	            	swap(a,j,j+1);
	            
	        }
	        //将最大值排到队尾
	        for(int j = a.length-1-(i+1); j > i ; j--){
	        	
	            if(a[j] < a[j-1])
	            	swap(a,j,j+1);
	            
	        }
	    }
	    
	}
	
	
	
	
	/**
	 * 直接插入排序
	 * 方法名:insertSort<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void insertSort(int[] a){
		
		int i,j;
		
		for (i = 1; i < a.length; i++) {
			
			if(a[i] < a[i-1]){
				
				int temp=a[i];//待插入元素
				
				for (j = i-1; j>=0 && a[j]>temp; j--) {
					
					a[j+1]=a[j];//将大于temp的往后挪一位
					
				}
				
				a[j+1]=temp;
			}
		}
	}
	
	
	
	/**
	 * 归并排序(递归型)
	 * 方法名:mergeSort<BR>
	 * 时间复杂度: O(nlogn)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a:待排序数组
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void mergeSort(int[] a){
		
		int[] temp=new int[200];   //临时数组存放排序结果
		
		merge_Sort(a,temp,0,a.length-1);
		
	} 
	
	public static void merge_Sort(int[] a,int[] temp, int first, int last){
		
		if(first == last) //递归结束条件:当分组后只有一个数据时,表示有序,递归结束
			
			temp[first]=a[first];
		
		else{
			
			int mid=(first+last)/2;//分组
			
			merge_Sort(a,temp,first,mid);//递归将左边归并为有序
			merge_Sort(a,temp,mid+1,last);//递归将右边归并为有序
			mergeDo(a,temp,first,mid,last);//合并有序序列
		}
		
	}
	
	public static void mergeDo(int[] a, int[] temp,int first, int mid, int last){
		
		int i=first,j=mid+1;
		int m=mid,n=last;
		int k=0;
		
		while(i<=m && j<=n){
			
			if(a[i] <= a[j])//依次比较两个序列的数,谁小取谁,将a中数据从小到大并入temp中
				temp[k++] = a[i++];
			else
				temp[k++] = a[j++];
			
		}
		
		while(i <= m) //将剩余的a[i..m]并入到temp中
			temp[k++] = a[i++];
		
		while(j <= n) //将剩余的a[j..n]并入到temp中
			temp[k++] = a[j++];
		
		for(i=0;i<k;i++) //最后将合并后数组temp复制给a
			a[first+i] = temp[i];
		
	}
	
	
	
	/**
	 * 归并排序(非递归型)
	 * 方法名:mergeSortII<BR>
	 * 时间复杂度: O(nlogn)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a:待排序数组
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void mergeSortII(int[] a){
		
		int[] temp=new int[200];   //临时数组存放排序结果
		
		for(int k=1;k < a.length;k = 2*k)
			merge_SortII(a,temp,k,a.length);//将a中相邻长度为k的子序列两两归并
		
	}
	
	public static void merge_SortII(int[] a, int[] temp,int s,int n){
		//s:子序列长度,n:数组大小
		int i;
		
		for(i=0;i <= n-2*s;i+=2*s)
			mergeDo(a,temp,i,i+s-1,i+2*s-1);//两两归并
		
		if(i<n-s)//归并剩下的最后两个序列(数组可能不会正好被平分)
			mergeDo(a,temp,i,i+s-1,n-1);
		
	}
	
	
	
	/**
	 * 基数排序
	 * 方法名:radixSort<BR>
	 * 时间复杂度: O(n^k)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void radixSort(int[] a, int d){ //d表示最大的数有多少位

        int k = 0;
        int n = 1;
        int m = 1; //控制键值排序依据在哪一位
        
        int[][] temp = new int[10][a.length]; //数组的第一维表示可能的余数0-9
        int[] order = new int[10]; //数组orderp[i]用来表示该位是i的数的个数
        while(m <= d)
        {
            for(int i = 0; i < a.length; i++)
            {
                int lsd = ((a[i] / n) % 10);
                temp[lsd][order[lsd]] = a[i];
                order[lsd]++;
            }
            for(int i = 0; i < 10; i++)
            {
                if(order[i] != 0)
                    for(int j = 0; j < order[i]; j++)
                    {
                        a[k] = temp[i][j];
                        k++;
                    }
                order[i] = 0;
            }
            n *= 10;
            k = 0;
            m++;
        }
    }
	
	
	
	
	/****************不稳定的*****************/
	
	

	/**
	 * 选择排序
	 * 方法名:selectSort<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void selectSort(int[] a){
		
		for (int i = 0; i < a.length-1; i++) {
			
			int min=i;//将当前下标定义为最小值下标
			
			for (int j = i+1; j < a.length; j++) {
				
				if(a[j] < a[min])//如果有小于当前最小值的数据
					min = j;//将此下标赋给min
				
			}
			
			if(min != i)
				swap(a,i,min);//若找到最小值则交换数据
			
		}
	}
	
	
	
	/**
	 * 希尔排序 
	 * 方法名:shellSort<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void shellSort(int[] a){
		
		int i,j;
		int gap=a.length;
		
		do{
			gap=gap/3 + 1;//增量
			
			for (i = gap; i < a.length; i++) {//分组进行直接插入排序
				
				if(a[i] < a[i-gap]){
					
					int temp=a[i];
					
					for (j = i-gap;  j>=0 && a[j] > temp; j-=gap) {
						a[j+gap]=a[j];
					}
					
					a[j+gap]=temp;
				}
			}
			
		}while(gap > 1);//直到增量为1结束
		
	}
	
	
		
	/**
	 * 堆排序
	 * 方法名:heapSort<BR>
	 * 时间复杂度: O(nlogn)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void heapSort(int[] a){  
		
		int n=a.length;
		
		for(int i=n/2-1;i >= 0;i--){//将数组a构建成大顶堆
			
			sift_down(a,i,n-1);
			
		}   
		
		for(int i=n-1 ;i > 0;i--){

			swap(a,0,i);//将堆顶数据与当前未排序子序列的最后一个数据交换
			sift_down(a,0,i-1);//将a[0..i-1]调整为大顶堆
		}
		
	}
	
	public static void sift_down(int a[],int x,int y){  
		
		int temp=a[x];
		
		for(int j=2*x+1;j<=y ;j=2*j+1){//从上向下,从左到右,将每个非叶结点及其子树调整为大顶堆
		
			if(j < y && a[j] < a[j+1])
				j++; 			//用j标记左右子树中的较大值
			if(temp >= a[j]) 	//若根节点大于左右子树,则跳出
				break;
			
			a[x]=a[j];		//若根节点小于左右子树,则跟较大值交换
			x=j;
		}
		
		a[x]=temp;	// 交换数据
		
	}
	
	
	
	
	/**
	 * 快速排序(优化枢轴值)
	 * 方法名:quickSort<BR>
	 * 时间复杂度: O(n^2)
	 * 创建人:潭州学院-liuchao <BR>
	 * 时间:2015年8月22日-下午10:03:19 <BR>
	 * @param a:待排序数组
	 * @return void<BR>
	 * @exception <BR>
	 * @since  1.0.0
	 */
	public static void quickSort(int[] a){
		
		quick_Sort(a,0,a.length-1);
	}
	
	public static void quick_Sort(int[] a, int low, int high){
		
		if(low < high){
			
			int point = partition(a,low,high);// 找到枢轴记录的下标
			quick_Sort(a,low,point-1);// 对低子表进行递归排序
			quick_Sort(a,point+1,high);// 对高子表进行递归排序
			
		}
	}
	
	public static int partition(int[] a,int low,int high){
		
		if (low < high){
	
			int mid = (low + high)/2;
			
			if(a[low] > a[high])	swap(a,low,high);//交换左端与右端的记录,保证左端较小
			if(a[mid] > a[high])	swap(a,mid,high);//交换中间与右端的记录,保证中间较小
			if(a[mid] > a[low])		swap(a,mid,low);//交换左端与中间的记录,保证左端较小 
		}
		
		int temp=a[low];// 将三取一后的中间值作为枢轴记录
		
		while(low < high){
			
			while(low<high && a[high]>=temp)	high--;
			
			swap(a,low,high);// 把比枢轴记录小的值交换到低端 
			
			while(low<high && a[low]<=temp)	low++;
			
			swap(a,low,high);// 把比枢轴记录大的值交换到高端 
			
		}
		return low;// 返回枢轴记录的下标
	}
	

	
	
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值