快速排序

快速排序原理

   简单的说,就是选取一个关键词(key) 将一个数列划分为两侧,一侧全部大于key,另一侧全部小于key.然后在分别对每一侧重复进行上述过程。直到最终排完序。

快速排序示意图
示意图来自百度百科“快速排序算法”词条,本图选取的是最左端的数位为key.

算法

   注意:下面的是选取最右边的数为key(下面写为k), 与上面示意图不同。
        a1,a2,,an
数组位数  0  1     n-1
位置   left   right
i,j初始位置 i j     k

第一步:进行第一次切分:

   当 j  < right 时: 
      若array[i] > k, j++;
      否则, array[i],array[j]的值互换。然后i++,j++

  这步中的I是用于分隔大于k的数和小于k的数,而j则用于检索,检索出每一个数,再与k进行比较,若小于k,则与i所指的数互换,i++,移到下一位,这样j所检索出的小于k的数便被放到i的左边。j++,检索下一位。如果j检索到的值>k,则这个数本来就在i的右边了,不需要交换,j++,检索下一位。直到j= right ,完成检索,跳出循环。

第二步:交换i 和 j 所指的数,即将 k放到他应该在的位置,即这个位置的一边都是大于k的,一边都是小于k的。

第三步:如果left < i-1 (即此时的k - 1),即left 没有和i -1 重合,此时left 和 i - 1 间还有未排序元素,对其进行快速排序。
   若 left == i - 1, 则左边排序完毕。
   若i + 1 (此时的k+1) < right ,同理。
   若切分后还未完成则继续切分进行快速排序,直到全部切分完毕,排序完毕,则完成。

虽然k的位置不同,但原理是相同的,可以参考开头的图来理解。

代码

#include<stdio.h>

void sort (int* array, int left, int right);
void swap (int *swap1, int *swap2);


int main() {
  int counter = 0, len = 0;
  int array[200] = {0}; //初始化
  scanf("%d", &len); // 待排序数组长度
  for (counter = 0; counter < len; counter++) {
    scanf("%d", &array[counter]);
  } //读入待排序数组

  for (counter = 0; counter < len; counter++) {
    printf("%d ", array[counter]);
  } // 输出待排序数组,用于和排序后的比较。
  sort (array, 0, len - 1);//排序
  printf("\n");//输出换行符
  for (counter = 0; counter < len; counter++) {
    printf("%d ", array[counter]);
  }//输出排序后数组
  return 0;//结束程序
}

void sort (int* array, int left, int right) {

  int i = left, j = left;//初始化,将i,j都置于待排序部分的最左端
  for (; j < right ;) {
    if (array[j] > array[right]) {//这里的array[right]就是上面讲的key
      j++;
    } else {
      swap(&array[i++], &array[j++]);
    }
  }//第一步
  swap(&array[i], &array[j]);//第二步
  if (left < i - 1) sort(array, left, i-1);
  if (right > i + 1) sort(array, i + 1, right);//第三步
}

void swap (int *swap1, int *swap2) {
  int temp = *swap1;
  *swap1 = *swap2;
  *swap2 = temp;
}//用于交换的函数

代码运行的结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值