A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Super_Class 高级黑马   /  2013-5-8 23:54  /  2021 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Super_Class 于 2013-5-9 14:57 编辑

最快的是希尔算法,求详细代码。附注释最好

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

12 个回复

倒序浏览
本帖最后由 Jacky_Chen1990 于 2013-5-9 00:00 编辑

占楼。编辑代码中。。
  1. public class Sort {

  2.         /**
  3.          * 希尔排序也是一种插入排序方法,实际上是一种分组插入方法
  4.          * 先取一个小于n的整数d1作为一个增量,把表的全部记录分成d1个组,所有
  5.          * 距离为d1的倍数的记录放在同一个组中,在各组内进行直接插入排序,然后
  6.          * ,取第二个增量d2(<d1),重复上述的分组和排序,直至所取的dt=1,即所有
  7.          * 记录放在同一组中进行直接插入排序为止
  8.          */
  9.         public static int[] shellSort(int []R){
  10.                
  11.                 int gap = R.length/2;
  12.                 int temp;
  13.                 while(gap>0){
  14.                         for(int i=gap;i<R.length;i++){
  15.                                 temp = R[i];
  16.                                 int j = i - gap;
  17.                                 while(j>=0 && temp < R[j]){
  18.                                         R[j+gap] = R[j];
  19.                                         j = j - gap;
  20.                                 }
  21.                                 R[j+gap] = temp;
  22.                         }
  23.                         gap = gap/2;
  24.                 }
  25.                 return R;
  26.         }
  27.        
  28.         public static void display(int[] R){
  29.                 System.out.println();
  30.                 for(int i=0;i<R.length;i++){
  31.                         System.out.print(R[i]+" ");
  32.                 }
  33.         }
  34.        
  35.         public static void main(String[] args) {
  36.                
  37.                 final int M = 50;//定义数组大小为50
  38.                 int []R = new int[M];
  39.                 for(int i=0;i<M;i++){
  40.                         R[i] = new Random().nextInt(100);//生成100以内的随机数
  41.                 }
  42.                 display(R);
  43.                 R = shellSort(R);
  44.                 display(R);

  45.         }

  46. }
复制代码
欢迎指教。

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
复杂度的计算好像有很多种说法。这个要深究数据库。。我回去研究下。。再来。。
回复 使用道具 举报
尹桥印 发表于 2013-5-9 00:03
嘿嘿,我现在处于断网之中,用手机连的~网速不行,~~就让你沙发呐~~嘿嘿

我前面也是哦。。。
回复 使用道具 举报
尹桥印 发表于 2013-5-9 00:06
加油加油。努力学知识。

恩啦。加油~~你准备进第几期?
回复 使用道具 举报
尹桥印 发表于 2013-5-9 00:09
我早呢,非常早。

点点点。
回复 使用道具 举报
研究研究
回复 使用道具 举报
long 中级黑马 2013-5-9 01:05:05
8#
/**希尔排序是基于插入排序的一种算法,时间复杂度为 O(N*(logN)2)。
*下面的希尔排序要求待排序的数组必须实现Comparable接口
*/
public class ShellSort
{
       private int[] increment;
       /**
       *利用希尔排序算法对数组obj进行排序
       */
       public void sort(Comparable[] obj)
       {
              if (obj == null)
              {
                     throw new NullPointerException("The argument can not be null!");
              }

              //初始化步长
              initGap(obj);

              //步长依次变化(递减)
              for (int i = increment.length - 1 ;i >= 0 ;i-- )
              {
                     int step = increment;                    
                     //由步长位置开始

                     for (int j = step ;j < obj.length ;j++ )
                     {
                            Comparable tmp;

                            //如果后面的小于前面的(相隔step),则与前面的交换
                            for (int m = j ;m >= step ;m = m - step )
                            {
                                   if (obj[m].compareTo(obj[m - step]) < 0)
                                   {
                                          tmp = obj[m - step];
                                          obj[m - step] = obj[m];
                                          obj[m] = tmp;
                                   }
                                   //因为之前的位置必定已经比较过,所以这里直接退出循环
                                   else
                                   {
                                          break;
                                   }
                            }
                     }
              }
       }


       /**
       *根据数组的长度确定求增量的公式的最大指数,公式为pow(4, i) - 3 * pow(2, i)
+ 1和9 * pow(4, i) - 9 * pow(2, i) + 1
       *@return int[] 两个公式的最大指数
       *@param length 数组的长度
       */
       private int[] initExponent(int length)
       {
              int[] exp = new int[2];
              exp[0] = 1;
              exp[1] = -1;
              int[] gap = new int[2];
              gap[0] = gap[1] = 0;

              //确定两个公式的最大指数
              while (gap[0] < length)
              {
                     exp[0]++;
                     gap[0] = (int)(Math.pow(4, exp[0]) - 3 * Math.pow(2, exp[0]) + 1);                     
              }
              exp[0]--;

              while (gap[1] < length)
              {
                     exp[1]++;
                     gap[1] = (int)(9 * Math.pow(4, exp[1]) - 9 * Math.pow(2, exp[1]) + 1);                       
              }
              exp[1]--;
              return exp;
       }

       private void initGap(Comparable[] obj)
       {
              //利用公式初始化增量序列
              int exp[] = initExponent(obj.length);
              int[] gap = new int[2];

               increment = new int[exp[0] + exp[1]];              






              //将增量数组由大到小赋值
              for (int i = exp[0] + exp[1] - 1 ;i >= 0 ;i-- )
              {
                     gap[0] = (int)(Math.pow(4, exp[0]) - 3 * Math.pow(2, exp[0]) + 1);
                     gap[1] = (int)(9 * Math.pow(4, exp[1]) - 9 * Math.pow(2, exp[1]) + 1);

                     //将大的增量先放入增量数组,这里实际上是一个归并排序
                     //不需要考虑gap[0] == gap[1]的情况,因为不可能出现相等。
                     if (gap[0] > gap[1])
                     {
                            increment = gap[0];
                            exp[0]--;
                     }
                     else
                     {
                            increment = gap[1];
                            exp[1]--;
                     }
              }            
       }
}

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
排序的平均时间:快速排序、希尔排序、归并排序、堆排序都为O(N*(logN)2).其他的都是O(n^2),一个特殊的是基数排序,为O(d(n+R)).
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法。[1]
比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比[1]较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
给定实例的shell排序的排序过程
假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04。
增量序列的取值依次为:
5,2,1
希尔排序是最快的之一,算法并不稳定。
  1. package sort;

  2. public class ShellSortTest {
  3. public static int count = 0;

  4. public static void main(String[] args) {

  5. int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 }; //定义数组
  6. print(data); //打印排序前的数组元素
  7. shellSort(data); //希尔排序
  8. print(data); //打印排序后的数组元素

  9. }

  10. public static void shellSort(int[] data) {
  11. // 计算出最大的h值
  12. int h = 1;
  13. while (h <= data.length / 3) {
  14. h = h * 3 + 1;
  15. }
  16. while (h > 0) {
  17. for (int i = h; i < data.length; i += h) {
  18. if (data[i] < data[i - h]) {
  19. int tmp = data[i];
  20. int j = i - h;
  21. while (j >= 0 && data[j] > tmp) {
  22. data[j + h] = data[j];
  23. j -= h;
  24. }
  25. data[j + h] = tmp;
  26. print(data);
  27. }
  28. }
  29. // 计算出下一个h值
  30. h = (h - 1) / 3;
  31. }
  32. }

  33. public static void print(int[] data) {
  34. for (int i = 0; i < data.length; i++) {
  35. System.out.print(data[i] + "\t");
  36. }
  37. System.out.println();
  38. }

  39. }
复制代码
回复 使用道具 举报
运行结果:
  1. 5   3   6   2   1   9   4   8   7     
  2. 1   3   6   2   5   9   4   8   7     
  3. 1   2   3   6   5   9   4   8   7     
  4. 1   2   3   5   6   9   4   8   7     
  5. 1   2   3   4   5   6   9   8   7     
  6. 1   2   3   4   5   6   8   9   7     
  7. 1   2   3   4   5   6   7   8   9     
  8. 1   2   3   4   5   6   7   8   9  
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马