java实现常用的八种内排序方法

虽然以前写过两篇关于内排序的博客,但时间一长这算法也就容易忘记了,所以最近又整理了一次,将八种排序方法一一实现下,它们分别是:

直接插入排序希尔排序
冒泡排序快速排序
直接选择排序堆排序
归并排序最低位优先的基数排序

      前面七种排序我用的数据结构是hashMap,其储存方式为<key,value>的键值对形式,我选的则是<Integer,Integer>(读者也可以使用数组类型保存数据,正如我前两篇博客那样),值得一提的是哈希表中的0号位全是来用作交换数据的中间值(即hashMap.put(0, null);//第一位置空),如对HashMap不熟悉的读者可以参考相关API,程序中会使用到的方法也只有hashPut.put(key, value)、hashMap.get(key)和hashMap.clear()而已。算法的思想我在这里就不一一详细介绍了,原因是下面的代码中有更为详尽的解释,我就不多此一举了。

——————————————————直接插入排序——————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4. /** 
  5.  * 直接插入排序 
  6.  * @author HHF 
  7.  * 2014年3月19日 
  8.  */  
  9. public class InsertSort {  
  10.   
  11.     private static int contrastCount = 0;//对比次数  
  12.     private static int swapCount = 0;//交换次数  
  13.   
  14.     public static void main(String[] args) {  
  15.         System.out.println("直接插入排序:\n  假设前面的序列都已经排序好了,把后面未排序的数往已排好序的序列内插入,时间复杂度O(n^2),空间复杂度O(1),稳定排序");  
  16.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();  
  17.         init(hashMap);//初始化       
  18.         System.out.println("初始序列为:");  
  19.         print(hashMap, 0);//打印    
  20.         insert(hashMap);//排序  
  21.     }  
  22.     /** 
  23.      * 初始化函数 
  24.      * @param hashMap 
  25.      */  
  26.     private static void init(HashMap<Integer, Integer> hashMap) {  
  27.         hashMap.put(0null);//第一位置空  
  28.         hashMap.put(10);  
  29.         hashMap.put(25);  
  30.         hashMap.put(311);  
  31.         hashMap.put(412);  
  32.         hashMap.put(513);  
  33.         hashMap.put(64);  
  34.         hashMap.put(71);  
  35.         hashMap.put(85);  
  36.         hashMap.put(98);  
  37.         hashMap.put(106);  
  38.         hashMap.put(114);  
  39.         hashMap.put(128);       
  40.     }  
  41.     /** 
  42.      * 进行插入排序 
  43.      * @param hashMap 待排序的表 
  44.      */  
  45.     private static void insert(HashMap<Integer, Integer> hashMap){  
  46.         System.out.println("开始插入排序:");  
  47.         int i,j;  
  48.         //排序开始时间  
  49.         long start = System.currentTimeMillis();      
  50.         for(i=2; i<hashMap.size(); i++){//从第二个开始排序,知道最后一个结束  
  51.             hashMap.put(0, hashMap.get(i));//储存待排序的数,以便前面的书好向后交换位置  
  52.             swapCount++;//发生一次交换  
  53.             j = i-1;//指向有序列  
  54.             while(hashMap.get(0) < hashMap.get(j)){//当发现有比待排序书大的时候 该数后移一位  
  55.                 hashMap.put(j+1, hashMap.get(j));  
  56.                 j--;//继续向前寻找合适的位置  
  57.                 swapCount++;//发生一次交换  
  58.                 contrastCount++;//发生一次对比  
  59.             }  
  60.             contrastCount++;//跳出while循环还有一次对比  
  61.             hashMap.put(j+1, hashMap.get(0));//放入合适的位置  
  62.             swapCount++;//发生一次交换  
  63.             /*比如说  我发现从第5号元素开始前面的数都比待排序值小 
  64.                 则j=5,且第6号元素位为合适的位置且为空 
  65.                 所以有j++ 
  66.             */  
  67.             print(hashMap, i-1);//输出每趟的序列  
  68.         }  
  69.         //排序结束时间  
  70.         long end = System.currentTimeMillis();  
  71.         System.out.println("结果为:");  
  72.         print(hashMap, 0);//输出排序结束的序列  
  73.         hashMap.clear();//清空  
  74.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  75.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  76.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  77.     }  
  78.     /** 
  79.      * 打印已排序好的元素 
  80.      * @param hashMap 已排序的表 
  81.      * @param j 第j趟排序 
  82.      */  
  83.     private static void print(HashMap<Integer, Integer> hashMap, int j){  
  84.         if(j != 0)  
  85.             System.out.print("第 "+j+" 趟:\t");  
  86.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  87.             System.out.print(hashMap.get(i)+"\t");  
  88.         }  
  89.         System.out.println();  
  90.     }  
  91. }  

 

 

——————————————————希尔排序————————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4. /** 
  5.  * 希尔排序 
  6.  * @author HHF 
  7.  * 2014年3月19日 
  8.  */  
  9. public class HillSort {  
  10.   
  11.     private static int contrastCount = 0;//对比次数  
  12.     private static int swapCount = 0;//交换次数  
  13.   
  14.     public static void main(String[] args) {  
  15.         System.out.println("希尔排序:\n  分间隔的直接插入排序,假定一个增量d,把全部n个记录分成d组,各组内直接插入排序;再取d1<d,重复分组排序,直到d=1,时间复杂度O(n^1.3),空间复杂度O(1),不稳定排序");         
  16.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();  
  17.         init(hashMap);//初始化       
  18.         System.out.println("初始序列为:");  
  19.         print(hashMap, 00);//打印  
  20.         hill(hashMap);//排序  
  21.     }  
  22.     /** 
  23.      * 初始化函数 
  24.      * @param hashMap 
  25.      */  
  26.     private static void init(HashMap<Integer, Integer> hashMap) {  
  27.         hashMap.put(0null);//第一位置空  
  28.         hashMap.put(110);  
  29.         hashMap.put(25);  
  30.         hashMap.put(311);  
  31.         hashMap.put(412);  
  32.         hashMap.put(513);  
  33.         hashMap.put(64);  
  34.         hashMap.put(71);  
  35.         hashMap.put(85);  
  36.         hashMap.put(98);  
  37.         hashMap.put(106);  
  38.         hashMap.put(114);  
  39.         hashMap.put(128);       
  40.     }  
  41.     /** 
  42.      * 进行希尔排序 
  43.      * @param hashMap 待排序的表 
  44.      */  
  45.     private static void hill(HashMap<Integer, Integer> hashMap){  
  46.         System.out.println("开始希尔排序:");  
  47.           
  48.         //排序开始时间  
  49.         long start = System.currentTimeMillis();  
  50.           
  51.         int d = hashMap.size()-1;//初始化增量d  
  52.         int count = 1;//只为统计执行次数  
  53.         while(true){  
  54.             d = d / 2;//增量每次对半减  
  55.             for(int x=1;x<=d;x++){//一共有d组 x表示每一组的一个数的下表  
  56.                 for(int i=x+d; i<hashMap.size(); i=i+d){//开始直接插入排序 每组内的数下标间隔d i表示这一组数的下标  
  57.                     hashMap.put(0, hashMap.get(i));//当前被待排序的书  
  58.                     swapCount++;//发生一次交换  
  59.                     int j = 0;//i之前的同一组数的下标  
  60.                     for(j=i-d; j>=0&&(hashMap.get(j)>hashMap.get(0)); j=j-d){//寻找i的当前合适位置 从i-d开始往前找  
  61.                         //只有当被查下标有效 且 被查值比待排序值大时才应该发生交换  
  62.                         hashMap.put(j+d, hashMap.get(j));  
  63.                         contrastCount++;//发生一次对比  
  64.                         swapCount++;//发生一次交换  
  65.                     }  
  66.                     contrastCount++;//跳出for循环还有一次对比  
  67.                     hashMap.put(j+d, hashMap.get(0));//放入合适的位置  
  68.                     swapCount++;//发生一次交换  
  69.                     //一趟直接插入排序结束  
  70.                 }  
  71.             }  
  72.             print(hashMap, count++, d);  
  73.             if(d == 1){  
  74.                 break;  
  75.             }  
  76.         }  
  77.           
  78.         //排序结束时间  
  79.         long end = System.currentTimeMillis();  
  80.         System.out.println("结果为:");  
  81.         print(hashMap, 00);//输出排序结束的序列  
  82.         hashMap.clear();//清空  
  83.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  84.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  85.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  86.     }  
  87.     /** 
  88.      * 打印已排序好的元素 
  89.      * @param hashMap 已排序的表 
  90.      * @param j 第j趟排序 
  91.      * @param d 当前的增量 
  92.      */  
  93.     private static void print(HashMap<Integer, Integer> hashMap, int j, int d){  
  94.         if(j != 0)  
  95.             System.out.print("第 "+j+" 趟:(d="+d+")\t");  
  96.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  97.             System.out.print(hashMap.get(i)+"\t");  
  98.         }  
  99.         System.out.println();  
  100.     }  
  101. }  

 

 

——————————————————冒泡排序————————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. /** 
  6.  * 冒泡排序 
  7.  * @author HHF 
  8.  * 2014年3月19日 
  9.  */  
  10. public class BubbleSort {  
  11.   
  12.     private static int contrastCount = 0;//对比次数  
  13.     private static int swapCount = 0;//交换次数  
  14.   
  15.     public static void main(String[] args) {  
  16.         System.out.println("冒泡排序:\n  第一轮使最大值沉淀到最底下,采用从头开始的两两比较的办法,如果i大于i++则交换,下一次有从第一个开始循环,比较次数减一,然后依次重复即可,"  
  17.                 + "\n 如果一次比较为发生任何交换,则可提前终止,时间复杂度O(n^2),空间复杂度O(1),稳定排序");          
  18.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();  
  19.         init(hashMap);//初始化       
  20.         System.out.println("初始序列为:");  
  21.         print(hashMap, 0);//打印  
  22.         bubble(hashMap);//排序  
  23.     }  
  24.     /** 
  25.      * 初始化函数 
  26.      * @param hashMap 
  27.      */  
  28.     private static void init(HashMap<Integer, Integer> hashMap) {  
  29.         hashMap.put(0null);//第一位置空  
  30.         hashMap.put(110);  
  31.         hashMap.put(25);  
  32.         hashMap.put(311);  
  33.         hashMap.put(412);  
  34.         hashMap.put(513);  
  35.         hashMap.put(64);  
  36.         hashMap.put(71);  
  37.         hashMap.put(85);  
  38.         hashMap.put(98);  
  39.         hashMap.put(106);  
  40.         hashMap.put(114);  
  41.         hashMap.put(128);       
  42.     }  
  43.     /** 
  44.      * 进行冒泡排序 
  45.      * @param hashMap 待排序的表 
  46.      */  
  47.     private static void bubble(HashMap<Integer, Integer> hashMap){  
  48.         System.out.println("开始冒泡排序:");  
  49.           
  50.         //排序开始时间  
  51.         long start = System.currentTimeMillis();  
  52.         boolean swap = false;//是否发生交换  
  53.         int count = 1;//只为了计数  
  54.         for(int i=1; i<hashMap.size(); i++){  
  55.             swap = false;  
  56.             for(int j=1; j<hashMap.size()-i; j++){  
  57.                 if(hashMap.get(j)>hashMap.get(j+1)){//需要发生交换j 和 j+1  
  58.                     hashMap.put(0, hashMap.get(j));  
  59.                     hashMap.put(j, hashMap.get(j+1));  
  60.                     hashMap.put(j+1, hashMap.get(0));  
  61.                     swap = true;  
  62.                     contrastCount++;//发生一次对比  
  63.                     swapCount++;//发生一次交换  
  64.                     swapCount++;//发生一次交换  
  65.                     swapCount++;//发生一次交换  
  66.                 }  
  67.                 contrastCount++;//跳出if还有一次对比  
  68.             }  
  69.             print(hashMap, count++);  
  70.             if(!swap)  
  71.                 break;  
  72.         }     
  73.         //排序结束时间  
  74.         long end = System.currentTimeMillis();  
  75.         System.out.println("结果为:");  
  76.         print(hashMap, 0);//输出排序结束的序列  
  77.         hashMap.clear();//清空  
  78.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  79.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  80.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  81.     }  
  82.     /** 
  83.      * 打印已排序好的元素 
  84.      * @param hashMap 已排序的表 
  85.      * @param j 第j趟排序 
  86.      */  
  87.     private static void print(HashMap<Integer, Integer> hashMap, int j){  
  88.         if(j != 0)  
  89.             System.out.print("第 "+j+" 趟:\t");  
  90.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  91.             System.out.print(hashMap.get(i)+"\t");  
  92.         }  
  93.         System.out.println();  
  94.     }  
  95. }  

 

 

——————————————————快速排序————————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. /** 
  6.  * 快速排序 
  7.  * @author HHF 
  8.  * 2014年3月19日 
  9.  */  
  10. public class QuickSort {  
  11.   
  12.     private static int contrastCount = 0;//对比次数  
  13.     private static int swapCount = 0;//交换次数  
  14.   
  15.     public static void main(String[] args) {  
  16.         System.out.println("快速排序:\n  任取一个数作为分界线,比它小的放到左边,比它大的放在其右边,然后分别对左右进行递归,时间复杂度O(nLgn),空间复杂度O(n),不稳定排序");        
  17.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();  
  18.         init(hashMap);//初始化       
  19.         System.out.println("初始序列为:");  
  20.         print(hashMap, 00);//打印  
  21.         System.out.println("开始快速排序:");        
  22.         //排序开始时间  
  23.         long start = System.currentTimeMillis();  
  24.           
  25.         quick(hashMap, 1, hashMap.size()-1);//排序  
  26.           
  27.         //排序结束时间  
  28.         long end = System.currentTimeMillis();  
  29.         System.out.println("结果为:");  
  30.         print(hashMap, 00);//输出排序结束的序列  
  31.         hashMap.clear();//清空  
  32.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  33.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  34.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  35.         System.out.println("(注:此输出序列为代码执行过程的序列, 即先左边递归 再 右边递归, 而教科书上的递归序列往往是左右同时进行的结果,特此说明)");  
  36.     }  
  37.     /** 
  38.      * 初始化函数 
  39.      * @param hashMap 
  40.      */  
  41.     private static void init(HashMap<Integer, Integer> hashMap) {  
  42.         hashMap.put(0null);//第一位置空  
  43.         hashMap.put(110);  
  44.         hashMap.put(25);  
  45.         hashMap.put(311);  
  46.         hashMap.put(412);  
  47.         hashMap.put(513);  
  48.         hashMap.put(64);  
  49.         hashMap.put(71);  
  50.         hashMap.put(85);  
  51.         hashMap.put(98);  
  52.         hashMap.put(106);  
  53.         hashMap.put(114);  
  54.         hashMap.put(128);       
  55.     }  
  56.     /** 
  57.      * 进行快速排序 
  58.      * @param hashMap 待排序的表 
  59.      * @param low 
  60.      * @param high 
  61.      */  
  62.     static int count = 1;  
  63.     private static void quick(HashMap<Integer, Integer> hashMap, int low, int high){  
  64.         if(low<high){//跳出递归的条件  
  65.             int k = quickOnePass(hashMap, low, high);//开始一趟排序  
  66.             print(hashMap, count++, hashMap.get(k));  
  67.             quick(hashMap, low, k-1);//对左边的序列递归排序  
  68.             quick(hashMap, k+1, high);//对右边的序列递归排序  
  69.         }  
  70.     }  
  71.     /** 
  72.      * 进行快速排序 
  73.      * @param hashMap 待排序的表 
  74.      * @param low  
  75.      * @param high 
  76.      */  
  77.     private static int quickOnePass(HashMap<Integer, Integer> hashMap, int low, int high){      
  78.         hashMap.put(0, hashMap.get(low));//选择一个分界值 此时第low位元素内的值已经无所谓被覆盖了  
  79.         swapCount++;//发生一次交换  
  80.         while(low<high){//左右两边还有数据为检查时  
  81.             while(low<high && hashMap.get(0)<hashMap.get(high)){//先开始从右往左走 直到有不对的数据 或者 到头了  
  82.                 high--;  
  83.                 contrastCount++;//发生一次对比  
  84.             }  
  85.             if(low<high){//如果停下来是因为不对的数据 而不是 到头了  
  86.                 hashMap.put(low++, hashMap.get(high));  
  87.                 swapCount++;//发生一次交换  
  88.             }  
  89.             while(low<high && hashMap.get(0)>hashMap.get(low)){//开始从左往右走 直到有不对的数据 或者 到头了            
  90.                 low++;  
  91.                 contrastCount++;//发生一次对比  
  92.             }  
  93.             if(low<high){//如果停下来是因为不对的数据 而不是 到头了  
  94.                 hashMap.put(high--, hashMap.get(low));  
  95.                 swapCount++;//发生一次交换  
  96.             }  
  97.         }  
  98.         hashMap.put(low, hashMap.get(0));  
  99.         swapCount++;//发生一次交换  
  100.         return low;  
  101.     }  
  102.     /** 
  103.      * 打印已排序好的元素 
  104.      * @param hashMap 已排序的表 
  105.      * @param j 第j趟排序 
  106.      * @param k 第k个元素被选中为分界线 
  107.      */  
  108.     private static void print(HashMap<Integer, Integer> hashMap, int j, int k){  
  109.         if(j != 0)  
  110.             System.out.print("第 "+j+" 趟:(分界线为"+k+")\t");  
  111.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  112.             System.out.print(hashMap.get(i)+"\t");  
  113.         }  
  114.         System.out.println();  
  115.     }  
  116. }  

 

 

——————————————————直接选择排序——————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. /** 
  6.  * 选择排序 
  7.  * @author HHF 
  8.  * 2014年3月19日 
  9.  */  
  10. public class SelectionSort {  
  11.   
  12.     private static int contrastCount = 0;//对比次数  
  13.     private static int swapCount = 0;//交换次数  
  14.   
  15.     public static void main(String[] args) {  
  16.         System.out.println("选择排序:\n  每次选择最小的,然后与对应的位置处元素交换,时间复杂度O(n^2),空间复杂度O(1),不稳定排序");         
  17.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();  
  18.         init(hashMap);//初始化       
  19.         System.out.println("初始序列为:");  
  20.         print(hashMap, 00);//打印  
  21.         select(hashMap);//排序  
  22.     }  
  23.     /** 
  24.      * 初始化函数 
  25.      * @param hashMap 
  26.      */  
  27.     private static void init(HashMap<Integer, Integer> hashMap) {  
  28.         hashMap.put(0null);//第一位置空  
  29.         hashMap.put(110);  
  30.         hashMap.put(25);  
  31.         hashMap.put(311);  
  32.         hashMap.put(412);  
  33.         hashMap.put(513);  
  34.         hashMap.put(64);  
  35.         hashMap.put(71);  
  36.         hashMap.put(85);  
  37.         hashMap.put(98);  
  38.         hashMap.put(106);  
  39.         hashMap.put(114);  
  40.         hashMap.put(128);       
  41.     }  
  42.     /** 
  43.      * 进行选择排序 
  44.      * @param hashMap 待排序的表 
  45.      */  
  46.     private static void select(HashMap<Integer, Integer> hashMap){  
  47.         System.out.println("开始选择排序:");        
  48.         //排序开始时间  
  49.         long start = System.currentTimeMillis();  
  50.         int count = 1;//只为统计执行次数  
  51.         for(int i=hashMap.size()-1; i>1; i--){//需要循环查询的次数 最后一个元素不用考虑  
  52.             int k = i;//记录本次查找序列最大值的下标 初始为该数应该要放的位置  
  53.             for(int j=1; j<i; j++){//  
  54.                 if(hashMap.get(k)<hashMap.get(j)){  
  55.                     k=j;//记录当前最大的数的下标  
  56.                     contrastCount++;//发生一次对比  
  57.                 }  
  58.             }  
  59.             //此时k中保存了i位置应该放的数的下标 于是发生交换  
  60.             if(i != k ){  
  61.                 hashMap.put(0, hashMap.get(k));  
  62.                 hashMap.put(k, hashMap.get(i));  
  63.                 hashMap.put(i, hashMap.get(0));  
  64.                 swapCount++;//发生一次交换  
  65.                 swapCount++;//发生一次交换  
  66.                 swapCount++;//发生一次交换  
  67.             }  
  68.             print(hashMap, count++, i);//输出排序结束的序列  
  69.         }          
  70.         //排序结束时间  
  71.         long end = System.currentTimeMillis();  
  72.         System.out.println("结果为:");  
  73.         print(hashMap, 00);//输出排序结束的序列  
  74.         hashMap.clear();//清空  
  75.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  76.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  77.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  78.     }  
  79.     /** 
  80.      * 打印已排序好的元素 
  81.      * @param hashMap 已排序的表 
  82.      * @param j 第j趟排序 
  83.      * @param d 被选到的数 
  84.      */  
  85.     private static void print(HashMap<Integer, Integer> hashMap, int j, int d){  
  86.         if(j != 0)  
  87.             System.out.print("第 "+j+" 趟:\t");  
  88.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  89.             System.out.print(hashMap.get(i)+"\t");  
  90.         }  
  91.         System.out.println();  
  92.     }  
  93. }  

 

 

——————————————————堆排序—————————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. /** 
  6.  * 堆排序——极大堆 
  7.  * @author HHF 
  8.  * 2014年3月19日 
  9.  */  
  10. public class HeapSort {  
  11.   
  12.     private static int contrastCount = 0;//对比次数  
  13.     private static int swapCount = 0;//交换次数  
  14.     private static int printCount = 1;//执行打印次数  
  15.     public static void main(String[] args) {  
  16.         System.out.println("堆排序:\n  首先建立一个堆(方法是首先把序列排成二叉树,然后从下往上,从右往左使得每一个小子树中的父节点大于子节点,然后从上往下,从左往右记录堆入序列),"  
  17.                 + "\n  然后把堆的根节点和最底下 的孩子节点交换,整理堆,再重复交换,整理,时间复杂度O(nlgn),空间复杂度O(1),不稳定排序");          
  18.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();  
  19.         init(hashMap);//初始化       
  20.         System.out.println("初始序列为:");  
  21.         print(hashMap, 0);//打印  
  22.         heap(hashMap);//排序  
  23.     }  
  24.     /** 
  25.      * 初始化函数 
  26.      * @param hashMap 
  27.      */  
  28.     private static void init(HashMap<Integer, Integer> hashMap) {  
  29.         hashMap.put(0null);//第一位置空  
  30.         hashMap.put(110);  
  31.         hashMap.put(25);  
  32.         hashMap.put(311);  
  33.         hashMap.put(412);  
  34.         hashMap.put(513);  
  35.         hashMap.put(64);  
  36.         hashMap.put(71);  
  37.         hashMap.put(85);  
  38.         hashMap.put(98);  
  39.         hashMap.put(106);  
  40.         hashMap.put(114);  
  41.         hashMap.put(128);       
  42.     }  
  43.     /** 
  44.      * 进行堆排序 
  45.      * @param hashMap 待排序的表 
  46.      */  
  47.     private static void heap(HashMap<Integer, Integer> hashMap){  
  48.         System.out.println("开始建堆:");          
  49.         //排序开始时间87    
  50.         long start = System.currentTimeMillis();  
  51.         for(int i=(hashMap.size()-1)/2; i>=1; i--){//开始建堆  
  52.             sift(hashMap, i, hashMap.size()-1);//把所有的节点调好位置即可以  
  53.         }         
  54.         System.out.println("建堆成功");  
  55.         for(int j=hashMap.size()-1; j>=1; j--){//每次都把第一个元素与最后一个未排序的交换 然后再调整第一个节点即可  
  56.             hashMap.put(0, hashMap.get(1));  
  57.             hashMap.put(1, hashMap.get(j));  
  58.             hashMap.put(j, hashMap.get(0));  
  59.             sift(hashMap, 1, j-1);//剩下要排序的数位为j-1  
  60.             swapCount++;//发生一次交换  
  61.             swapCount++;//发生一次交换  
  62.             swapCount++;//发生一次交换  
  63.         }  
  64.         //排序结束时间  
  65.         long end = System.currentTimeMillis();  
  66.         System.out.println("结果为:");  
  67.         print(hashMap, 0);//输出排序结束的序列  
  68.         hashMap.clear();//清空  
  69.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  70.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  71.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  72.     }  
  73.     /** 
  74.      * 把第i位的元素移动到合适位置 与其子孩子的最大值比较 如果有发生交换 则继续往下比较 
  75.      * @param hashMap 
  76.      * @param i 待移动的数下标 
  77.      * @param n 表示要查找的范围 从1到n个 
  78.      */  
  79.     private static void sift(HashMap<Integer, Integer> hashMap, int i, int n){  
  80.         int j = 2*i;//j为i的左孩子  
  81.         hashMap.put(0, hashMap.get(i));//当前被待排序的数  
  82.         while(j<=n){//如果有左孩子的  
  83.             if(hashMap.containsKey(j+1) && hashMap.get(j)<hashMap.get(j+1)){//保证j为最大的孩子  
  84.                 j++;  
  85.             }  
  86.             contrastCount++;//发生一次对比  
  87.             if(hashMap.get(0)<hashMap.get(j)){//如果是孩子比较大  
  88.                 hashMap.put(i, hashMap.get(j));//交换  
  89.                 i=j;//转移根节点下标  
  90.                 j*=2;//转移孩子节点下标  
  91.                 swapCount++;//发生一次交换  
  92.             }else//如果是根比较大  
  93.                 break;  
  94.             contrastCount++;//发生一次对比  
  95.         }  
  96.         hashMap.put(i, hashMap.get(0));//i为当前的合适位置  
  97.         swapCount++;//发生一次交换  
  98.         print(hashMap, printCount++);//输出排序结束的序列  
  99.                   
  100.     }  
  101.   
  102.     /** 
  103.      * 打印已排序好的元素 
  104.      * @param hashMap 已排序的表 
  105.      * @param j 第j趟排序 
  106.      */  
  107.     private static void print(HashMap<Integer, Integer> hashMap, int j){  
  108.         if(j != 0)  
  109.             System.out.print("第 "+j+" 趟:\t");  
  110.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  111.             System.out.print(hashMap.get(i)+"\t");  
  112.         }  
  113.         System.out.println();  
  114.     }  
  115. }  

 

 

——————————————————归并排序————————————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. /** 
  6.  * 归并排序 
  7.  * @author HHF 
  8.  * 2014年3月19日 
  9.  */  
  10. public class MergeSort {  
  11.   
  12.     private static int contrastCount = 0;//对比次数  
  13.     private static int swapCount = 0;//交换次数  
  14.     private static int printCount = 1;//只为统计执行次数  
  15.   
  16.     public static void main(String[] args) {  
  17.         System.out.println("归并尔排序:\n  先将数据分为n组,然后没两组开始合并,相邻两个合并为一个新的有序队列,重复合并直到整个队列有序,时间复杂度O(nlgn),空间复杂度O(n),稳定排序");          
  18.         HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();//未排序  
  19.         HashMap<Integer,Integer> hashMapNew = new HashMap<Integer,Integer>();//已排序  
  20.         hashMapNew.put(0null);//第一位置空  
  21.         init(hashMap);//初始化       
  22.         System.out.println("初始序列为:");  
  23.         print(hashMap, 0);//打印  
  24.         System.out.println("开始归并尔排序:");  
  25.         //排序开始时间  
  26.         long start = System.currentTimeMillis();          
  27.         merge(hashMap, hashMapNew, 1, hashMap.size()-1);//排序  
  28.         //排序结束时间  
  29.         long end = System.currentTimeMillis();  
  30.         System.out.println("结果为:");  
  31.         print(hashMapNew, 0);//输出排序结束的序列  
  32.         hashMap.clear();//清空  
  33.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  34.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  35.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  36.         System.out.println("(注:此输出序列为代码执行过程的序列, 即先左边递归 再 右边递归, 而教科书上的递归序列往往是左右同时进行的结果,特此说明)");  
  37.     }  
  38.     /** 
  39.      * 初始化函数 
  40.      * @param hashMap 
  41.      */  
  42.     private static void init(HashMap<Integer, Integer> hashMap) {  
  43.         hashMap.put(0null);//第一位置空  
  44.         hashMap.put(110);  
  45.         hashMap.put(25);  
  46.         hashMap.put(311);  
  47.         hashMap.put(412);  
  48.         hashMap.put(513);  
  49.         hashMap.put(64);  
  50.         hashMap.put(71);  
  51.         hashMap.put(85);  
  52.         hashMap.put(98);  
  53.         hashMap.put(106);  
  54.         hashMap.put(114);  
  55.         hashMap.put(128);       
  56.     }  
  57.     /** 
  58.      * 进行归并尔排序 
  59.      * @param hashMap 待排序的表 
  60.      * @param hashMapNew 已排序的表 
  61.      */  
  62.     private static void merge(HashMap<Integer, Integer> hashMap, HashMap<Integer, Integer> hashMapNew, int low, int high){  
  63.         if(low == high){  
  64.             hashMapNew.put(low, hashMap.get(low));  
  65.             swapCount++;//发生一次交换  
  66.         }else{  
  67.             int meddle = (int)((low+high)/2);//将这一序列数均分的中间值  
  68.             merge(hashMap, hashMapNew, low, meddle);//继续对左边的序列递归  
  69.             merge(hashMap, hashMapNew, meddle+1, high);//对右边的序列递归  
  70.             mergeSort(hashMap, hashMapNew, low, meddle, high);//把相邻的序列组合起来  
  71.             for(int i=low; i<=high; i++){//将已经排好序的hashMapNew【low,high】覆盖hashMap【low,high】以便进入下一次的递归归并  
  72.                 hashMap.put(i, hashMapNew.get(i));  
  73.                 swapCount++;//发生一次交换  
  74.             }  
  75.         }   
  76.     }  
  77.     /** 
  78.      * 进行归并尔排序 把【low,meddle】和【meddle+1,high】和并为一个有序的hashMapNew【low,high】 
  79.      * @param hashMap 待排序的表       
  80.      * @param hashMapNew 已排序的表  
  81.      * @param low 低位 
  82.      * @param meddle 中位  
  83.      * @param high 高位 
  84.      */  
  85.     private static void mergeSort(HashMap<Integer, Integer> hashMap, HashMap<Integer, Integer> hashMapNew, int low, int meddle, int high){  
  86.         int k = low;  
  87.         int j = meddle+1;  
  88.         while(low<=meddle && j<=high){//两个序列组合成一个序列 从小到达的顺序  
  89.             if(hashMap.get(low) < hashMap.get(j)){  
  90.                 hashMapNew.put(k++, hashMap.get(low++));//放入合适的位置  
  91.             }else{  
  92.                 hashMapNew.put(k++, hashMap.get(j++));//放入合适的位置  
  93.             }             
  94.             contrastCount++;//发生一次对比  
  95.             swapCount++;//发生一次交换  
  96.         }  
  97.         //如果有一方多出来了 则直接赋值  
  98.         while(low<=meddle){  
  99.             hashMapNew.put(k++, hashMap.get(low++));//放入合适的位置  
  100.             swapCount++;//发生一次交换  
  101.         }  
  102.         while(j<=high){  
  103.             hashMapNew.put(k++, hashMap.get(j++));//放入合适的位置  
  104.             swapCount++;//发生一次交换  
  105.         }  
  106.         print(hashMapNew, printCount++);  
  107.     }  
  108.     /** 
  109.      * 打印已排序好的元素 
  110.      * @param hashMap 已排序的表 
  111.      * @param j 第j趟排序 
  112.      */  
  113.     private static void print(HashMap<Integer, Integer> hashMap, int j){  
  114.         if(j != 0)  
  115.             System.out.print("第 "+j+" 趟:\t");  
  116.         for(int i=1; i<hashMap.size(); i++){//从第一个一直输出到最后一个  
  117.             System.out.print(hashMap.get(i)+"\t");  
  118.         }  
  119.         System.out.println();  
  120.     }  
  121. }  

 

 

——————————————————最低位优先基数排序———————————————————

 

Java代码   收藏代码
  1. package com.sorting;  
  2.   
  3. /** 
  4.  * 最低位优先基数排序 
  5.  * @author HHF 
  6.  * 
  7.  */  
  8. public class LSDSort {  
  9.   
  10.     private static int contrastCount = 0;//对比次数  
  11.     private static int swapCount = 0;//交换次数  
  12.     private static int printCount = 1;//只为统计执行次数  
  13.   
  14.     public static void main(String[] args) {  
  15.         System.out.println("最低位优先基数排序:\n  按个位、十位、百位排序,不需要比较,只需要对数求余然后保存到相应下标的二维数组内,然后依次读取,每一进制重复依次 ,时间复杂度O(d(n+rd)),空间复杂度O(n+rd),稳定排序");          
  16.         int[] data = { 17322934355142865398133100 };  
  17.         System.out.println("初始序列为:");  
  18.         print(data, 0);//打印  
  19.         LSD(data, 3);  
  20.     }  
  21.       
  22.     public static void LSD(int[] number, int d) {// d表示最大的数有多少位  
  23.         int k = 0;//number的小标  
  24.         int n = 1;//当比较十位的时候 n=10  比较百位的时候 n=100 用来吧高位降低方便求余数   
  25.         int m = 1;//正在比较number中数据的倒数第几位  
  26.         int[][] temp = new int[10][number.length];// 数组的第一维表示可能的余数0-9 二维依次记录该余数相同的数  
  27.         int[] order = new int[10];// 数组orderp[i]用来表示该位的余数是i的数的个数  
  28.         //排序开始时间  
  29.         long start = System.currentTimeMillis();  
  30.         while (m <= d) {//d=5则比较五次  
  31.             for (int i = 0; i < number.length; i++) {//把number中的数按余数插入到temp中去  
  32.                 int lsd = ((number[i] / n) % 10);//求得该数的余数  
  33.                 temp[lsd][order[lsd]] = number[i];//保存到相应的地方  
  34.                 order[lsd]++;//该余数有几个  
  35.                 swapCount++;//发生一次交换  
  36.             }  
  37.             for (int i = 0; i < 10; i++) {//将temp中的数据按顺序提取出来  
  38.                 if (order[i] != 0)//如果该余数没有数据则不需要考虑  
  39.                     for (int j = 0; j < order[i]; j++) {//有给余数的数一共有多少个  
  40.                         number[k] = temp[i][j];//一一赋值  
  41.                         k++;  
  42.                         swapCount++;//发生一次交换  
  43.                     }  
  44.                 order[i] = 0;//置零,以便下一次使用  
  45.             }  
  46.             n *= 10;//进制+1 往前走  
  47.             k = 0;//从头开始  
  48.             m++;//进制+1  
  49.             print(number, printCount++);  
  50.         }  
  51.         //排序结束时间  
  52.         long end = System.currentTimeMillis();  
  53.         System.out.println("结果为:");  
  54.         print(number, 0);//输出排序结束的序列  
  55.         System.out.print("一共发生了 "+contrastCount+" 次对比\t");  
  56.         System.out.print("一共发生了 "+swapCount+" 次交换\t");  
  57.         System.out.println("执行时间为"+(end-start)+"毫秒");  
  58.     }  
  59.     /** 
  60.      * 打印已排序好的元素 
  61.      * @param data 已排序的表 
  62.      * @param j 第j趟排序 
  63.      */  
  64.     private static void print(int[] data, int j){  
  65.         if(j != 0)  
  66.             System.out.print("第 "+j+" 趟:\t");  
  67.         for (int i = 0; i < data.length; i++) {  
  68.             System.out.print(data[i] + " ");  
  69.         }  
  70.         System.out.println();  
  71.     }  
  72. }  

 

 

——————————————————算法分析————————————————————————

排序方法最好时间平均时间最坏时间辅助空间稳定性
直接插入O(n)O(n^2)O(n^2)O(1)稳定
冒泡O(n)O(n^2)O(n^2)O(1)稳定
简单选择O(n^2)O(n^2)O(n^2)O(1)不稳定
希尔 O(n^1.3) O(1)不稳定
快速O(nLNn)O(nLNn)O(n^2)O(LNn)不稳定
O(nLNn)O(nLNn)O(nLNn)O(1)不稳定
归并O(nLNn)O(nLNn)O(nLNn)O(n)稳定
基数O(d(n+rd))O(d(n+rd))O(d(n+rd))O(n+rd)稳定

原文地址:http://java--hhf.iteye.com/blog/2034925

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值