JAVA 排序方法整理

1.     冒泡排序

基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对

相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的

数比较后发现它们的排序与排序要求相反时,就将它们互换。

2.     选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。

 

 

3.     插入排序

所谓插入排序法,就是检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就可以停止了。插入排序法主要的回圈有两个变数:ij,每一次执行这个回圈,就会将第i个数字放到左边恰当的位置去。

 

4.     堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

 

 

5.     快速排序

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

 

 

 

 

6.     基数排序

基数排序(radix sort)属于“分配式排序”(distributionsort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。



java 代码实例:

package com.gnet.module.talk;



public class RainTest extends Thread {
	   
	static int[] num={9,10,4,5,2,1,6,3,7,8};
	static int MAX=num.length;
	
	
	 /*-------------------------插入排序法-------------------------------- 
    像是玩朴克一样,我们将牌分作两堆,每次从后面一堆的牌抽出最前端的牌,然后插入前面一堆牌的适当位置 
-----------------------------------------------------------------*/  
	 public   void insort(int number[]){  
	        int i, j, k, temp;  
	        long start,end;  
	        start=System.nanoTime();  
	        for(j = 1; j < MAX; j++) {  
	            temp = number[j];  
	            i = j - 1;  
	            while(temp < number[i]) {  
	                number[i+1] = number[i];  
	                i--;  
	                if(i == -1){  
	                    break;  
	                }  
	            }  
	        number[i+1] = temp;  
	        }  
	        end=System.nanoTime();  
	          
	        System.out.println("-----------------插入排序法------------------");  
	        System.out.print("排序后是:");  
	        for(i=0;i<MAX;i++){  
	            System.out.print(number[i]+" ");  
	        }  
	        System.out.println();  
	        System.out.println("排序使用时间:"+(end-start)+" ns");  
	   }  
	
	
	 /*----------------------------选择排序法------------------------------------------- 
     将要排序的对象分作两部份,一个是已排序的,一个是未排序的,从后端未排序部份选择一个最小值,并放入前端已排序部份的最后一个。 
-------------------------------------------------------------------------------*/  
	 public  void selsort(int number[]) {  
	        int i, j, k, m, temp;  
	        long start,end;  
	          
	        start=System.nanoTime();  
	        for(i = 0; i < num.length; i++) {  
	            m = i;  
	            for(j = i; j < num.length; j++){  
	                if(number[j] < number[m]){  
	                 m = j;  
	                }  
	            }  
	            if( i != m){  
	                temp=number[i];  
	                number[i]=number[m];  
	                number[m]=temp;  
	            }  
	        }  
	        end=System.nanoTime();  
	          
	        System.out.println("-----------------选择排序法------------------");  
	        System.out.print("排序后是:");  
	        for(i=0;i<num.length;i++){  
	            System.out.print(number[i]+" ");  
	        }  
	        System.out.println();  
	        System.out.println("排序使用时间:"+(end-start)+" ns");  
	    }  
	//-----------------冒泡排序法------------------
	public  void bubsort(int number[]){  
        int i, j, k, temp, flag = 1;  
        long start,end;  
        int MAX=num.length;
        start=System.nanoTime();  
        for(i = 0; i <MAX ; i++) {  
            for(j = i; j < MAX; j++) {  
                if(number[j] < number[i]) {  
                    temp=number[j];  
                    number[j]=number[i];  
                    number[i]=temp;  
                }  
            }  
        }  
        end=System.nanoTime();  //返回的是纳秒
          
        System.out.println("-----------------冒泡排序法------------------");  
        System.out.print("排序后是:");  
        for(i=0;i<num.length;i++){  
            System.out.print(number[i]+" ");  
        }  
        System.out.println();  
        System.out.println("排序使用时间:"+(end-start)+" ns");  
   }  
	  
	/*-----------------------heap排序(堆排序法--改进的选择排序)---------------------------- 
    利用堆积树的原理,先构造一个堆积树(看堆积树的定义,笔记本上有),然后将根节点与最后的叶子节点交换,并屏蔽掉最后一个叶子节点, 
    然后再将未被屏蔽的部分重新构造堆积树,然后再重复上面的步骤,直到所有的数被按顺序排好。 
	--------------------------------------------------------------------------------*/  
	public  void heapsort(int number[]) {  
		int i, m, p, s, temp;  
		long start,end;  
		  
		start=System.nanoTime();  
		int number_temp[]=new int[MAX+1];  
		for(int temp_i=1;temp_i<MAX+1;temp_i++){  
		    number_temp[temp_i]=number[temp_i-1];  
		}  
		createheap(number_temp);  
		m = MAX;  
		while(m > 1) {  
		    temp=number_temp[1];  
		    number_temp[1]=number_temp[m];  
		    number_temp[m]=temp;  
		    m--;  
		    p = 1;  
		    s = 2 * p;  
		    while(s <= m) {  
		        if(s < m && number_temp[s+1] > number_temp[s])  
		            s++;  
		        if(number_temp[p] >= number_temp[s])  
		            break;  
		        temp=number_temp[p];  
		        number_temp[p]=number_temp[s];  
		        number_temp[s]=temp;  
		        p = s;  
		        s = 2 * p;  
		    }  
		}  
		for(int temp_j=1;temp_j<MAX+1;temp_j++){  
		    number[temp_j-1]=number_temp[temp_j];  
		}  
		end=System.nanoTime();  
		  
		  
		 System.out.println("-----------------heap排序(堆排序法--改进的选择排序)------------------");  
		 System.out.print("排序后是:");  
		 for(i=0;i<=MAX-1;i++){  
		     System.out.print(number[i]+" ");  
		 }  
		 System.out.println();  
		 System.out.println("排序使用时间:"+(end-start)+" ns");  
	}  
	 //将原数组构造为从下标1开始的一个新数组,便于处理,同时将这个新数组构造为最初始的堆积树结构  
	   public  void createheap(int number[]) {  
	       int i, s, p, temp;  
	       int heap[] = new int[MAX+1];  
	       for(i = 1; i <= MAX; i++) {  
	           heap[i] = number[i];  
	           s = i;  
	           p = i / 2;  
	           while(s >= 2 && heap[p] < heap[s]) {  
	               temp=heap[p];  
	               heap[p]=heap[s];  
	               heap[s]=temp;  
	               s = p;  
	               p = s / 2;  
	           }  
	       }  
	       for(i = 1; i <= MAX; i++){  
	          number[i] = heap[i];   
	       }  
	   }  
	   
	   /*-----------------------快速排序法(一)--------------------------------------------- 
	    这边所介绍的快速演算如下:将最左边的数设定为轴,并记录其值为s 
	    廻圈处理: 
	    令索引i 从数列左方往右方找,直到找到大于s 的数 
	    令索引j 从数列左右方往左方找,直到找到小于s 的数 
	    如果i >= j,则离开回圈 
	    如果i < j,则交换索引i与j两处的值 
	    将左侧的轴与j 进行交换 
	    对轴左边进行递回 
	    对轴右边进行递回   
	    --------------------------------------------------------------------------------*/  
	   public void quicksort_one(int number[]){  
	       long start,end;  
	         
	       start=System.nanoTime();  
	       quicksort_1(number,0,MAX-1);  
	       end=System.nanoTime();  
	         
	        System.out.println("-----------------快速排序法( 一 )------------------");  
	        System.out.print("排序后是:");  
	        for(int i=0;i<=MAX-1;i++){  
	            System.out.print(number[i]+" ");  
	        }  
	        System.out.println();  
	        System.out.println("排序使用时间:"+(end-start)+" ns");  
	         
	         
	   } 
	   //数组,第一个索引,最后一个索引
	   public void quicksort_1(int number[],int left,int right) {  
	       int i, j, s, temp;  
	       if(left < right) {  
	           s = number[left];  
	           i = left;  
	           j = right + 1;  
	           while(true) {  
	               // 向右找  1<10&&num[1]<num[0]
	               while(i + 1 < number.length && number[++i] < s) ;  
	               // 向左找  9>-1&&num[9]>num[1]
	               while(j -1 > -1 && number[--j] > s) ;  
	               if(i >= j)  
	                   break;  
	               temp=number[i];  
	               number[i]=number[j];  
	               number[j]=temp;  
	           }  
	       number[left] = number[j];  
	       number[j] = s;  
	       quicksort_1(number, left, j-1); // 对左边进行递回  
	       quicksort_1(number, j+1, right); // 对右边进行递回  
	       }  
	   }  
	   
	   /*-----------------------快速排序法(二)--------------------------------------------- 
	    在这个例子中,取中间的元素s作比较,同样的先得右找比s大的索引i,然后找比s小的 
	    索引j,只要两边的索引还没有交会,就交换i 与j 的元素值,这次不用再进行轴的交换了, 
	    因为在寻找交换的过程中,轴位置的元素也会参与交换的动作,例如: 
	    41 24 76 11 45 64 21 69 19 36 
	    首先left为0,right为9,(left+right)/2 = 4(取整数的商),所以轴为索引4的位置,比较的元素是 
	    45,您往右找比45大的,往左找比45小的进行交换: 
	    41 24 76* 11 [45] 64 21 69 19 *36 
	    41 24 36 11 45* 64 21 69 19* 76 
	    41 24 36 11 19 64* 21* 69 45 76 
	   [41 24 36 11 19 21] [64 69 45 76] 
	    完成以上之后,再初别对左边括号与右边括号的部份进行递回,如此就可以完成排序的目的。 
	   --------------------------------------------------------------------------------*/  
	   public void quicksort_two(int number[]){  
	       long start,end;  
	         
	       start=System.nanoTime();  
	       quicksort_2(number,0,MAX-1);  
	       end=System.nanoTime();  
	         
	        System.out.println("-----------------快速排序法( 二 )------------------");  
	        System.out.print("排序后是:");  
	        for(int i=0;i<=MAX-1;i++){  
	            System.out.print(number[i]+" ");  
	        }  
	        System.out.println();  
	        System.out.println("排序使用时间:"+(end-start)+" ns");  
	   }  
	     
	     
	   public void quicksort_2(int number[], int left, int right) {  
	       int i, j, s, temp;  
	       if(left < right) {  
	           s = number[(left+right)/2];  
	           i = left - 1;  
	           j = right + 1;  
	           while(true) {  
	               while(number[++i] < s) ; // 向右找  
	               while(number[--j] > s) ; // 向左找  
	               if(i >= j)  
	                   break;  
	               temp=number[i];  
	               number[i]=number[j];  
	               number[j]=temp;  
	           }  
	       quicksort_2(number, left, i-1); // 对左边进行递回  
	       quicksort_2(number, j+1, right); // 对右边进行递回  
	       }  
	   }  
	     
	     
	     
	     
	   /*-----------------------快速排序法(三)--------------------------------------------- 
	            先说明这个快速排序法的概念,它以最右边的值s作比较的标准,将整个数列分为三个部份, 
	    一个是小于s的部份,一个是大于s的部份,一个是未处理的部份,如下所示: 
	            i           j 
	    --------|-----------|----------|s 
	        小于s     大于s         未处理 
	    在排序的过程中,i 与j 都会不断的往右进行比较与交换,最后数列会变为以下的状态: 
	    -------------|-----------------|s 
	        小于s             大于s 
	    然后将s的值置于中间,接下来就以相同的步骤会左右两边的数列进行排序的动作,如下所示: 
	    -------------|s|--------------- 
	        小于s             大于s 
	    然后采用递归的方法重复上面的步骤,就可以实现排序了。 
	   --------------------------------------------------------------------------------*/  
	   public void quicksort_three(int number[]){  
	       long start,end;  
	         
	       start=System.nanoTime();  
	       quicksort_3(number,0,MAX-1);  
	       end=System.nanoTime();  
	         
	        System.out.println("-----------------快速排序法( 三 )------------------");  
	        System.out.print("排序后是:");  
	        for(int i=0;i<=MAX-1;i++){  
	            System.out.print(number[i]+" ");  
	        }  
	        System.out.println();  
	        System.out.println("排序使用时间:"+(end-start)+" ns");  
	         
	   }  
	     
	     
	   public int partition(int number[], int left, int right) {  
	       int i, j, s, temp;  
	       s = number[right];  
	       i = left - 1;  
	       for(j = left; j < right; j++) {  
	           if(number[j] <= s) {  
	               i++;  
	               temp=number[i];  
	               number[i]=number[j];  
	               number[j]=temp;  
	           }  
	       }  
	       temp=number[i+1];  
	       number[i+1]=number[right];  
	       number[right]=temp;  
	       return i+1;  
	   }  
	     
	   public void quicksort_3(int number[], int left, int right) {  
	       int q;  
	       if(left < right) {  
	           q = partition(number, left, right);  
	           quicksort_3(number, left, q-1);  
	           quicksort_3(number, q+1, right);  
	       }  
	   }
	   
	   //基数
	   /*-----------------------基数排序法--------------------------------------------- 
       基数排序的方式可以采用LSD(Least sgnificant digital)或MSD(Most sgnificant digital), 
LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。 
以LSD为例,假设原来有一串数值如下所示: 
73, 22, 93, 43, 55, 14, 28, 65, 39, 81 
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中: 
0   1   2   3   4   5   6   7   8   9 
   81              65              39 
           43  14  55          28 
           93 
       22  73 
接下来将这些桶子中的数值重新串接起来,成为以下的数列: 
81, 22, 73, 93, 43, 14, 55, 65, 28, 39 
接着再进行一次分配,这次是根据十位数来分配: 
接下来将这些桶子中的数值重新串接起来,成为以下的数列: 
0   1   2   3   4   5   6   7   8   9 
       28  39 
   14  22      43  55  65  73  81  93 
14, 22, 28, 39, 43, 55, 65, 73, 81, 93 
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最 
高位数为止。 
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好,MSD的方 
式恰与LSD相反,是由高位数为基底开始进行分配,其他的演算方式则都相同。       
--------------------------------------------------------------------------------*/  
	public void basesort(int number[]){  
	  int temp[][] = new int[MAX][MAX];  
	  int order[] = new int[MAX];  
	  int i, j, k, n, lsd;  
	  long start,end;  
	  k = 0;  
	  n = 1;  
	  start=System.nanoTime();  
	  while(n <= 10) {  
	      for(i = 0; i < MAX; i++) {  
	          lsd = ((number[i] / n) % 10);  
	          temp[lsd][order[lsd]] = number[i];  
	          order[lsd]++;  
	      }  
	      //重新排列  
	      for(i = 0; i < MAX; i++) {  
	          if(order[i] != 0)  
	              for(j = 0; j < order[i]; j++) {  
	                  number[k] = temp[i][j];  
	                  k++;  
	              }  
	          order[i] = 0;  
	      }  
	      n *= 10;  
	      k = 0;  
	   }  
	  end=System.nanoTime();  
	  System.out.println("-----------------基数排序法------------------");  
	  System.out.print("排序后是:");  
	  for(int ii=0;ii<=MAX-1;ii++){  
	       System.out.print(number[ii]+" ");  
	  }  
	  System.out.println();  
	  System.out.println("排序使用时间:"+(end-start)+" ns");  
	}  
	
	   
	public static void main(String[] args) throws Exception {
		  RainTest t=new RainTest();
		  t.bubsort(num);
		  t.selsort(num);
		  t.insort(num);
		  t.heapsort(num);
		  t.quicksort_one(num);
		  t.quicksort_two(num);
		  t.quicksort_three(num);
		  t.basesort(num);
    }
}





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值