分治法之快速排序算法

这周的算法设计与分析的作业,要求是根据所讲基本算法选择其一,给出具体事例,并且详细描述算法实现过程,同时利用一种语言编程实现,得出结果。将整个过程详细整理上传平台。
上周所讲算法也只有那么几种:分治法,动态规划、贪心算法、回溯法、分值界限。
这次用了分治法解决快速排序的问题。

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,它的具体思想如下:
1.从数列中挑出一个元素,称为 “基准”(pivot);
2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3.递归(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

本次试验的目的是随机生成9个正整数,然后使用快速排序算法对这9个正整数从小到大进行排序,并输出排序结果。程序如附录一所示,运行结果如附录二所示。

具体的步骤如下:
1. 假设随机数为83,82,86,84,23,43,61,83,53,并打印出来。
2. 设最左边的数a[left]=a[0],最右边的数a[right]=a[8],若left小于right,则进行下面的分区。
3. 设a[right]为基准值,从左边第一个数开始与基准数进行比较,若a[i]比基准值小,则与a[j]交换位置,最终排列情况为,以基准值为中心,基准值左边的值小于基准值,基准值右边的值大于基准值。例如;第一次分区结果为:23,43,53,83,82,86,84,61,83。
4. 以基准数为界限,左边的区从a[0]到基准数前一个数,右边的区从基准数后一个到a[8],重新进行步骤3.
5. 一直重复步骤4,直到数列按照从小到大排列。
6. 打印出来最终结果。

附录一:

#include
#include
#include
#define RANDOM(i) (rand()%i)
#define N 9    //设置数组长度
//分区操作
int Partition(int array[], int left, int right)
{
 int i,j;
 int temp;
 j = left-1;
 for (i=left; i<=right; i++)
 {
  if (array[i] <=  array[right]) //以最后一个数的值为基准
  {
   j++;
   temp = array[j];
   array[j] = array[i];
   array[i] = temp;
  }
 }
 return j;
}
//迭代运算
void QuikSort(int array[], int left, int right)
{
 int pivot;
 if (left < right)
 {
  pivot = Partition(array, left, right);
  QuikSort(array, left, pivot-1);
  QuikSort(array, pivot+1, right);
 }
}
//示例
int main()
{
 int i = 0;
 int a[N];
 srand((int)time(0));  //设置随机数种子
 for (i=0; i//排序前
 {
  a[i] = RANDOM(100);
  printf("%d, ", a[i]);
 }
 printf("\n\n");
 QuikSort(a, 0, N-1);
 for (i=0; i//排序后
 {
  printf("%d, ", a[i]);
 }
printf("\n\n");
 system("pause");
 return 0;
}

分治法之快速排序算法_第1张图片

你可能感兴趣的:(算法)