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

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

快速排序 (Quick Sort)

我们依然考虑按照身高给学生排序。在快速排序中,我们随便挑出一个学生,以该学生的身高为参考(pivot)。然后让比该学生低的站在该学生的右边,剩下的站在该学生的左边。

很明显,所有的学生被分成了两组。该学生右边的学生的身高都大于该学生左边的学生的身高。

我们继续,在低身高学生组随便挑出一个学生,将低身高组的学生分为两组(很低和不那么低)。同样,将高学生组也分为两组(不那么高和很高)。

如此继续细分,直到分组中只有一个学生。当所有的分组中都只有一个学生时,则排序完成。

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


/*By Vamei*/
/*select pivot, put elements (<= pivot) to the left*/
void quick_sort(int a[], int ac)
{
  /*use swap*/

  /* pivot is a position, 
    all the elements before pivot is smaller or equal to pvalue */
  int pivot;
  /* the position of the element to be tested against pivot */
  int sample;

  /* select a pvalue. 
    Median is supposed to be a good choice, but that will itself take time.
    here, the pvalue is selected in a very simple wayi: a[ac/2] */
  /* store pvalue at a[0] */
  swap(a+0, a+ac/2);
  pivot = 1; 

  /* test each element */
  for (sample=1; sample<ac; sample++) {
    if (a[sample] < a[0]) {
      swap(a+pivot, a+sample);
      pivot++;
    }
  }
  /* swap an element (which <= pvalue) with a[0] */
  swap(a+0,a+pivot-1);

  /* base case, if only two elements are in the array,
    the above pass has already sorted the array */
  if (ac<=2) return;
  else {
    /* recursion */
    quick_sort(a, pivot);
    quick_sort(a+pivot, ac-pivot);
  }
}

理想的pivot是采用分组元素中的中位数。然而寻找中位数的算法需要另行实现。也可以随机选取元素作为pivot,随机选取也需要另行实现。为了简便,我每次都采用中间位置的元素作为pivot。

 

堆排序 (Heap Sort)

堆(heap)是常见的数据结构。它是一个有优先级的队列。最常见的堆的实现是一个有限定操作的Complete Binary Tree。这个Complete Binary Tree保持堆的特性,也就是父节点(parent)大于子节点(children)。因此,堆的根节点是所有堆元素中最小的。堆定义有插入节点和删除根节点操作,这两个操作都保持堆的特性。

我们可以将无序数组构成一个堆,然后不断取出根节点,最终构成一个有序数组。