C++快速排序 c语言法问题

快速排序 - 如果天空不死 - 博客园
随笔 - 278
评论 - 594
本章介绍排序算法中的快速排序。
目录1.&2.&3.&4.&4.1&4.2&4.3&
转载请注明出处:
更多内容:
快速排序介绍
快速排序(Quick Sort)使用分治法策略。它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序流程:(1) 从数列中挑出一个基准值。(2) 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。(3) 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。
快速排序图文说明
快速排序代码
* 快速排序
* 参数说明:
a -- 待排序的数组
l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
void quick_sort(int a[], int l, int r)
if (l & r)
int i,j,x;
while (i & j)
while(i & j && a[j] & x)
j--; // 从右向左找第一个小于x的数
a[i++] = a[j];
while(i & j && a[i] & x)
i++; // 从左向右找第一个大于x的数
a[j--] = a[i];
quick_sort(a, l, i-1); /* 递归调用 */
quick_sort(a, i+1, r); /* 递归调用 */
下面以数列a={30,40,60,10,20,50}为例,演示它的快速排序过程(如下图)。
上图只是给出了第1趟快速排序的流程。在第1趟中,设置x=a[i],即x=30。(01) 从"右 --&
左"查找小于x的数:找到满足条件的数a[j]=20,此时j=4;然后将a[j]赋值a[i],此时i=0;接着从左往右遍历。(02) 从"左 --&
右"查找大于x的数:找到满足条件的数a[i]=40,此时i=1;然后将a[i]赋值a[j],此时j=4;接着从右往左遍历。(03) 从"右 --&
左"查找小于x的数:找到满足条件的数a[j]=10,此时j=3;然后将a[j]赋值a[i],此时i=1;接着从左往右遍历。(04) 从"左 --&
右"查找大于x的数:找到满足条件的数a[i]=60,此时i=2;然后将a[i]赋值a[j],此时j=3;接着从右往左遍历。(05) 从"右 --&
左"查找小于x的数:没有找到满足条件的数。当i&=j时,停止查找;然后将x赋值给a[i]。此趟遍历结束!
按照同样的方法,对子数列进行递归遍历。最后得到有序数组!
快速排序的时间复杂度和稳定性
快速排序稳定性快速排序是不稳定的算法,它不满足稳定算法的定义。算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
快速排序时间复杂度快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)。这句话很好理解:假设被排序的数列中有N个数。遍历一次的时间复杂度是O(N),需要遍历多少次呢?至少lg(N+1)次,最多N次。(01) 为什么最少是lg(N+1)次?快速排序是采用的分治法进行遍历的,我们将它看作一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。因此,快速排序的遍历次数最少是lg(N+1)次。(02) 为什么最多是N次?这个应该非常简单,还是将快速排序看作一棵二叉树,它的深度最大是N。因此,快读排序的遍历次数最多是N次。
快速排序实现
快速排序C实现实现代码(quick_sort.c)
* 快速排序:C 语言
* @author skywang
8 #include &stdio.h&
10 // 数组长度
11 #define LENGTH(array) ( (sizeof(array)) / (sizeof(array[0])) )
* 快速排序
* 参数说明:
a -- 待排序的数组
l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
21 void quick_sort(int a[], int l, int r)
if (l & r)
int i,j,x;
while (i & j)
while(i & j && a[j] & x)
j--; // 从右向左找第一个小于x的数
a[i++] = a[j];
while(i & j && a[i] & x)
i++; // 从左向右找第一个大于x的数
a[j--] = a[i];
quick_sort(a, l, i-1); /* 递归调用 */
quick_sort(a, i+1, r); /* 递归调用 */
47 void main()
int a[] = {30,40,60,10,20,50};
int ilen = LENGTH(a);
printf("before sort:");
for (i=0; i& i++)
printf("%d ", a[i]);
printf("\n");
quick_sort(a, 0, ilen-1);
printf("after
for (i=0; i& i++)
printf("%d ", a[i]);
printf("\n");
快速排序C++实现实现代码(QuickSort.cpp)
* 快速排序:C++
* @author skywang
8 #include &iostream&
9 using namespace
* 快速排序
* 参数说明:
a -- 待排序的数组
l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
19 void quickSort(int* a, int l, int r)
if (l & r)
int i,j,x;
while (i & j)
while(i & j && a[j] & x)
j--; // 从右向左找第一个小于x的数
a[i++] = a[j];
while(i & j && a[i] & x)
i++; // 从左向右找第一个大于x的数
a[j--] = a[i];
quickSort(a, l, i-1); /* 递归调用 */
quickSort(a, i+1, r); /* 递归调用 */
45 int main()
int a[] = {30,40,60,10,20,50};
int ilen = (sizeof(a)) / (sizeof(a[0]));
cout && "before sort:";
for (i=0; i& i++)
cout && a[i] && " ";
quickSort(a, 0, ilen-1);
cout && "after
for (i=0; i& i++)
cout && a[i] && " ";
快速排序Java实现实现代码(QuickSort.java)
* 快速排序:Java
* @author skywang
8 public class QuickSort {
* 快速排序
* 参数说明:
a -- 待排序的数组
l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
public static void quickSort(int[] a, int l, int r) {
if (l & r) {
int i,j,x;
while (i & j) {
while(i & j && a[j] & x)
j--; // 从右向左找第一个小于x的数
a[i++] = a[j];
while(i & j && a[i] & x)
i++; // 从左向右找第一个大于x的数
a[j--] = a[i];
quickSort(a, l, i-1); /* 递归调用 */
quickSort(a, i+1, r); /* 递归调用 */
public static void main(String[] args) {
int a[] = {30,40,60,10,20,50};
System.out.printf("before sort:");
for (i=0; i&a. i++)
System.out.printf("%d ", a[i]);
System.out.printf("\n");
quickSort(a, 0, a.length-1);
System.out.printf("after
for (i=0; i&a. i++)
System.out.printf("%d ", a[i]);
System.out.printf("\n");
上面3种语言的实现原理和输出结果都是一样的。下面是它们的输出结果:
before sort:30 40 60 10 20 50
sort:10 20 30 40 50 60
阅读(...) 评论()& C/C++各种排序算法的讲解与实现
C/C++各种排序算法的讲解与实现
排序的分类:
1 内部排序
内部排序:在整个排序过程中不需不访问外存便能完成,称这样的排序问题为内部排序;
1.1 插入排序
插入排序: 将无序序列中的一个或几个记录“插入”到有序的序列中,从而增加记录的有序序列的长度。
主要思想是将第一个元素看做是有序的,从第二个元素起将待排序的元素插入到有序序列中,使序列逐渐扩大,直到所有的元素都插入到有序序类中。
直接插入排序
基本思想是将记录R[i]插入到有序序列R[1..i-1],使记录的有序序列从R[1..i-1]变为R[1..i]。
直接插入排序算法最好情况下的时间复杂度为O(n),最坏情况的时间复杂度和平均时间复杂度为O(n^2)。
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#include "stdafx.h"
#include &iostream&
void StrInsSort (int number
for(int i=1;i&=i++)
temp=r[i];int j=i-1;
while(temp&r[j])
r[j+1]=r[j];
int _tmain(int argc, int argv[])
std::cout&&"输入数组大小"&&
std::cin&&
std::cout&&"输入数组内数据"&&
for(int j=0;j&j++)
std::cin&&argv[j];
StrInsSort (argc ,argv);
for(int j=0;j&j++)
std::cout && argv[j] && std::
system("pause");
次待排序数组是从0开始的,先假定第0个元素是有序的,从第一个元素起与前边的有序序列进行比较,T先和下标为i-1的数组比较,(生成的整个序列是从小到达排列的)如果
r[i]&r[i-1],则直接放在r[i]的位置,否则如果T&r[i-1],则将将i--,直到找到一个比T小的,把T放在该数的后边;
折半插入排序
折半插入与直接插入比较,当第i 个记录要插入到前i-1个记录序列时,可以利用折半查找方式确定插入位置,以减少比较次数。
折半查找明显减少了关键字的“比较”次数,单记录的移动次数不变,故时间复杂度仍为O(n^2)。
[html][/html] view plaincopy
void BinSort (int count, int R[])
for (int i=1;i&=i++)
int left=0;
int right=i-1;
while (right&=left)
temp=R[i] ;
int mid =(left+right)/2;
if (temp&R[mid])
left=mid+1;
right=mid-1;
for (int j=i-1;j&=right+1;j--)
R[j+1]=R[j];
R[right+1]=
函数写过程中,首先确定有多少个元素要参加排序,由于次数组是从下表0开始的,所以和直接插入排序一样,先假设第0个元素是有序的,则从下标为1的元素开始执行循环,即从1到count个元素都要执行对比循环过程;其循环内部基本思路是,把取到的第i个元素插入到前0到i-1个元素中,因为前i个元素是有序的,所以二分查找是拿第i元素和和前面有序数列中的第mid =(left+right)/2个元素比较,即有序数列中中间的那个元素,因为排序后要生成一个从小到大排序的数列,即升序数列,所以如果temp&R[mid]如下图所示,
则要是插入 temp后整个数列依然有序,则temp必须在6的后面,所以要最左侧的数为left=mid+1;才能保证在后半部分寻找数据;
然后就要判断循环什么时候终止,因为在整个循环过程中不断缩小循环的范围,即left和right的距离越来越近,当left==right时,这时mid==left==righ, 这时,
if (temp&R[mid])
left=mid+1;
如上图所示,mid在6的位置,此时的temp是&6而&7 的,应该把&=left的或&=mid+1的或&=right+1的元素向后移一位;
right=mid-1;
如上图所示,mid应该&6且&4,即放在4和6之间,这样更应该把&=left的后&=mid的或&=right+1的元素向后移一位;
for (int j=i-1;j&=right+1;j--)
R[j+1]=R[j];
即对应这段程序;
经过上边分析,同样也可以写成下面程序,即把&=right+1,改成&=
for (int j=i-1;j&=j--)
R[j+1]=R[j];
二路插入排序
基本思想是另设一数组d,将R[1]复制给d[1],并将d[1]看做排好序的“中间”记录,从第二个起依次将关键字小于d[1]的记录插入到d[1]之前的有序序列中,将关键字大于d[1]的记录插入到d[1]之后的有序序列中。这里借助两个变量first和final来指示排序过程中有序序列第一个记录和最后一个记录在d中的位置。
[html][/html] view plaincopy
int BiInsertSort()
//二路插入排序算法
int iRawBuff[6] ={0,9,6,7,3,2};
int final = 0;
int first = 0;
const int iLenght = 5;
int iTempBuff[iLenght] = {0};
iTempBuff[0] = iRawBuff[0];
for (int i = 1; i &= iLi++)
if(iRawBuff[i] & iTempBuff[final])
//大于当前最大值,后插
iTempBuff[final] = iRawBuff[i];
if(iRawBuff[i]& iTempBuff[first])
//小于当前最小值,前插
first = (first-1+iLenght)%iL
iTempBuff[first] = iRawBuff[i];
if(iRawBuff[i] & iTempBuff[final]&&iRawBuff[i] & iTempBuff[first])
//大于当前最小值,小于当前最大值,中间插
int j = final++;
while (iRawBuff[i] & iTempBuff[j])
iTempBuff[(j+1)%iLenght] = iTempBuff[j];
j = (j-1+iLenght)%iL
iTempBuff[j+1] = iRawBuff[i];
printf("第%d趟:\n",i-1);
for(int k = 0; k & iL k++)
std::cout&&iTempBuff[k]&&"\t";
std::cout&&std::
//导入输入到原始数组中
for (int k = 0; k & iL k++)
iRawBuff[k+1] = iTempBuff[(first++)%iLenght];
运行结果:
由于first在增加增加的过程中,没有最大值的限制,为了防止生成的数组发生越界,所以对这些数取iLenght的余数,即用%iLenght。
表插入排序
为了减少在排序过程中“移动”记录的操作,必须改变排序过程中采用的存储结构。利用静态链表进行排序,并在排序之后,一次性地调整各个记录之间的位置,即将每个记录都调整到他们应该在的位置上,这样的排序方法称为表插入排序。
基本思想:
使头结点的next域始终指示最小的那个元素,然后依次向下:每一个元素的next域都指示比它稍大的那个元素。最大的元素的next域指示头结点。
下面分三步给出具体的代码:
1、用数组初始化表结构。
2、修改next域形成有序的循环链表。
3、根据next域信息调整表结构中的数组,是数据从小到大排列。
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#define INT_MAX 100
#define number 100
#include&iostream&
#include&time.h&
#include&stdlib.h&
#include&iomanip&
#include&math.h&
//排序后按从小到大输出
typedef struct
//记录其他数据域
STListType SL[number+1];
void ListInsSort(STListType SL[],int n)
//对记录序列SL[1..n]进行表插入排序
SL[0].key = 10000;
SL[0].next=1;
SL[1].next=0;
//初始化,假定第一个记录有序
for (int i=2; i& i++)
//查找插入位置
for (k=SL[0].SL[k].key&SL[i].)
//保证[k].key&=[i].key
j=k, k=SL[k].
//保证是SL[k]里的总是最大的
SL[j].next=i;
//结点i插入在结点j和结点k之间
SL[j]&=SL[i]&=SL[k]
SL[i].next =k;
cout&&"ListInsSort-key:\n";
for(int count=0;count&n;count++)
cout&&setw(4)&&SL[count].
cout&&"ListInsSort-next:\n";
for(int count=0;count&n;count++)
cout&&setw(4)&&SL[count].
void Arrange(STListType SL[],int n)
//根据静态表SL中各节点的指针值调整记录位置,使得SL中的记录关键字非递减有序顺序排列
//p指示第i个记录的当前位置;i指示第i个记录应在的位置;q指示第i+1个记录的当前位置;
int p=SL[0].
//p指示第一个记录的当前位置
for (int i=1;i&n;i++)
//SL[1..i-1]中的记录关键字有序排列,第i个记录在SL中的当前位置应不小于i
//为了保证&i 的元素都是有序的
while(p&i)
//找到第i个记录,并用p指示其在SL中的当前位置
//q指示尚未调整的表尾
temp = SL[p];
SL[p] = SL[i];
//交换记录,使第i个记录到位
SL[i].next=p;
//指向被移走的记录,使得以后可以由while循环找到
//p指示尚未调整的表尾,为找第i+1个记录作准比
cout&&"Arrange-key:\n";
for(int count=0;count&n;count++)
cout&&setw(4)&&SL[count].
cout&&"Arrange-next:\n";
for(int count=0;count&n;count++)
cout&&setw(4)&&SL[count].
int _tmain()
STListType SL[100];
cout&&"ListInsSort.cpp运行结果:\n";
int b[100],i;
srand(time(0));
cout&&"输入待排序元素个数n:";cin&&n;
for(i=1;i&n;i++)
b[i]=rand()%100;
SL[i].key=b[i];
cout&&"排序前数组:\n";
for(i=1;i&n;i++)
cout&&setw(4)&&b[i];
ListInsSort(SL,n);
Arrange(SL,n);
cout&&"排序后数组:\n";
for(i=1;i&n;i++)
cout&&setw(4)&&SL[i].
system("pause");
希尔插入排序
希尔排序又称缩小增量排序,(适用于待排序数列很无序的情况下);基本思想是将待排序的记录划分成几组,从而减少参与直接插入排序的数据量,经过几次分组排序后,记录的排序已经基本有序,在对所有的记录实施最后的直接插入排序。
对于希尔排序,具体步骤可以描述如下:假设待排序的记录为n个,先取整数d&n,例如d=n/2,将所有距离为d的记录构成一组,从而将整个待排序记录分割成为d个子序列(d组),对每个分组进行直接插入排序,然后再缩小间隔d,例如,取d=d/2,重复上述分组,再对每个分组分别进行直接插入排序,直到最后取d=1,即将所有的记录放在一组进行一次直接插入排序,最终将所有记录重新排列成按关键字有序的序列。
Shell提出的选法:d1=n/2 , di+1=di/2
[html][/html] view plaincopy
#include&iostream&
#include&iomanip&
#include&stdlib.h&
#include&time.h&
#define MAXI 11
typedef int KeyT
typedef int ElemT
struct rec
typedef rec sqlist[MAXI];
void shellsort(sqlist b,int n)
int i,j,gap,k;
while(gap&0)
for(i=gap+1;i&n;i++)
while(j&0)
if(b[j].key&b[j+gap].key)
b[j]=b[j+gap];
b[j+gap]=x;
for(k=1;k&n;k++)
cout&&setw(4)&&b[k].
gap=gap/2;
void main()
{cout&&"运行结果:\n";
int i,n=MAXI;
srand(time(0));
for(i=1;i&n;i++)
{a[i].key=rand()%80;
a[i].data=rand()%100;}
cout&&"排序前数组:\n";
for(i=1;i&n;i++)
cout&&setw(4)&&a[i].
cout&&"数组排序过程演示:\n";
shellsort(a,n);
cout&&"排序后数组:\n";
for(i=1;i&n;i++)
cout&&setw(4)&&a[i].
cout&&cin.get();}
1.2 交换排序
交换排序:通过“交换”无序序列中的相邻记录从而得到其中关键字最小或最大的记录,并将他们加入到有序序列中,以增加记录的有序序列长度。
主要思想是在排序过程中,通过比较待排序记录序列中元素的关键字,如果发现次序相反,则将存储位置交换来达到排序目的。
它的基本思想是对所有相邻记录的关键字值进行比较,如果是逆序(a[j]&a[j+1]),则将其交换,最终达到有序。
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#include "stdafx.h"
#include &iostream&
int bubbleSort (int number
for (int i =0;i&=number-1;i++)
for (int j=0;j&=number-i-1;j++)
if (r[j]&r[j+1])
temp=r[j];
r[j]=r[j+1];
int _tmain(int argc, int argv[])
std::cout&&"输入数组大小"&&
std::cin&&
std::cout&&"输入数组内数据"&&
for(int j=0;j&j++)
std::cin&&argv[j];
bubbleSort (argc ,argv);
for(int j=0;j&j++)
std::cout && argv[j] && std::
system("pause");
在排序过程中,比较相邻的元素,如果第前个比后一个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。
for (int i =0;i&=number-1;i++)循环是指(一个元素向上冒泡,直到它找到合适的位置)这个过程的次数,即有多少个元素要进行冒泡操作;冒到上边的是最大的;
for (int j=0;j&=number-i-1;j++)循环是指进行冒泡操作的每一个元素,要经过做少次对比,才能找到合适的位置;
快速排序的基本思想:首先将待排序记录序列中的所有记录作为当前待排序区域,从中任选一个记录(通常可选取第一个记录),以它的关键字作为枢纽,凡其关键字小于枢纽的记录均移到该记录之前,反之,凡关键字大于枢纽的记录均移至该纪录之后,这样一趟排序之后,记录的无序序列R[s..t]将分割成两部分:R[s..i-1]和R[i+1..t],且R[j].key&=R[i].key&=R[k].key
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#include "stdafx.h"
#define number 100
#include&iostream&
#include&time.h&
#include&stdlib.h&
#include&iomanip&
#include&math.h&
//排序后按从小到大输出
typedef struct
//记录其他数据域
RecType S[number+1];
int Partirion(RecType R[],int l,int h)
//交换记录子序列R[1..h]中的记录,使枢纽记录交换到正确的位置,并返回其所在的位置
//用变量i,j记录待排序记录的首尾位置
R[0]=R[i];
//以子表的第一个记录作为枢轴,将其暂存到记录R[0]中
int x=R[i].
//用变量x存放枢纽记录的关键字
while (i&j)
//从表的两端交替地向中间扫描
while (i&j&&R[j].key&=x)
R[i]=R[j];
//将比枢纽小的记录移到低端
while (i&j&&R[i].key&=x)
R[j]=R[i];
//将比枢纽大的记录移到高端
R[i]=R[0];
//枢纽记录到位
//返回枢纽位置
void QuickSort(RecType R[],int s,int t)
//对记录序列R[s..t]进行快速排序
k=Partirion(R,s,t);
QuickSort(R,s,k-1);
QuickSort(R,k+1,t);
cout&&"QuickSort:\n";
for(i=2;i&=t;i++)
cout&&setw(4)&&R[i].
int _tmain()
RecType SL[100];
cout&&"QuickSort.cpp运行结果:\n";
int b[100],i;
srand(time(0));
cout&&"输入待排序元素个数n:";cin&&n;
for(i=1;i&n;i++)
b[i]=rand()%100;
SL[i].key=b[i];
cout&&"排序前数组:\n";
for(i=1;i&n;i++)
cout&&setw(4)&&b[i];
QuickSort(SL,1,n);
cout&&"排序后数组:\n";
for(i=2;i&=n;i++)
cout&&setw(4)&&SL[i].
system("pause");
运行结果:
1.3 选择排序
选择排序:从记录的无序序列中“选择”关键字最小或最大的记录,并将他加入到有序子序列中,以增加记录的有序序列的长度。
基本思想是依次从待排序记录中选择出关键字值最小(或最大)的记录、关键字值次之的记录、...并分别将它们定位到序列左侧(或右侧)的第1位置、第2位置、...,从而使待排序的记录序列成为按关键字值由小到大(或有大到小)排列的有序序列。
直接选择排序
有序序列中所有记录的关键字均小于无序序列中记录的关键字,则第i趟直接选择排序是从无序序列R[i..n]的n-i+1个记录中选择关键字最小的记录加入有序序列的末尾。
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#define number 100
#include&iostream&
#include&time.h&
#include&stdlib.h&
#include&iomanip&
#include&math.h&
//排序后按从小到大输出
typedef struct
//记录其他数据域
RecType S[number+1];
void SelectSort(RecType R[],int n)
//对记录序列R[1..n]进行直接选择排序
for (int i=1;i&n;i++)
for (int j=i+1;j&=n;j++)
if (R[k].key&R[j].key)
temp=R[i];
R[i]=R[k];
int _tmain()
RecType SL[100];
cout&&"SelectSort.cpp运行结果:\n";
int b[100],i;
srand(time(0));
cout&&"输入待排序元素个数n:";
for(i=1;i&n;i++)
b[i]=rand()%100;
SL[i].key=b[i];
cout&&"排序前数组:\n";
for(i=1;i&n;i++)cout&&setw(4)&&b[i];
cout&&SelectSort(SL,n);
cout&&"排序后数组:\n";
for(i=2;i&=n;i++)
cout&&setw(4)&&SL[i].
system("pause");
树形选择排序
基本思想:首先是对n个待排序记录的关键字进行两两比较,从中选出[n/2]个较小者再两两比较,直到选出关键字最小的记录为止,此为一趟排序。
[html][/html] view plaincopy
#include "stdafx.h"
//锦标赛排序法
#include&iostream&
#include&iomanip&
#include&math.h&
#include&stdlib.h&
#include&time.h&
class DataNode //胜者树结点的类定义
//树中的结点号
//参选标志
//锦标赛排序中的调整算法;i是表中当前
//最小元素的下标,即胜者.从它开始向上调整
void UpdataTree(DataNode *tree,int i)
if(i%2==0) //i为偶数,对手为左结点
tree[(i-1)/2]=tree[i-1];//i为奇数,对手为右结点
tree[(i-1)/2]=tree[i+1];
i=(i-1)/2; //i上升到双亲结点位置
{if(i%2==0) j=i-1;//确定i的对手为左结点还是右结点
else j=i+1;
if(!tree[i].active||!tree[j].active)//比赛对手中间有一个空
if(tree[i].active) tree[(i-1)/2]=tree[i];
else tree[(i-1)/2]=tree[j]; //非空者上升到双亲结点
//比赛对手都不为空
if(tree[i].data&tree[j].data) tree[(i-1)/2]=tree[i];
else tree[(i-1)/2]=tree[j];//胜者上升到双亲结点
i=(i-1)/2; //i上升到双亲结点
//建立树的顺序存储数组tree,将数组a[]中的元素复制到胜者树中,
//对它们进行排序,并把结果返回数组中,n是待排序元素个数
void TournmentSort(int a[],int n)
{DataNode * //胜者树结点数组
int m,i,j=0;
for(int k=0;k&n;k++)//计算满足&=n的2的最小次幂的数
m=(int)pow((double) 2,(double)k);
int bottomRowSize=m;
int TreeSize=2*bottomRowSize-1;//计算胜者树的大小:内结点+外结点数
int loadindex=bottomRowSize-1;//外结点开始位置
tree=new DataNode[TreeSize];
//动态分配胜者树结点数组空间
for(i=i&TreeSi++)//复制数组数据到树的外结点中
{tree[i].index=i;//下标
if(j&n) {tree[i].active=1;tree[i].data=a[j++];}//复制数据
else tree[i].active=0; //后面的结点为空的外结点
//进行初始比较寻找最小的项
while(j&2*i)
//处理各对比赛者
{if(!tree[j+1].active||tree[j].data&tree[j+1].data)
tree[(j-1)/2]=tree[j];
else tree[(j-1)/2]=tree[j+1];//胜者送入双亲
j+=2; //下一对参加比较的项
i=(i-1)/2;//i退到双亲,直到i=0为止
for(i=0;i&n-1;i++)//处理其他n-1个元素
{a[i]=tree[0].//当前最小元素送数组a
tree[tree[0].index].active=0;//该元素相应外结点不再比赛
UpdataTree(tree,tree[0].index);//从该处向上修改
a[n-1]=tree[0].
//锦标赛排序法的测试
void main()
{cout&&"JinBiaoSai.cpp运行结果:\n";
int n,b[100],i;
srand(time(0));
cout&&"输入待排序元素个数n:";cin&&n;
for(i=0;i&n;i++) b[i]=rand()%100;
cout&&"排序前数组:\n";
for(i=0;i&n;i++)
cout&&setw(4)&&b[i];
TournmentSort(b,n);
cout&&"排序后数组:\n";
for(i=0;i&n;i++)
cout&&setw(4)&&b[i];
cin.get();cin.get();
树形选择排序:
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#include&iostream&
#include&string.h&
#include&ctype.h&
#include&malloc.h&
#include&limits.h&
#include&stdio.h&
#include&stdlib.h&
#include&io.h&
#include&math.h&
#define MAX_SIZE 20
typedef int KeyT
typedef int InfoT //定义其他数据类型
struct RedType{ KeyT InfoT };
struct SqList
RedType r[MAX_SIZE];
void print(SqList L)
for(i=1;i&=L.i++)
cout&&"("&&L.r[i].key&&","&&L.r[i].otherinfo&&")";
void TreeSort(SqList &L)
int i,j,j1,k,k1,l;
float n=L.
RedType *t;
l=(int)ceil(log(n)/log(2.0))+1; //完全二叉树的层数;ceil取上整,返回比x大的最小整数
k=(int)pow(2.0,l)-1; //k为l层完全二叉树的结点总数
k1=(int)pow(2.0,l-1)-1; //k1为l-1层二叉完全二叉树的结点总数
t=(RedType*)malloc(k*sizeof(RedType)); //二叉树采用顺序存储
for(i=1;i&=n;i++) //将L.r赋值给叶子结点
t[k1+i-1]=L.r[i];
for(i=k1+n;i&k;i++) //给多余的叶子结点的关键字赋无穷大值
t[i].key=INT_MAX;
//给非叶子结点赋值
for(i=j1;i&j;i+=2)
t[i].key&t[i+1].key?(t[(i+1)/2-1]=t[i]):(t[(i+1)/2-1]=t[i+1]);
j=j1; j1=(j1-1)/2;
cout&&"给非叶子结点赋值:"&&
//循环一次,找到最小的
for(i=0;i&n;i++)
L.r[i+1]=t[0]; //键当前最小值赋给L.r[i]
for(j=1;j&l;j++) //沿树根找到结点t[0]在叶子结中的序号j1
t[2*j1+1].key==t[j1].key?(j1=2*j1+1):(j1=2*j1+2);
t[j1].key=INT_MAX;
j1=(j1+1)/2-1; //序号为j1的节点的双亲节点序号
t[2*j1+1].key&=t[2*j1+2].key?(t[j1]=t[2*j1+1]):(t[j1]=t[2*j1+2]);
cout&&"循环排序:"&&
#define N 8
void main()
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
for(i=0;i&N;i++)
l.r[i+1]=d[i];
l.length=N;
cout&&"排序前:"&&
TreeSort(l);
cout&&"排序后:"&&
system("pause");
排序过程中t[k1+i-1]=L.r[i];把L里的数据存储t[k1+i-1]中,为排序需要
k=(int)pow(2.0,l)-1; //k为l层完全二叉树的结点总数
t=(RedType*)malloc(k*sizeof(RedType)); //二叉树采用顺序存储
的存储空间;
运行结果:
其左右子树分别是堆,任何一个结点的值不大(或不小于)左右孩子节点,则最顶端元素必是序列中的最大值或最小值,分别称为小顶堆或大顶堆(小堆或大堆)。堆排序是利用堆的特性对记录序列进行排序的一种排序算法。其基本思想是:先建一个堆,即先选一个关键字最大或最小的记录,然后与序列中的最后一个记录交换,之后将序列中前n-1个记录重新调整为一个堆(调堆的过程称为“筛选”),再将堆顶记录和第n-1个记录交换,如此反复至排序结束。注意:第i 次筛选的前提是从2到n-i 是一个堆,即筛选是对一棵左/右子树均为堆的完全二叉树“调整”根节点使整棵二叉树为堆的过程。
[html][/html] view plaincopy
#include "stdafx.h"
#include &iostream&
void sift(int R[],int i,int m) //R[]要排序的数组;i是指是从堆的第几行的首元素 即i=1 2 4 8 16...;m是指数组中一共多少个元素
//设R[i+1..m]中各元素满足堆的定义,本算法调整R[i]使序列R[i..m]中的元素满足堆的性质
int temp = R [i];
for (int j=2*i;j&=m;j*=2)
//在堆的同一层进行比较,如果右边的大于左边的,则继续向右查找 ,为了保证下面和temp比较的R[j],是这一层上最大的一个
if ((j&m)&&(R[j]&R[j+1]))
if (temp&R[j]) //temp和每一层最大的数比较,如果小于最大的,则把最大的的值赋给R[i]
R[i]=R[j];
//修改i的值,此时R[i]=R[j]的值相同
//最初要调整的节点放在正确的位置
HeapSort( int R[],int n)
int nCreateTime=1;
for (i=n/2;i&0;i--)
sift(R,i,n);
//建堆时i从n/2起递减,是指i从从最底层起依次循环向顶层排序
std::cout&&"建堆"&&nCreateTime&&
for(int j=1;j&9;j++)
std::cout && R[j];
nCreateTime++;
std::cout&&
int nAdjustTime=1;
for (i=n;i&1;i--)
temp=R[i];
R[i]=R[1];
sift(R,1,i-1);
std::cout&&"重新调整"&&nAdjustTime&&
for(int j=1;j&9;j++)
std::cout && R[j];
nAdjustTime++;
std::cout&&
int _tmain(int argc, _TCHAR* argv[])
int data[9]={0,6,9,3,1,5,8,9};
std::cout&&"初始序列"&&
for(int j=1;j&9;j++)
std::cout && data[j];
std::cout&&
HeapSort( data,8);
std::cout&&"生成的有序序列"&&
for(int j=1;j&9;j++)
std::cout && data[j];
std::cout&&
system("pause");
运行结果:
1.4 归并排序
归并排序:通过“归并”两个或两个以上的有序序类,逐步增加有序序列的长度。
归并排序 2-路归并排序
其基本思想是:将一个具有n个待排序记录的序列看成是n个长度为1的有序序列,然后进行两两归并,得到n/2个长度为2的有序序列,在进行两两归并,得到n/4个长度为4的有序序列,如此重复,直至得到一个长度为n的有序序列为止。
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#define number 100
#include&iostream&
#include&time.h&
#include&stdlib.h&
#include&iomanip&
#include&math.h&
//排序后按从小到大输出
typedef struct
//记录其他数据域
RecType S[number+1];
void Merge(RecType R[],RecType R1[],int i,int l,int h)
//将有序的R[i..l]和R[l+1..h]归并为有序的R1[i..h]
for (j=l+1,k=i;i&=l && j&=h;k++)
//将R[]中记录由小到大地并入R1
if (R[i].key&=R[j].key)
R1[k]=R[i++];
R1[k]=R[j++];
R1[k++]=R[i++];
R1[k++]=R[j++];
//将剩余的R[j..h]复制到R1
void Msort(RecType R[],RecType R1[],int s,int t)
//将R[s..t]2-路归并排序为R1[s..t]
RecType R2[100];
R1[s]=R[s];
int m=(s+t)/2;
//将R[s..t]平分为R[s..m]和R[m+1..t]
Msort(R,R2,s,m);
//递归的将R[s..m]归并为有序的R2[s..m]
Msort(R,R2,m+1,t);
//递归的将R[m+1..t]归并为有序的R2[m+1..t]
Merge(R2,R1,s,m,t);
//将R2[s..m]和R2[m+1..t]归并到R1[s..t]
int _tmain()
cout&&"MergingSort.cpp运行结果:\n";
int b[100],i;
RecType R1[100];
srand(time(0));
cout&&"输入待排序元素个数n:";cin&&n;
RecType SL[100];
for(i=1;i&=n;i++)
b[i]=rand()%100;
SL[i].key=b[i];
cout&&"排序前数组:\n";
for(i=1;i&=n;i++)
cout&&setw(4)&&b[i];
Msort(SL,R1,1,n);
cout&&"排序后数组:\n";
for(i=1;i&=n;i++)
cout&&setw(4)&&R1[i].
system("pause");
1.5 分配排序
前面讨论的排序算法都是基于关键字之间的比较,通过比较判断出大小,然后进行调整。而分配排序则不然,它是利用关键字的结构,通过“分配”和“收集”的办法来实现排序。
分配排序:通过对无序序列中的记录进行反复的“分配”和“收集”操作,逐步是无序序列变为有序序列。
分配排序分为:桶排序和基数排序两类。
计数排序的过程类似小学选班干部的过程,如某某人10票,作者9票,那某某人是班长,作者是副班长
大体分两部分,第一部分是拉选票和投票,第二部分是根据你的票数入桶
看下具体的过程,一共需要三个数组,分别是待排数组,票箱数组,和桶数组
var unsorted = new int[] { 6, 2, 4, 1, 5, 9 };
//待排数组
var ballot = new int[unsorted.Length];
//票箱数组
var bucket = new int[unsorted.Length];
最后再看桶数组,先看待排数组和票箱数组
初始状态,迭代变量i = 0时,待排数组[i] = 6,票箱数组[i] = 0,这样通过迭代变量建立了数字与其桶号(即票数)的联系
待排数组[ 6 2 4 1 5 9 ] i = 0时,可以从待排数组中取出6
票箱数组[ 0 0 0 0 0 0 ] 同时可以从票箱数组里取出6的票数0,即桶号
拉选票的过程
首先6出列开始拉选票,6的票箱是0号,6对其它所有数字说,谁比我小或与我相等,就给我投票,不然揍你
于是,2 4 1 5 分别给6投票,放入0号票箱,6得四票
待排数组[ 6 2 4 1 5 9 ]
票箱数组[ 4 0 0 0 0 0 ]
接下来2开始拉选票,对其它人说,谁比我小,谁投我票,不然弄你!于是1投了一票,其他人比2大不搭理,心想你可真二
于是2从1那得到一票
待排数组[ 6 2 4 1 5 9 ]
票箱数组[ 4 1 0 0 0 0 ]
4得到2和1的投票,共计两票
1得到0票,没人投他
5得到2,4,1投的三张票
9是最大,得到所有人(自己除外)的投票,共计5票(数组长度-1票)
投票完毕时的状态是这样
待排数组[ 6 2 4 1 5 9 ]
票箱数组[ 4 1 2 0 3 5 ]
入桶的过程
投票过程结束,每人都拥有自己的票数,桶数组说,看好你自己的票数,进入与你票数相等的桶,GO
6共计5票,进入5号桶
2得1票,进入1号桶,有几票就进几号桶
4两票,进2号桶,5三票进3号桶,9有5票,进5号桶
待排数组[ 6 2 4 1 5 9 ]
票箱数组[ 4 1 2 0 3 5 ]
-----------------------
入桶前 [ 0 1 2 3 4 5 ] //里边的数字表示桶编号
入桶后 [ 1 2 4 5 6 9 ] //1有0票,进的0号桶
排序完毕,顺序输出即可[ 1 2 4 5 6 9]
可以看到,数字越大票数越多,9得到除自己外的所有人的票,5票,票数最多所以9最大,
每个人最多拥有[数组长度减去自己]张票
1票数最少,所以1是最小的
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#include &iostream&
#include &cstdio&
#include &cstdlib&
#include &cmath&
#include &cstring&
#include &stdlib.h&
#include&time.h&
#include&iomanip&
#include&math.h&
void CountingSort(int *A,int *B,int *Order,int N,int K)
int *C=new int[K+1];
memset(C,0,sizeof(int)*(K+1));
for (i=1;i&=N;i++) //把A中的每个元素分配
C[A[i]]++;
for (i=2;i&=K;i++) //统计不大于i的元素的个数
C[i]+=C[i-1];
for (i=N;i&=1;i--)
B[C[A[i]]]=A[i]; //按照统计的位置,将值输出到B中,将顺序输出到Order中
Order[C[A[i]]]=i;
C[A[i]]--;
int main()
int *A,*B,*Order,N=15,K=10,i;
A=new int[N+1];
B=new int[N+1];
Order=new int[N+1];
for (i=1;i&=N;i++) A[i]=rand()%K+1; //生成1..K的随机数
cout&&"Before CS:\n";
for (i=1;i&=N;i++)
cout&&setw(4)&&A[i];
CountingSort(A,B,Order,N,K);
printf("\nAfter CS:\n");
for (i=1;i&=N;i++)
cout&&setw(4)&&B[i];
cout&&"\nOrder:\n";
for (i=1;i&=N;i++)
cout&&setw(4)&&Order[i];
system("pause");
运行结果:
桶排序(Bucket Sort)也称箱排序(Bin Sort),其基本思想是:设置若干个桶,依次扫描待排序记录R[1..n],把关键字等于k的记录全部都装到第k个桶里(分配),按序号依次将各非空的桶首尾连接起来(收集)。桶的个数取决于关键字的取值范围。
桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。
基本思路:
1.设置一个定量的数组当作空桶子。
2.寻访串行,并且把项目一个一个放到对应的桶子去。
3.对每个不是空的桶子进行排序。
4.从不是空的桶子里把项目再放回原来的串行中。
无序数组有个要求,就是成员隶属于固定(有限的)的区间,如范围为[0-9](考试分数为1-100等)
例如待排数字[6 2 4 1 5 9]
准备10个空桶,最大数个空桶
[6 2 4 1 5 9]
[0 0 0 0 0 0 0 0 0 0]
[0 1 2 3 4 5 6 7 8 9]
桶编号(实际不存在)
1,顺序从待排数组中取出数字,首先6被取出,然后把6入6号桶,这个过程类似这样:空桶[ 待排数组[ 0 ] ] = 待排数组[ 0 ]
[6 2 4 1 5 9]
[0 0 0 0 0 0 6 0 0 0]
[0 1 2 3 4 5 6 7 8 9]
桶编号(实际不存在)
2,顺序从待排数组中取出下一个数字,此时2被取出,将其放入2号桶,是几就放几号桶
[6 2 4 1 5 9]
[0 0 2 0 0 0 6 0 0 0]
[0 1 2 3 4 5 6 7 8 9]
桶编号(实际不存在)
3,4,5,6省略,过程一样,全部入桶后变成下边这样
[6 2 4 1 5 9]
[0 1 2 0 4 5 6 0 0 9]
[0 1 2 3 4 5 6 7 8 9]
桶编号(实际不存在)
0表示空桶,跳过,顺序取出即可:1 2 4 5 6 9
[cpp][/cpp] view plaincopy
/* 桶排序实现 */
#include "stdafx.h"
#include &iostream&
#include &cstdio&
#include &cstdlib&
#include &cmath&
#include &cstring&
#include &stdlib.h&
#include&time.h&
#include&iomanip&
#include&math.h&
void BucketSort(int *A,int *B,int N,int K)
int *C=new int[K+1];
int i,j,k;
memset(C,0,sizeof(int)*(K+1));
for (i=1;i&=N;i++) //把A中的每个元素按照值放入桶中
C[A[i]]++;
for (i=j=1;i&=K;i++,j=k) //统计每个桶元素的个数,并输出到B
for (k=j;k&j+C[i];k++)
int main()
int *A,*B,N=100,K=100,i;
A=new int[N+1];
B=new int[N+1];
cout&&"排序前:"&&
for (i=1;i&=N;i++)
A[i]=rand()%K+1; //生成1..K的随机数
cout&&setw(4)&&A[i];
BucketSort(A,B,N,K);
cout&&"排序后:"&&
for (i=1;i&=N;i++)
cout&&setw(4)&&B[i];
system("pause");
运行结果:
这种特殊实现的方式时间复杂度为O(N+K),空间复杂度也为O(N+K),同样要求每个元素都要在K的范围内。更一般的,如果我们的K很大,无法直接开出O(K)的空间该如何呢?
首先定义桶,桶为一个数据容器,每个桶存储一个区间内的数。依然有一个待排序的整数序列A,元素的最小值不小于0,最大值不超过K。假设我们有M个桶,第i个桶Bucket[i]存储iK/M至(i+1)K/M之间的数,有如下桶排序的一般方法:
1.扫描序列A,根据每个元素的值所属的区间,放入指定的桶中(顺序放置)。
2.对每个桶中的元素进行排序,什么排序算法都可以,例如快速排序。
3.依次收集每个桶中的元素,顺序放置到输出序列中。
对该算法简单分析,如果数据是期望平均分布的,则每个桶中的元素平均个数为N/M。如果对每个桶中的元素排序使用的算法是快速排序,每次排序的时间复杂度为O(N/Mlog(N/M))。则总的时间复杂度为O(N)+O(M)O(N/Mlog(N/M)) = O(N+ Nlog(N/M)) = O(N + NlogN - NlogM)。当M接近于N是,桶排序的时间复杂度就可以近似认为是O(N)的。就是桶越多,时间效率就越高,而桶越多,空间却就越大,由此可见时间和空间是一个矛盾的两个方面。
[cpp][/cpp] view plaincopy
/*桶排序实现 */
#include "stdafx.h"
#include &iostream&
#include &cstdio&
#include &cstdlib&
#include &cmath&
#include &cstring&
#include &stdlib.h&
#include&time.h&
#include&iomanip&
#include&math.h&
struct linklist
linklist *
linklist(int v,linklist *n):value(v),next(n){}
~linklist() {if (next)}
inline int cmp(const void *a,const void *b)
return *(int *)a-*(int *)b;
/* 为了方便,我把A中元素加入桶中时是倒序放入的,而收集取出时也是倒序放入序列的,所以不违背稳定排序。 */
void BucketSort(int *A,int *B,int N,int K)
linklist *Bucket[101],*p;
int i,j,k,M; M=K/100;
memset(Bucket,0,sizeof(Bucket));
for (i=1;i&=N;i++)
//把A中的每个元素按照的范围值放入对应桶中
Bucket[k]=new linklist(A[i],Bucket[k]);
for (k=j=0;k&=100;k++)
for (p=Bucket[k];p;p=p-&next)
B[++j]=p-&
//把桶中每个元素取出,排序并加入B
delete Bucket[k];
qsort(B+i+1,j-i,sizeof(B[0]),cmp);
int main()
int *A,*B,N=100,K=100,i;
A=new int[N+1];
B=new int[N+1];
for (i=1;i&=N;i++)
A[i]=rand()%K+1; //生成1..K的随机数
cout&&setw(4)&&A[i];
BucketSort(A,B,N,K);
cout&&"排序后:"&&
for (i=1;i&=N;i++)
cout&&setw(4)&&B[i];
system("pause");
运行结果:
基数排序(Radix Sort)是对桶排序的改进和推广。
基本思想:将一个关键字分解成多个“关键字”,再利用多关键字排序的思想对记录序列进行排序。基数排序就是借助“多关键字排序”的思想来实现“单关键字排序”的算法。
假设有n个记录的待排序序列{R1,R2,...,Rn},每个记录Ri中含有d个关键字,则称上述记录序列对关键字有序,是指对于序列中的任意两个记录Ri和Rj(1&=i&j&=n)都满足下列(词典)有序关系;
具体做法为:
(1)待排序的记录以指针相链,构成一个链表。
(2)“分配”时,按当前“关键字位”的取值,将记录分配到不同的“链队列”中,每个队列中记录的“关键字位”相同。
(3)“收集”时,按当前关键字取值从小到大将各队首尾相链接成一个链表;对每个关键字位均重复2)和3)两步。如下所示:
p-&369-&367-&167-&239-&237-&138-&230-&139
第一次分配得到:
B[0].f-&230&-B[0].e
B[7].f-&367-&167-&237&-B[7].e
B[8].f-&138&-B[8].e
B[9].f-&369-&239-&139&-B[9].e
第一次收集得到:
p-&230-&367-&167-&237-&138-&369-&239-&139
第二次分配得到:
B[3].f-&230-&237-&138-&239-&139&-B[3].e
B[6].f-&367-&167-&369&-B[6].e
第二次收集得到:
p-&230-&237-&138-&239-&139-&367-&167-&369
第三次分配得到:
B[1].f-&138-&139-&167&-B[1].e
B[2].f-&230-&237-&239&=B[2].e
B[3].f-&367-&369&-B[3].e
第三次收集之后便得到记录的有序序列:
p-&138-&139-&167-&230-&237-&239-&367-&369
[cpp][/cpp] view plaincopy
#include "stdafx.h"
#include &iostream&
#include&stdlib.h&
#include&iomanip&
#include&math.h&
int maxbit(int data[],int n) //辅助函数,求数据的最大位数
int d = 1; //保存最大的位数
int p =10;
for(int i = 0;i & ++i)
while(data[i] &= p)
void radixsort(int data[],int n) //基数排序
int d = maxbit(data,n);
int * tmp = new int[n];
int * count = new int[10]; //计数器
int i,j,k;
int radix = 1;
for(i = 1; i&=i++) //进行d次排序
for(j = 0;j & 10;j++)
count[j] = 0; //每次分配前清空计数器
for(j = 0;j & j++)
k = (data[j]/radix)%10; //统计每个桶中的记录数
count[k]++;
for(j = 1;j & 10;j++)
count[j] = count[j-1] + count[j]; //将tmp中的位置依次分配给每个桶
for(j = n-1;j &= 0;j--) //将所有桶中记录依次收集到tmp中
k = (data[j]/radix)%10;
tmp[count[k]-1] = data[j];
count[k]--;
for(j = 0;j &j++) //将临时数组的内容复制到data中
data[j] = tmp[j];
radix = radix*10;
int _tmain(int argc, _TCHAR* argv[])
int data[10]={267,6,9,679,0,999,99,9,22,11};
std::cout&&"初始序列"&&
for(int j=0;j&10;j++)
std::cout &&setw(4)&& data[j];
std::cout&&
radixsort( data,10);
std::cout&&"生成的有序序列"&&
for(int j=0;j&10;j++)
std::cout && setw(4)&&data[j];
std::cout&&
system("pause");
system(&span class="string"&&span style="color:#0000"&"pause"&/span&&/span&&span&);
运行结果:
各种排序算法比较
大部分已排序时较好
B是真数(0-9),
R是基数(个十百)
O(ns) 1&s&2
s是所选分组
2 外部排序
外部排序:若参加排序的记录数量很大,整个排序过程不能一次在内存中完成,则称此类排序问题为外部排序;
本文固定链接:
[上一篇][下一篇]
最新文章随机精彩热门排行
精彩内容获取超时,请稍候...
日志总数:3902 篇
评论总数:8096 评
标签数量:4473 个
链接总数:4 条
建站日期:
运行天数:1188 天

我要回帖

更多关于 快速排序 c语言 的文章

 

随机推荐