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


關於快速排序這個算法,看了很多次了,但是經常自己寫的時候就會出現一些小錯誤,算法的思想還是很清楚的,就是寫不對。記錄下來已備看。

        前兩天的時候做算法課的實驗,實驗的題目是,利用分治的策略找數組中的最大值和最小值,

實驗中提供的一些資料

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;
}




運行的效果截圖是:



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