快速排序法

本文详细介绍了快速排序算法的原理及其实现过程。通过一个具体的例子,展示了如何选取中间元素,并逐步分解数组,最终实现排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*--------------------------------------------------------------------------------------------
                                             快速排序法
排序原理:找出一个中间元素,让左边的值均小于它,右边的值均大于它.然
                 后再分别对左边和右边进行同样处理的方式排序.第一次用到的
                 中间元素可以取中间元素也可以取第一个元素,这里取第一个元
                 素,所以先找右边第一个小于它的值,将该值赋给第一个元素,还
                 是用一个短小的例子说明吧!(最基本的原理应该是用的分治法.)
                 下面拿10个元素为例进行说明:
                 ---------------------------------------------------------
                 23   45   34   5   765   74   657   88   99   87
                 ---------------------------------------------------------
                 第一次:  left=0;
                                right=9;
                 调用Find_Mind(ar,left,right)分析如下:
                 temp=ar[left]=ar[0]=23;
                1.在left右边寻找第一个小于23的元素(5),并把它赋给
                    ar[left],此时排序结果:
                  --------------------------------------------------------
                  5   45   34   5   765   74   657   88   99   87
                  ---------------------------------------------------------
                 此时:left=0+1=1;(赋值语句结束后需要将left右移一位)
                          right=3;
                 2.在right左边从left(1)开始寻找第一个大于5的元
                     素(45),然后将其赋给ar[right],此时排序结果:
                 ---------------------------------------------------------
                 5   45   34   45   765   74   657   88   99   87
                 ---------------------------------------------------------
               此时:left=1;
                        right=1;(赋值语句结束后需要将right左移一位)


第二次:是在Quick_Sort(ar,left,mid-1);这步的递归调用规程中,但是需
             要注意,这里的left是主函数在调用Quick_Sort(ar,0,n-1)是传递
             来的实参0,注意区这里的left和Find_Mid()中的left,实在不行可
             用其他字母代替Find_Mid()中的left和right便可.但是这时传递的
             left和min-1都是0,所以被if(left<right)语句挡住不能进入{}内
             部求mid了,这时便要将控制权返回给调用Quick_Sort(ar,left,mid-1);
             函数的下一个可执行语句,就是Quick_Sort(ar,mid+1,right);将上
            次求的的mid和主函数参来的right带入为Quick_Sort(ar,2,9);这时
            满足if(left<right),所以会调用Find_Mid()函数,继续求中间值.
            步骤同第一次相同,具体参数如下:
            mid=1;
            right=9;
            调用Quick_Sort(ar,mid+1,right);


中间的n次.................................


            直到调用的Quick_Sort()中的两个参数相差为1时,便得出结果.


            对以上的数组,输出结果应为:
            1 : left = 1  right = 1
            2 : left = 2  right = 2
            3 : left = 3  right = 3
            4 : left = 9  right = 9
            5 : left = 5  right = 5
            6 : left = 8  right = 8
            7 : left = 7  right = 7
           ar[10] = 5  23  34  45  74  87  88  99  657  765
--------------------------------------------------------------------------------------------*/
#include<stdio.h>
int Find_Mid(int ar[],int left,int right);
void Quick_Sort(int ar[],int lrft,int right);
int main(void)
{
	int i,n;
	
	puts("Input the number of elements to the array:");
		scanf("%d",&n);
	int ar[n];                      //变长数组,编译器应支持C99标准
	printf("Input %d elements of the array:\n",n);
	for(i=0;i<n;i++)                //读取数组元素
		scanf("%d",&ar[i]);
	Quick_Sort(ar,0,n-1);               
	printf("ar[%d] = ",n);
	for(i=0;i<n;i++)                //逐个打印数组元素             
		printf("%d  ",ar[i]);   
	putchar('\n');
	return 0;
}
void Quick_Sort(int ar[],int left,int right)
{
	int mid;
	if(left<right)
	{
		mid=Find_Mid(ar,left,right);     //求中间位置
		Quick_Sort(ar,left,mid-1);       //递归调用,对左边进行相同方式的分发
		Quick_Sort(ar,mid+1,right);      //递归调用,对右边进行相同方式的分发
	}
}
int Find_Mid(int ar[],int left,int right)
{
	static int ct;                                //声明一个静态变量用于计算调用Find_Mid()的次数
	int temp;
	if(left<right)
	{
		temp=ar[left];
		while(left<right)
		{
			while(left<right && ar[right]>=temp)   //右侧寻找第一个小于temp的元素
				right--;
			if(left<right)                         //left<right说明找到了,所以将找到的元素赋值给s[left]
				ar[left++]=ar[right];

			while(left<right && ar[left]<temp)     //左侧寻找第一个大于等于temp的元素
				left++;
			if(left<right)                         //left>right说明找到了,所以将找到的元素赋值给s[left]
				ar[right--]=ar[left];
		}
		ct++;
	}
	printf("%d : left = %d   right = %d\n",ct,left,right);//输出每次调用后的left和right,应该相等
	ar[left]=temp;                                        //将比较的元素赋给找到的位置
	return left;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值