算法之分治思想和快速排序


关于快速排序这个算法,看了很多次了,但是经常自己写的时候就会出现一些小错误,算法的思想还是很清楚的,就是写不对。记录下来已备看。

        前两天的时候做算法课的实验,实验的题目是,利用分治的策略找数组中的最大值和最小值,

实验中提供的一些资料

1.如何生成随机数的数组:


2、算法分析:



然后根据这些资料写出程序,这里用的是C语言

因为之前看数据结构的时候就有看过这一块儿的知识,所以实现所要求的不是很难,最后我写出来的代码如下

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAXSIZE 100

void findMM(int a[],int *max,int *min,int low,int high);//寻找最大最小值的声明

void findMM(int a[],int *max,int *min,int low,int high)
{	
	if(low >= high)
	{	
		if(*max < a[low])	*max = a[low];//if(*max < a[low])<span style="white-space:pre">	</span>max = a + low;这种写法是错误的
		if(*min > a[low])	*min = a[low];//<span style="font-family: Arial, Helvetica, sans-serif;">if(*max < a[low])</span><span style="font-family: Arial, Helvetica, sans-serif;">	</span>       <span style="font-family: Arial, Helvetica, sans-serif;">min = a + low;</span>

		return;
	}
	findMM(a,max,min,low,low+(high-low)/2);
	findMM(a,max,min,low+(high-low)/2+1,high);
}
int main(int argc, char const *argv[])
{
	int i = 0,max,min;
	int Data[MAXSIZE];
    srand((unsigned)time(NULL));//生成种子
	for(i=0;i<MAXSIZE;i++)
	{
		Data[i] = rand() %100 +1;//生成1-100之间的随机数
	}
	

	for(i=0;i<MAXSIZE;i++)
	{
		if(i!=0 && i%5 == 0)
		{
			printf("\n");
		}
		printf("%4d",Data[i]);
	}
	findMM(Data,&max,&min,0,MAXSIZE-1);

	printf("\n最大值是:%d\n最小值是:%d\n",max,min);
	return 0;
}

在实验的时候一到一个问题,就是在交换的时候注释中写的那种写法,排错排了很久,调试后才发现,Data数却没有改变,那种修改地址的写法是错误的。

最后,实验的效果很明显,是正确的,但是呢看起来不是很方便,所以我决定增加一个快速排序的函数,将数组拍好序之后就很容易看得出最小值和最大值,以方便验证,但在写的时候就出现了很多的问题,最后参考了百度百科里面快速排序算法,里面讲的的确特别的详细,还有动态的演示图片,有需要的话可以查看百度一下快速排序算法。最终我的成型的代码是这样的:


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAXSIZE 100

void quicksort(int *a,int left,int right);//快速排序的声明
void findMM(int a[],int *max,int *min,int low,int high);//寻找最大最小值的声明

void findMM(int a[],int *max,int *min,int low,int high)
{	
	if(low >= high)
	{	
		if(*max < a[low])	*max = a[low];
		if(*min > a[low])	*min = a[low];
		return;
	}
	findMM(a,max,min,low,low+(high-low)/2);
	findMM(a,max,min,low+(high-low)/2+1,high);
}

void quicksort(int *a,int left,int right)//从小到大排列
{
	int i = left,j=right,temp=a[left];//定义一个临时变量来存储当前的轴值
	if(left>=right) return; //如果左边的数大于右边就带表排完一组了
	while(i<j)
	{
		while(i<j && temp<=a[j]) j--;//控制在组内寻找一遍,右边的应该比轴值大,如果找到
		//一个小于轴值的就往前交换
		a[i] = a[j];
		while(i<j&& temp>=a[i]) i++;//从左向右寻找比轴值大的数
		a[j] = a[i];
	}
	a[i] = temp;//将暂存的轴值存放到相应的位置上
	quicksort(a,left,i-1);//递归遍历左边
	quicksort(a,i+1,right);	//递归遍历右边
}

int main(int argc, char const *argv[])
{
	int i = 0,max,min;
	int Data[MAXSIZE];
    srand((unsigned)time(NULL));//生成种子
	for(i=0;i<MAXSIZE;i++)
	{
		Data[i] = rand() %100 +1;//生成1-100之间的随机数
	}
	

	for(i=0;i<MAXSIZE;i++)
	{
		if(i!=0 && i%5 == 0)
		{
			printf("\n");
		}
		printf("%4d",Data[i]);
	}

	printf("\n\n+++++++++++++++++++++++++\n\n");
	//先排序后输出方便看出最大值和最小值
	quicksort(Data,0,MAXSIZE-1);
	for(i=0;i<MAXSIZE;i++)
	{
		if(i!=0 && i%5 == 0)
		{
			printf("\n");
		}
		printf("%4d",Data[i]);
	}

	max = min = Data[0];
	findMM(Data,&max,&min,0,MAXSIZE-1);

	printf("\n最大值是:%d\n最小值是:%d\n",max,min);
	return 0;
}




运行的效果截图是:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章