用分治法实现快排

#include "stdio.h"

/*

* 显示数组

* 只显示begin 到 end 下标间的数据到对应位置。

* 如,数组为 13, 17, 12 并先后执行:

* show(array, 3, 0, 2);

* show(array, 3, 1, 2);

* show(array, 3, 1, 1);

* 会显示为:

* 13 17 12

* 17 12

* 17

*/

void show(int array[], long maxlen, int begin, int end)

{

int i = 0;

/* 不关心的数据用空格填充显示 */

for (i = 0; i<begin; i++)

printf(" ");

for (i = begin; i <= end; i++)

printf("%4d", array[i]);

printf("\n");

}

/*

* 两个数交换数值。

* 返回为 1 时说明进行了交换。

* 返回为 0 时说明两个数值相同没必要交换。

* 此返回值可以用于只想打印结果变化的情况。

*/

int swap(int *i, int *j)

{

int temp;

if (*i == *j)

return 0;

temp = *i;

*i = *j;

*j = temp;

return 1;

}

/*

* 快速排序函数

* 此函数只会对begin下标(包括begin )和end(包括end)下标间的数据进行排序

*/

void quicksort(int array[], int maxlen, int begin, int end)

{

int i, j;

if (begin < end) {

/* 因为开始值作为基准值不用移动,所以需要比较的值是从 begin+1 开始 */

i = begin + 1;

j = end;

/*

* 此循环的作用:array[begin] 为基准对 array[begin+1] 和 array[end]

* 之间的数进行初步分组,分组后的效果见循环后的描述

*

* 此处写 while(i != j) 是等价的,因为初始状态 i<=j 且每次i和j的

* 相对变化值为 1 所以不会出现 i>j的情况

*/

while (i < j) {

/* 如果当前值大于 array[begin],把当前值换到 j 指向的位置,换位后 j 下标前移 */

if (array[i] > array[begin]) {

if (swap(&array[i], &array[j]) == 1)

show(array, maxlen, begin, end); /* 只显示begin 到 end 下标间的数据 */

j--;

}

/* 否则 i 下标向后移动,准备比较下一个数。*/

else

i++;

}

/*

* 在此时: i=j, array还没有进行判断处理

* 且 array[begin+1] ~ array[i-1] 都小于 array[begin]

* 且 array[i+1] ~ array[end] 都大于 array[begin]

*

* 接着: 对 array[begin] 和 array[i] 比较并处理

* 目的是判断 array[i] 应该分在左组还是右组,

* 同时还要把 array[begin] 的值放在分割线位置。

*

* 如果 array[i] 的值大于 array[begin],则把 array[begin] 放在 i 前

* 也就是把 array[begin] 和 i 前的数换位

*/

if (array[i] > array[begin])

i--;

/* 把 array[begin] 放在 i 指向的位置 */

if (swap(&array[begin], &array[i]) == 1)

/* 只显示begin 到 end 下标间的数据 */

show(array, maxlen, begin, end);

/* 再从分割线位置 i 分组分别排序 */

quicksort(array, maxlen, begin, i);

quicksort(array, maxlen, j, end);

}

}

int main(int argc, char* argv[])

{

int array[10] = { 49, 38, 65, 97, 48, 13, 27, 11, 56, 45 };

int maxlen = sizeof(array) / sizeof(int);

show(array, maxlen, 0, maxlen - 1); /* 打印初始顺序 */

quicksort(array, maxlen, 0, maxlen - 1);

show(array, maxlen, 0, maxlen - 1); /* 打印最终结果 */

getchar();

return 0;

}

时间: 2024-11-06 05:25:43

用分治法实现快排的相关文章

分治法快排

//快速排序,第一步确定一个关键值key(一般设置为第一个元素),一次快排基本思路是将比key小的数放在key的左边将比key大的数放在key右边,于是完成一次快排 接下来对key左边和右边分别递归采用同样方法 算法步骤: 1.选择一个基准key(一般选第一个元素) 2设定两个指针low和high,初始指向第一个元素和最后的一个元素 3.先将high从右向左扫描直到找到比key小的元素,将此元素移到low位置,然后low从左向右扫描,找到比key大元素移动到high的位置 一次快排结束的条件为l

快速排序--QuickSort,看完五分彩开奖网平台搭建自己就能写出来的快排思路推演

快速五分彩开奖网平台搭建论坛:haozbbs.com Q1446595067排序(QuickSort)介绍首先发明者竟然敢给自己发明的算法叫做QuickSort,这个名字闪不闪亮?好比别的武功叫做六脉神剑.降龙十八掌,我这个叫做"天下无敌神功".别的排序算法都是按照特点来起的,你这个不是应该叫分块递归排序法吗?或者和希尔一样,叫做霍尔排序也可以啊,这么高调是要干啥啊?我给了他一次机会,特意去查了一下,这个名字并不是江湖朋友抬爱给的,就是发明者自己起的,社会社会...不过看完这篇博客,理

分治法(一)

这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它们放在一起来比较,看看分治是如何实现滴.由于内容太多,我将再花一篇文章来写4个之前没有写过的分治算法:1,大整数乘法   2,矩阵乘法的分治策略   3,最近点对  4,凸包问题,请见下一篇. 好了,切入正题. --------------------------------------------

堆排 归并排序 快排

堆排序的思想 利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单. 其基本思想为(大顶堆): 1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区: 2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n]; 3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,

快排、归并排序(分治)、堆排序

一.快速排序 1)算法简介 快速排序是由C. A. R. Hoare所发展的一种排序算法.其基本思想是基本思想是,通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序. 2)算法描述 快速排序使用分治法来把一个串(list)分为两个子串行(sub-lists). 步骤为: 1.从数列中挑出一个元素,称为 "基准"(pivot), 2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准

算法(二)--------分治法

分治法的适?条件: • 该问题的规模缩?到?定程度就可以容易地解决.• 该问题可以分解为若?个规模较?的相同问题:递归思想的应?• 该问题所分解出的各个?问题是相互独?的,即?问题之间不包含公共的?问题.• 利?该问题分解出的?问题的解可以合并为该问题的解. 案例---快排: (1)过程 • Divide (Partition) – 对元素进?重排以得到这样?个划分 • 在某个位置s前?的所有元素都?于等于A[s] • 在位置s后?的所有元素都?于等于A[s]• Conquer: ?个划分确定后

常见经典排序算法学习总结,附算法原理及实现代码(插入、shell、冒泡、选择、归并、快排等)

博主在学习过程中深感基础的重要,经典排序算法是数据结构与算法学习过程中重要的一环,这里对笔试面试最常涉及到的7种排序算法(包括插入排序.希尔排序.选择排序.冒泡排序.快速排序.堆排序.归并排序)进行了详解.每一种算法都有基本介绍.算法原理分析.算法代码. 转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/47280135 插入排序 1)算法简介 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过

分治法-合并排序和快速排序

分治法是按照以下方案工作的: 将问题的实例划分为同一个问题的几个较小的实例,最好拥有同样的规模 对这些较小的实例求解(一般使用递归方法,但在问题规模足够小的时候,有时会利用另一种算法以提高效率) 如果必要的话,合并较小问题的解,以得到原始问题的解 分治法的流程: 4.1 合并排序 合并排序是成功应用分治技术的一个完美例子(书上说的). 对于一个需要排序的数组,合并排序把它一分为二,并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组. 代码实现: /** * 合并排序 * @au

Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排序.快速排序(重点).堆排序.归并排序等等.看下图: 给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78} 一.直接插入排序(内部排序.O(n2).稳定) 原理:从待排序的数中选出一个来,插入到前面的合适位置. [java] view plain copy