常用排序算法:一

一、交换排序

1.冒泡排序:

冒泡排序的思想就是每次对指定区间进行遍历的同时,比较相邻元素,如果相邻元素为逆序则交换相邻元素,如果位正序则不作任何操作,这样如果按从小到大的顺序遍历数组下标,那么一次遍历之后,整个序列中的最小数或者最大数就“下沉”到数组底部了,反之,如果从大到小遍历数组小标,那么一次遍历之后,整个序列中的最小数或者最大数就“上浮”到数组顶部了。

 

一般情况下,给定序列区间都是0-n-i)。(当然i-n应该也是可以的,这种情况一般不会出现,因为我们遍历数组的时候,经常是从小标从小到大的顺序进行的,所以只能把重要的元素下沉,如果我们从大到小遍历数组下标,是可以达到将重要元素上浮的目的的。这个时候,给定序列就是i-n了。)

 

冒泡排序1,数组下标遍历方式从大到小,给定冒泡区间0-n-i

void bubleSort( int *pArray,const int n, const int type)
{
	int i = 0;
	int j = 0;
	for (i=1; i<n-1; i++)
	{
		for(j=0; j<n-i; j++)
		{
			if ( type )
			{
				if( pArray[j] < pArray[j+1] )
				mSwap(pArray+j, pArray+j+1);
			}
			else
			{
				if( pArray[j] > pArray[j+1] )
				mSwap(pArray+j, pArray+j+1);
			}
		}
	}
}

冒泡排序 2 ,数组小标遍历方式从大到小,给定冒泡区间( n-1 -i

void bubleSort1( int *pArray, const int n, const int type )
{
	int i = 0;
	int j = 0;
	for ( i=0; i<n; i++)
	{
		for ( j=n-1; j>i; j--)
		{
			if ( type )
			{
				if( pArray[j] < pArray[j-1] )
				mSwap(pArray+j, pArray+j-1);
			}
			else
			{
				if( pArray[j] > pArray[j-1] )
				mSwap(pArray+j, pArray+j-1);
			}
		}
	}
}

2.快速排序


快排的基本思路是分治,将待排序列划分为各个小的序列,而对每一个序列做的操作是选中一个轴(实际上就是一个数组中某个元素),通过某种方法使得在这个序列中轴的两边分别是比轴大的数和比轴小的数,当排序序列分到足够小时,整个序列就有序了。

void QuickSort (int *pArray, const int left, const int right, const int type)
{
	if( left < right )
	{
		//先划分
		int pivotpos = parttition1( pArray, left, right, type);
		//左部递归(递归的时候,及得要把轴从队列中拿出来)
		QuickSort( pArray, left, pivotpos-1, type);
		//右部递归(递归的时候,及得要把轴从队列中拿出来)
		QuickSort( pArray, pivotpos+1, right, type);
	}
}

对于划分:划分的最终目的是要让序列中的轴两边的元素处于一边是比轴大,一边比轴小的状态,而实现这个目的下面介绍两种方法:

方法1

//这里划分的思路是先把轴的值保存起来,

//然后用一个指针指向轴的位置(即队首部),

//接着依次从序列首部向尾部遍历,查找是否有比轴大(或者比轴小)的元素,

//一旦有,将它和该指针指向的元素交换,然后再把该指针向队尾移动一个单位

//这样做的目的是保证轴指针左边都是比轴大(或者比轴小)的元素,

//遍历完之后,再将轴指针指向的元素和真正的轴交换

int parttition( int *pArray, const int low, const int high, const int type)
{
	int pivotpos = low;      //轴位置
	int pivot = pArray[low]; //选中排序序列中第一个位置为轴
	int i = low + 1;
	for( i=low+1; i<=high; i++)
	{
		if( type ) //从小到大
		{
			//保证pivotpos指针左边都是比pivot小的值 
			if( pArray[i] < pivot && ++pivotpos != i )
			{
				mSwap( pArray+pivotpos, pArray+i);
			}
		}
		else //从达到小
		{
			//保证pivotpos指针左边都是比pivot大的值
			if( pArray[i] > pivot && ++pivotpos != i )
			{
				mSwap( pArray+pivotpos, pArray+i);
			}
		}	
	}
	//将正真的轴,和轴指针指向的元素做交换
	mSwap( pArray+low, pArray+pivotpos);
	return pivotpos;
}

方法2

//同样首先保存轴的值,这里取队首第一个元素,然后从序列的两端(low和high)向中间遍历,

//首先high向队首移动,一旦找到比轴小的(或大的)元素,将其放到low的位置,

//然后low向队尾移动,一旦找到比轴大的(或者小的)元素,将其放到high的位置,

//这样直到low和high相遇,并且在相遇的时候,low和high就把这个序列分成一边是比轴

//大的元素,一边是比轴小的元素,最后将轴放到low(或high)的位置。

int parttition1( int *pArray, const int low, const int high, const int type)
{
	int tlow = low;
	int thigh = high;
	int pivot = pArray[tlow];
	while( tlow < thigh )
	{
		if( type ) //从小到大排序
		{
			//high指针向队尾移动
			while(tlow < thigh && pArray[thigh] > pivot )
			{
				thigh--;
			}
			//找到比pivot小的值,放到low处
			pArray[tlow] = pArray[thigh];
			//low指针向队首移动
			while( tlow < thigh && pArray[tlow] < pivot )
			{
				tlow++;
			}
			//找到比pivot大的,放到high处
			pArray[thigh] = pArray[tlow];
		}
		else //从大到小排序
		{
			//high指针向队尾移动
			while(tlow < thigh && pArray[thigh] < pivot )
			{
				thigh--;
			}
			//找到比pivot大的值,放到low处
			pArray[tlow] = pArray[thigh];
			//low指针向队首移动
			while( tlow < thigh && pArray[tlow] > pivot )
			{
				tlow++;
			}
			//找到比pivot小的,放到high处
			pArray[thigh] = pArray[tlow];
		}
	}
	//当low和high指针相遇,把轴插入
	pArray[tlow] = pivot;
	return tlow;
}

我个人比较喜欢第一种方法,当然第二种方法实质上也是交换元素的位置,只是一开始留出一个空位,然后每次都把特定元素移到该空位上来,直到最后用轴填充该空位。


二、选择排序

1.直接选择排序:

选择排序的思路跟冒泡排序很相似,都是每次对一个序列进行遍历,在遍历完之后缩短该序列的长度(通常是将原序列减去1个元素),然后作为一个新的序列输入进行下一次遍历,直到这个序列中只剩下一个元素为止。选择排序跟冒泡排序的不同之处在于,冒泡排序在遍历过程中是比较两个相邻元素,操作(交换)的时候也是对两个相邻元素进行的;而选择排序遍历的时候,所做的操作是选出当前序列中的最大值,或者最小值,然后把这个最值放在序列的最前端,或者是最后端,下次遍历的时候将把这个选中的值从原队列中剔除,直到队列中只剩下一个元素为止。

 

遍历序列0-n-i),每次把选中的最值,放到队列尾部:

void selectSort( int *pArray, const int n, const int type)
{
	int i = 0;
	int j = 0;
	int mIndex = 0;
	int m = 0;
	if ( !type ) //如果是求最小值
	{
		m = AMAX; 
	}
	for (i=0; i<n-1; i++)
	{
		for (j=0; j<n-i; j++)//遍历序列0-(n-i)
		{
			if ( type )  //求最大值
			{
				if ( m < pArray[j])
				{
					m = pArray[j];
					mIndex = j;//找到最大值的下标
				}
			}
			else //求最小值
			{
				if ( m > pArray[j])
				{
					m = pArray[j];
					mIndex = j;
				}
			}
		}
		mSwap(pArray+n-1-i, pArray+mIndex);  //把最大值放到序列尾部
		//重置最值(m)
		if ( type ) //求最大值
		{
			m = 0;
		}
		else  //求最小值
		{
			m = AMAX;
		}
	}
}

遍历序列i-n-1),每次把选中的最值,放到队列首部:

void selectSort1( int *pArray, const int n, const type )
{
	int i = 0;
	int j = 0;
	int mIndex = 0;
	int m = 0;
	if ( !type ) //如果是求最小值
	{
		m = AMAX; 
	}
	for (i=0; i<n-1; i++)
	{
		for (j=i; j<n; j++)//遍历序列i-(n-1)
		{
			if ( type )  //求最大值
			{
				if ( m < pArray[j])
				{
					m = pArray[j];
					mIndex = j;//找到最大值的下标
				}
			}
			else //求最小值
			{
				if ( m > pArray[j])
				{
					m = pArray[j];
					mIndex = j;
				}
			}
		}
		mSwap(pArray+i, pArray+mIndex);  //把最大值放到序列首部
		//重置最值(m)
		if ( type ) //求最大值
		{
			m = 0;
		}
		else  //求最小值
		{
			m = AMAX;
		}
	}
}

不得不说的是,写到这里 出现了一个挺有意思的小插曲:

void mSwap( int *i, int *j)
{
	*i = *i + *j;
	*j = *i - *j;
	*i = *i - *j;
}

上面是一个交换两个变量的函数,在这个排序程序中咋一看似乎没什么问题,只是没有用常规的方法(用第三个临时变量实现),而是通过传入的这两个变量做加法解决的。但问题往往就出在这种地方。

下面是发现bug后更进的代码:

void mSwap( int *i, int *j)
{
	if(i != j)     
	{
		*i = *i + *j;
		*j = *i - *j;
		*i = *i - *j;
	}
}

大家现在应该看出来了。在排序的时候,我们不确定需要交换位置的两个元素在数组中的位置,也就是说两个元素在数组中的位置处同一个位置(即这两个元素是同一个元素)的情况也是可能发生的。而一旦发生这样的情况,上面第一个函数就会出问题了,因为传入的地址,是同一个地址,*i*j的值不管在什么情况下都是相同的。看看代码:

*I += *j;   //现在改地址空间中的值是原来的两倍
*j = *I - *j; //由于两次从地址中取出的值是相同的,所以计算结果为0。 
*I = *I - *j; //很显然,现在的结果就是0-0了,原来空间中的数成功的被置0,出现bug了。所以用第一个swap函数的时候,排序后的结果有一定概率地出现一些元素的值被置0的情况。

如果是常规的方法呢?再看看代码:

Temp = *I ;  //将该数倒入空杯子
*I = *j;     //覆盖i的值,实际上是自己赋值给自己
*j = Temp;   //再从临时变量中取值,由于临时变量只是自己的一个copy,所以也不出现任何问题,也就是说上面的swap函数用常规方法实现,一点问题也不会出现。也许,常用的方法之所以常用,总该是有一定的道理吧。

这里涉及 swap ,除了上面两种方法之外,用位操作符也可以解决,只是也会出现被置 0 的情况:

void mSwap( int *i, int *j)
{
	if( i != j)
	{
		*i ^= *j;
		*j ^= *i;
		*i ^= *j;
	}
}

三、插入排序

1.直接插入排序:

打过扑克牌的人,都会这个排序方法。插入排序有一个前提:已排序列是排好序的或者是空的。插入排序的基

本思路是,从待排序列中找出一个待排元素i,这时已排序列中会增加一个空位置,用来移动元素。然后与已排序列中的各个元素进行比较,如果不符合比较条件,将已排序列中的那个元素移动一个位置,如果符合比较条件就将i插入空位置中,直到待排序列中的所有元素都插入已排序列中。


void insertSort( int *pArray, const int n, const int type)
{
	int temp;
	int i = 0;
	int j = 0;
	for( i=1; i<n; i++)
	{
		//这里temp就是从待排序列中取出的一个元素
		//而初始化时待排队列是数组元素1-(n-1)位置上n-1个元素
		//已排队列是数组中头部第一个元素
		temp = pArray[i];
		j = i;
	
		if( type )//从小到大排列
		{
			//如果满足左大右小,所有数组中的元素从左向右移动
			//如果temp最小,它将被插到数组头部
			while( j>0 && pArray[j-1] > temp )
			{
				pArray[j] = pArray[j-1]; 
				j--;
			}
		}
		else //从大到小排列
		{
			//如果temp最小,它将被插到数组头部
			while( j>0 && pArray[j-1] < temp )
			{
				pArray[j] = pArray[j-1]; 
				j--;
			}
		}
		//如果移动到数组头部,或者找到合适的位置,将元素插入
		pArray[j] = temp;
	}
}

2.二分插入排序

在直接插入排序中,将一个元素插入到已排好序的队列中是直接从一头到另一头的线性查找,效率不高。而由于已排序列是已经排好序的,所以在查找插入位置的时候,可以利用二分查找来提高效率。

void binaryInsertSort( int *pArray, const int n, const int type)
{
	int temp;
	int i = 0;
	int j = 0;
	int left = 0;
	int right = 0;
	int middle = 0;
	for( i=1; i<n; i++)
	{
		temp = pArray[i];
		//二分查找,寻找插入位置
		left = 0;
		right = i - 1;
		while( left <= right )
		{
			middle = ( left + right ) / 2;
			if( type ) //从大到小
			{
				if( temp < pArray[middle] )
				{
					left = middle + 1;
				}
				else
				{
					right = middle - 1;
				}
			}
			else //从小到大
			{
				if( temp > pArray[middle] )
				{
					left = middle + 1;
				}
				else
				{
					right = middle - 1;
				}
			}
			
		}
		//成块的移出插入位置
		for( j=i-1; j>=left; j--)
		{
			pArray[j+1] = pArray[j];
		}
		//插入元素
		pArray[left] = temp; 
	}
}

3.Shell排序

不管是在直接插入排序中,还是在二分插入排序中,最耗时间的是查找插入位置的过程。而对于基本有序的序列来说,寻找插入位置的过程可以省去很多时间。也就是说在排序序列具有一定有序性的情况下,插入排序的效率可以很大的提高。Shell排序的思路就是逐渐提高排序序列的有序性,直到整个序列式完全有序的。

具体的做法是选取一个gap值,用这个值每次选取待排队列中的某些元素,组成一个子序列,然后对子序列进行直接插入排序,接着缩小gap的值,再选取子序列再排序,直到最后gap==1(此时待排序列的有序程度已经很高了),再进行一次直接插入排序。

Shell排序中gap的取值方法有很多种,孰优孰劣,众说纷纭。最初提出来的时候gap=n/2, gap/=2;后来提出取:gap = gap / 3 + 1;还有些人提出取奇数,也有人提出取的gap值互为素数较好。

Shell排序:

void shellSort( int *pArray, const int n, const int type)
{
	int gap = n/2;  //首次选取gap值为n/2
	int i = 0;
	int j = 0;
	int temp = 0;
	while( gap )
	{
		for( i=gap; i<n; i+=gap)
		{
			temp = pArray[i];
			j = i;
			if( type ) //从大到小
			{
				while( j>0 && temp > pArray[j-gap])
				{
					pArray[j] = pArray[j-gap];
					j = j - gap;
				}
			}
			else  //从小到大
			{
				while( j>0 && temp < pArray[j-gap])
				{
					pArray[j] = pArray[j-gap];
					j = j - gap;
				}
			}	
			pArray[j] = temp;
		}
		gap /= 2;  //每次gap值折半
	}
}

再给出一个上面排序算法的测试程序,暂时就到这儿吧。

测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define AMAX 10000   //数组元素中的最大值
#define LEN 100     //数组长度

/*
* 打印出数组中的所有元素
*/
void printArray( int *pArray, const int n)
{
	int i = 0;
	for (i=0; i<n; i++)
	{
		printf("%d ", pArray[i]);
	}
	printf("\n\n");
}

/*
* 寻找数组中的最大值
*/
void findMaxAndMin( int *pArray, const int n)
{
 	int max = 0;
	int min = AMAX;
	int i = 0;
	for (i=0; i<n; i++)
	{
		if ( max < pArray[i])
		{
			max = pArray[i];
		}
		if ( min > pArray[i])
		{
			min = pArray[i];
		}
	}
	printf("Max: %d, Min: %d\n", max, min);
}

/*
* 交换两个元素
*/
void mSwap( int *i, int *j)
{
	if(i != j)     
		//一个很有意思的bug,这里,如果i和j这两个地址
		//是同一个地址的话,在swap之后,地址中的数变为0,
		//表面上,我们要交换这个数组中的两个元素,但由于某种原因这两个元素
		//在数组中处于同一位置(也就是同一个元素),交换之后的结果(地址中的数变为0)并不是我们想要的(地址中的数不变)。
		//如果这里的swap用第三个变量来实现的话,是不会出现这种情况的。
	{
		*i = *i + *j;
		*j = *i - *j;
		*i = *i - *j;
	}
}

/*
* 冒泡排序
*/
void bubleSort1( int *pArray, const int n, const int type )
{
	int i = 0;
	int j = 0;
	for ( i=0; i<n; i++)
	{
		for ( j=n-1; j>i; j--)
		{
			if ( type )
			{
				if( pArray[j] < pArray[j-1] )
				mSwap(pArray+j, pArray+j-1);
			}
			else
			{
				if( pArray[j] > pArray[j-1] )
				mSwap(pArray+j, pArray+j-1);
			}
		}
	}
}

/*
* 冒泡排序
*/
void bubleSort( int *pArray,const int n, const int type)
{
	int i = 0;
	int j = 0;
	for (i=1; i<n-1; i++)
	{
		for(j=0; j<n-i; j++)
		{
			if ( type )
			{
				if( pArray[j] < pArray[j+1] )
				mSwap(pArray+j, pArray+j+1);
			}
			else
			{
				if( pArray[j] > pArray[j+1] )
				mSwap(pArray+j, pArray+j+1);
			}
		}
	}
}

/*
* 选择排序
*/
void selectSort( int *pArray, const int n, const int type)
{
	int i = 0;
	int j = 0;
	int mIndex = 0;
	int m = 0;
	if ( !type ) //如果是求最小值
	{
		m = AMAX; 
	}
	for (i=0; i<n-1; i++)
	{
		for (j=0; j<n-i; j++)//遍历序列0-(n-i)
		{
			if ( type )  //求最大值
			{
				if ( m < pArray[j])
				{
					m = pArray[j];
					mIndex = j;//找到最大值的下标
				}
			}
			else //求最小值
			{
				if ( m > pArray[j])
				{
					m = pArray[j];
					mIndex = j;
				}
			}
		}
		mSwap(pArray+n-1-i, pArray+mIndex);  //把最大值放到序列尾部
		//重置最值(m)
		if ( type ) //求最大值
		{
			m = 0;
		}
		else  //求最小值
		{
			m = AMAX;
		}
	}
}

/*
* 选择排序
*/
void selectSort1( int *pArray, const int n, const type )
{
	int i = 0;
	int j = 0;
	int mIndex = 0;
	int m = 0;
	if ( !type ) //如果是求最小值
	{
		m = AMAX; 
	}
	for (i=0; i<n-1; i++)
	{
		for (j=i; j<n; j++)//遍历序列i-(n-1)
		{
			if ( type )  //求最大值
			{
				if ( m < pArray[j])
				{
					m = pArray[j];
					mIndex = j;//找到最大值的下标
				}
			}
			else //求最小值
			{
				if ( m > pArray[j])
				{
					m = pArray[j];
					mIndex = j;
				}
			}
		}
		mSwap(pArray+i, pArray+mIndex);  //把最大值放到序列首部
		//重置最值(m)
		if ( type ) //求最大值
		{
			m = 0;
		}
		else  //求最小值
		{
			m = AMAX;
		}
	}
}

/*
* 直接插入排序
*/
void insertSort( int *pArray, const int n, const int type)
{
	int temp;
	int i = 0;
	int j = 0;
	for( i=1; i<n; i++)
	{
		//这里temp就是从待排序列中取出的一个元素
		//而初始化时待排队列是数组元素1-(n-1)位置上n-1个元素
		//已排队列是数组中头部第一个元素
		temp = pArray[i];
		j = i;
		
		if( type )//从小到大排列
		{
			//如果满足左大右小,所有数组中的元素从左向右移动
			//如果temp最小,它将被插到数组头部
			while( j>0 && pArray[j-1] > temp )
			{
				pArray[j] = pArray[j-1]; 
				j--;
			}
		}
		else //从大到小排列
		{
			//如果temp最小,它将被插到数组头部
			while( j>0 && pArray[j-1] < temp )
			{
				pArray[j] = pArray[j-1]; 
				j--;
			}
		}
		//如果移动到数组头部,或者找到合适的位置,将元素插入
		pArray[j] = temp;
	}
}

/*
* 二分插入排序
*/
void binaryInsertSort( int *pArray, const int n, const int type)
{
	int temp;
	int i = 0;
	int j = 0;
	int left = 0;
	int right = 0;
	int middle = 0;
	for( i=1; i<n; i++)
	{
		temp = pArray[i];
		//二分查找,寻找插入位置
		left = 0;
		right = i - 1;
		while( left <= right )
		{
			middle = ( left + right ) / 2;
			if( type ) //从大到小
			{
				if( temp < pArray[middle] )
				{
					left = middle + 1;
				}
				else
				{
					right = middle - 1;
				}
			}
			else //从小到大
			{
				if( temp > pArray[middle] )
				{
					left = middle + 1;
				}
				else
				{
					right = middle - 1;
				}
			}
			
		}
		//成块的移出插入位置
		for( j=i-1; j>=left; j--)
		{
			pArray[j+1] = pArray[j];
		}
		//插入元素
		pArray[left] = temp; 
	}
}

/*
* Shell 排序
*/
void shellSort( int *pArray, const int n, const int type)
{
	int gap = n/2;  //首次选取gap值为n/2
	int i = 0;
	int j = 0;
	int temp = 0;
	while( gap )
	{
		for( i=gap; i<n; i+=gap)
		{
			temp = pArray[i];
			j = i;
			if( type ) //从大到小
			{
				while( j>0 && temp > pArray[j-gap])
				{
					pArray[j] = pArray[j-gap];
					j = j - gap;
				}
			}
			else  //从小到大
			{
				while( j>0 && temp < pArray[j-gap])
				{
					pArray[j] = pArray[j-gap];
					j = j - gap;
				}
			}	
			pArray[j] = temp;
		}
		gap /= 2;  //每次gap值折半
	}
}

/*
* 划分,根据选中的轴把排序序列划分为两个部分
*/
int parttition( int *pArray, const int low, const int high, const int type)
{
	//这里划分的思路是先把轴的值保存起来,
	//然后用一个指针指向轴的位置(即队首部),
	//接着依次从序列首部向尾部遍历,查找是否有比轴大(或者比轴小)的元素,
	//一旦有,将它和该指针指向的元素交换,然后再把该指针向队尾移动一个单位
	//这样做的目的是保证轴指针左边都是比轴大(或者比轴小)的元素,
	//遍历完之后,再将轴指针指向的元素和真正的轴交换
	int pivotpos = low;      //轴位置
	int pivot = pArray[low]; //选中排序序列中第一个位置为轴
	int i = low + 1;
	for( i=low+1; i<=high; i++)
	{
		if( type ) //从小到大
		{
			//保证pivotpos指针左边都是比pivot小的值 
			if( pArray[i] < pivot && ++pivotpos != i )
			{
				mSwap( pArray+pivotpos, pArray+i);
			}
		}
		else //从达到小
		{
			//保证pivotpos指针左边都是比pivot大的值
			if( pArray[i] > pivot && ++pivotpos != i )
			{
				mSwap( pArray+pivotpos, pArray+i);
			}
		}	
	}
	//将正真的轴,和轴指针指向的元素做交换
	mSwap( pArray+low, pArray+pivotpos);
	return pivotpos;
}

/*
* 划分2,根据选中的轴把排序序列划分为两个部分
*/
int parttition1( int *pArray, const int low, const int high, const int type)
{
	//除了上面的划分方法之外,还有一种方法
	//首先保存轴的值,这里取队首第一个元素,然后从序列的两端(low和high)向中间遍历,
	//首先high向队首移动,一旦找到比轴小的(或大的)元素,将其放到low的位置,
	//然后low向队尾移动,一旦找到比轴大的(或者小的)元素,将其放到high的位置,
	//这样直到low和high相遇,并且在相遇的时候,low和high就把这个序列分成一边是比轴
	//大的元素,一边是比轴小的元素,最后将轴放到low(或high)的位置。
	int tlow = low;
	int thigh = high;
	int pivot = pArray[tlow];
	while( tlow < thigh )
	{
		if( type ) //从小到大排序
		{
				//high指针向队尾移动
				while(tlow < thigh && pArray[thigh] > pivot )
				{
					thigh--;
				}
				//找到比pivot小的值,放到low处
				pArray[tlow] = pArray[thigh];
				//low指针向队首移动
				while( tlow < thigh && pArray[tlow] < pivot )
				{
					tlow++;
				}
				//找到比pivot大的,放到high处
				pArray[thigh] = pArray[tlow];
		}
		else //从大到小排序
		{
				//high指针向队尾移动
				while(tlow < thigh && pArray[thigh] < pivot )
				{
					thigh--;
				}
				//找到比pivot大的值,放到low处
				pArray[tlow] = pArray[thigh];
				//low指针向队首移动
				while( tlow < thigh && pArray[tlow] > pivot )
				{
					tlow++;
				}
				//找到比pivot小的,放到high处
				pArray[thigh] = pArray[tlow];
		}
	}
	//当low和high指针相遇,把轴插入
	pArray[tlow] = pivot;
	return tlow;
}

/*
* 快排
*/
void QuickSort (int *pArray, const int left, const int right, const int type)
{
	if( left < right )
	{
		//先划分
		int pivotpos = parttition1( pArray, left, right, type);
		//左部递归(递归的时候,及得要把轴从队列中拿出来)
		QuickSort( pArray, left, pivotpos-1, type);
		//右部递归(递归的时候,及得要把轴从队列中拿出来)
		QuickSort( pArray, pivotpos+1, right, type);
	}
}

void quickSort( int *pArray, const int n, const int type )
{
	QuickSort( pArray, 0, n-1, type);
}

int main()
{	
	int i = 0;
	int marray[LEN] = {0};
	srand(time(0));
	for ( i=0; i<LEN; i++)
	{
		marray[i] = rand() % AMAX + 1;
	}
	//findMaxAndMin(marray, LEN);

	printf("SORT1:\n");
	printf("Before Sort:\n");
	printArray(marray, LEN);
	quickSort(marray, LEN, 1);
	printf("After Sort:\n");
	printArray(marray, LEN);

	printf("SORT2:\n");
	printf("Before Sort:\n");
	printArray(marray, LEN);
	quickSort(marray, LEN, 0);
	printf("After Sort:\n");
	printArray(marray, LEN);

/*
	printf("SORT2:\n");
	printf("Before Sort:\n");
	printArray(marray, LEN);
	bubleSort1( marray, LEN,0);
	printf("After Sort:\n");
	printArray(marray, LEN);
*/
	return 0;
}





  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值