算法(3)

直接插入,希尔排序,归并排序
首先是直接插入:很现实的例子就是斗地主,拿到一手乱牌,从第一张看起,然后是第二张,然后比较,前两张的大小,然后排序,
 
比较简单的一种排序
java代码实现:
private static void InsertSort(int[] a) {
          // 无需序列
          int temp;
          int j;
          for (int i = 1; i < a.length; i++) {
               if (a[i] < a[i - 1]) {
                    temp = a[i];
                    for (j = i - 1; j >= 0; j--) {
                         a[j+1]=a[j];
                    }
                    a[j+1]=temp;
               }
          }
     }
同样的测试数量:216ms
排序效率拙计啊。
 
希尔排序:
当数组是5,4,3,2,1时候插入排序,每一次就都要移动十分的烦人,效率十分底下,shell根据这个弱点进行了算法改进,融入了一种叫做“缩小增量排序法”的思想,其实也蛮简单的,不过有点注意的就是:增量不是乱取,而是有规律可循的。
 
 
增量的选取:
第一次:d=count/2
第二次:d=(count/2)/2
最后:d=1;
上面的的现象:
d=3:40-50不交换,20-30不交换,80-60交换 最后40,20,60,50,30,80
d=2:40-60不交换,60-30交换,此时40-30再次交换,20-50不交换,50-80不交换  30,20,40,50,60,80
d=1:30-20交换30-40不交换,40-50不交换,50-60不交换,60-80不交换 20,30,40,50,60,80
 
希尔排序是插入排序的改进版本。
java实现:
// 希尔排序
     private static void ShlleSort(int[] a) {
          int step=a.length/2;//增量
          while(step>=1){
               for(int i=step;i<a.length;i++){
                    int temp=a[i];
                    int j;
                    for(j=i-step;j>=0&&temp<a[j];j=j-step){
                         a[j+step]=a[j];
                    }
                    a[j+step]=temp;
               }
               step=step/2;
          }
     }
 
运行时间:38;
 
下面是归并排序:归并排序是非常明显的算法设计分治法的一种。
分治法的思想:由一个大规模的问题分解成,互不相干的规模小的子问题,然后把小的问题在分。这是分
治:分解了之后就要解决了,治就是解决,这里应用的就是排序,把分解的最小单位来解决排序
合并:最后一步就是合并了,把排序好的若干个小问题合并,在排序。最后解决。
 
那么我们来看看归并排序:
 
 
归并排序分两步:
1.分,将数组尽可能的分,一直到原子级别。
2.并,将原子级别的数两两合并排序,最后产生结果。
 
 
// 归并排序
     // 第一步数组的划分
     private static void MergeSort(int[] a, int[] temparray, int left, int right) {
          if (left < right) {
               int middle = (left + right) / 2;
               // 递归的划分数组左序列
               MergeSort(a, temparray, left, middle);
               // 递归的划分数组右序列
               MergeSort(a, temparray, middle + 1, right);
               // 数组合并操作
               Merge(a, temparray, left, middle + 1, right);
          }
     }

     // 数组两两合并
     private static void Merge(int[] a, int[] temparray, int left, int middle,
               int right) {
          int leftEnd = middle-1;
          int rightStart = middle;
          int tempIndex = left;
          int tempLength = right - left + 1;
          // 先循环两个区间都没有结束的情况
          while ((left <= leftEnd) && (rightStart <= right)) {
               if (a[left] < a[rightStart]) {
                    temparray[tempIndex++] = a[left++];
               } else {
                    temparray[tempIndex++] = a[rightStart++];
               }
          }

          // 判断左序列是否结束
          while (left <= leftEnd) {
               temparray[tempIndex++] = a[left++];
          }
          // 判断右序列是否结束
          while (rightStart <= right) {
               temparray[tempIndex++] = a[rightStart++];
          }
          // 交换数据
          for (int i = 0; i < tempLength; i++) {
               a[right] = temparray[right];
               right--;
          }
     }
posted @ 2015-06-17 23:49  呜呜啦啦拉  阅读(155)  评论(0)    收藏  举报