算法学习入门之使用C语言实现各大基本的排序算法

2020-01-06 14:01:56王冬梅

完成对四个子数组的排序后,数组的顺序并不一定能排列好。希尔排序会不断减小间隔,重新形成子数组,并对子数组冒泡排序…… 当间隔减小为1时,就相当于对整个数组进行了一次冒泡排序。随后,数组的顺序就排列好了。

希尔排序不止可以配合冒泡排序,还可以配合其他的排序方法完成。


/*By Vamei*/
/*quickly sort the turtles at the tail of the array*/
void shell_sort(int a[], int ac)
{
  int step;
  int i,j;
  int nsub;
  int *sub;

  /* initialize step */
  step = 1;
  while(step < ac) step = 3*step + 1;

  /* when step becomes 1, it's equivalent to the bubble sort*/
  while(step > 1) {
    /* step will go down to 1 at most */
    step = step/3 + 1;
    for(i=0; i<step; i++) {
      /* pick an element every step, 
       and combine into a sub-array */
      nsub = (ac - i - 1)/step + 1;      
      sub = (int *) malloc(sizeof(int)*nsub);
      for(j=0; j<nsub; j++) {
        sub[j] = a[i+j*step]; 
      }
      /* sort the sub-array by bubble sorting. 
       It could be other sorting methods */
      bubble_sort(sub, nsub);
      /* put back the sub-array*/
      for(j=0; j<nsub; j++) {
        a[i+j*step] = sub[j];
      }
      /* free sub-array */
      free(sub);
    }  
  }
}

Shell Sorting依赖于间隔(step)的选取。一个常见的选择是将本次间隔设置为上次间隔的1/1.3。见参考书籍。

 

归并排序 (Merge Sort)

如果我们要将一副扑克按照数字大小排序。此前已经有两个人分别将其中的一半排好顺序。那么我们可以将这两堆扑克向上放好,假设小的牌在上面。此时,我们将看到牌堆中最上的两张牌。

我们取两张牌中小的那张取出放在手中。两个牌堆中又是两张牌暴露在最上面,继续取小的那张放在手中…… 直到所有的牌都放入手中,那么整副牌就排好顺序了。这就是归并排序。

下面的实现中,使用递归:


/*By Vamei*/
/*recursively merge two sorted arrays*/
void merge_sort(int *a, int ac)
{
  int i, j, k;  
  int ac1, ac2;
  int *ah1, *ah2;
  int *container;

  /*base case*/  
  if (ac <= 1) return;

  /*split the array into two*/
  ac1 = ac/2;
  ac2 = ac - ac1;
  ah1 = a + 0;
  ah2 = a + ac1;

  /*recursion*/
  merge_sort(ah1, ac1);
  merge_sort(ah2, ac2);
 
  /*merge*/
  i = 0;
  j = 0;
  k = 0;
  container = (int *) malloc(sizeof(int)*ac);
  while(i<ac1 && j<ac2) {
    if (ah1[i] <= ah2[j]) {
      container[k++] = ah1[i++];
    } 
    else {
      container[k++] = ah2[j++];
    }
  }
  while (i < ac1) {
    container[k++] = ah1[i++];
  }
  while (j < ac2) {
    container[k++] = ah2[j++];
  }

  /*copy back the sorted array*/
  for(i=0; i<ac; i++) {
    a[i] = container[i];
  }
  /*free space*/
  free(container);
}