快速排序、求旋转数组最小数字

#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

// 快速排序1
void quickSort( int a[], int l, int r )
{
	if( l >= r )
	{
		return;
	}
	
	int i = l; 
	int j = r;

	int mid = ( l + r ) / 2;
	int tmp = a[mid];
	a[mid] = a[l];
	a[l] = tmp;

	int value = a[l];

	while( i < j )
	{

		while( i < j && a[j] >= value ) j--;
		
		a[i] = a[j];

		while( i < j && a[i] <= value ) i++;
		
		a[j] = a[i];		
		
	}

	a[i] = value;

	quickSort( a, l, i - 1 );
	quickSort( a, i + 1, r );
	
	
	return;

}


// 快速排序2,容易理解的快排
void quickSort1( int a[], int start, int end )
{
	if( start >= end )
	{
		return;
	}	

	int mid = ( start + end ) / 2;
	int tmp = a[mid];
	a[mid] = a[end];
	a[end] = tmp;

	int idx = start - 1;

	for( int i = start; i < end; i++ )
	{		
		if( a[i] < a[end] )   // a[end]作为pivot 
		{
			idx++;
			
			if( idx != i )
			{
				int tmp = a[idx];
				a[idx] = a[i];
				a[i] = tmp;
			}
		}		
	}

	idx++;
	tmp = a[idx];
	a[idx] = a[end];
	a[end] = tmp;

	quickSort1( a, start, idx - 1 );
	quickSort1( a, idx + 1, end );
	
	return;
}


void print( int a[], int len )
{
	for( int i = 0; i < len; i++ )
	{
		cout << a[i] << ' ';	
	}

	cout << endl;

	return;
}


// 求旋转数组的最小数字 递归实现
int midRotatedArray( int a[], int start, int end )
{
	int min = -1;

	if( NULL == a )
	{
		min = -1;
		return min;
	}

	if( start >= end )
	{
		min = a[start];
		return min;
	}

	int mid = ( start + end ) / 2;

	//if( a[mid] <= a[ ( mid + 1 ) % 
	int right = mid + 1 > end ? start : mid + 1;
	int left = mid - 1 < start ? end: mid - 1;

	if( a[mid] <= a[right] && a[mid] <= a[left] )  
	{
		if( !( a[mid] == a[right] && a[mid] == a[left] ) ) // for { 2 3 3 3 1 }
		{
			min = a[mid];
			//cout << start << ' ' << mid << ' ' << end << endl;
			return min;
		}
		
	}

	int minLeft = midRotatedArray( a, start, mid - 1 );
	int minRight = midRotatedArray( a, mid + 1, end );

	return minLeft > minRight ? minRight : minLeft;
	
}

// 求旋转数组的最小数字 非递归实现
int midRotatedArray_noRecur( int a[], int start, int end )
{
	int min = -1;

	if( NULL == a )
	{
		min = -1;
		return min;
	}

	if( start >= end )
	{
		min = a[start];
		return min;
	}

	int mid = ( start + end ) / 2;
	
	while( a[start] >= a[end] )
	{
		mid = ( start + end ) / 2;
			
		int right = mid + 1 > end ? start : mid + 1;
		int left = mid - 1 < start ? end : mid - 1;

		if( a[mid] <= a[right] && a[mid] <= a[left] )
		{
			if( !( a[mid] == a[right] && a[mid] == a[left] ) )
			{
				min = a[mid];
				//cout << start << ' ' << mid << ' ' << end << endl;
				return min;
			}
		
		}	
		
		if( a[start] == a[mid] && a[mid] == a[end] ) // 顺序查找, for : { 1 0 1 1 1 } and  { 1 1 1 0 1 }
		{
			min = a[start];

			for( int i = start + 1; i <= end; i++ )
			{
				if( min > a[i] )
				{
					min = a[i];
				}
			}

			return min;
		}

		if( start != mid && a[start] >= a[mid] )
		{
			end = mid - 1;
		}
		else 
		{
			start = mid + 1;
		}

	}

	min = a[start];
	return min;
}

// 总结: 先写测试用例,否则很多考虑不周

int main()
{
	int ret = 0;
	int data = -2;
	data = data << 2;
	cout << data << endl;
	
	data = -2;
	data = data >> 2;
	cout << data << endl;
        // 针对求旋转数组的最小数字的测试用例
	int b0[] = { 3, 4, 5, 6, 1 };
	int b1[] = { 2, 2, 3, 0, 1 };
	int b2[] = { 1, 2, 3, 4, 5 };
	int b3[] = { 2, 2, 2, 2, 2 };
	int b4[] = { 1, 1, 1, 0, 1 };
	int b5[] = { 1, 0, 1, 1, 1 };
	int b6[] = { 2, 1 };
	int b7[] = { 3 };
	int *b8 = NULL;

	cout << midRotatedArray( b7, 0, 0 ) << endl;
	cout << midRotatedArray_noRecur( b7, 0, 0 ) << endl;

	int a1[] = { 1, 2, 3, 4, 5 };
	int a2[] = { 5, 4, 3, 2, 1 };
	int a3[] = { 5, 7, 1, 3, 6 };
	int a4[] = { 5, 4, 4, 4, 1 };
	int a5[] = { 4, 4, 4, 4, 4 };

	quickSort1( a1, 0, 4 );
	quickSort1( a2, 0, 4 );
	quickSort1( a3, 0, 4 );
	quickSort1( a4, 0, 4 );
	quickSort1( a5, 0, 4 );

	print( a1, 5 );
	print( a2, 5 );
	print( a3, 5 );
	print( a4, 5 );
	print( a5, 5 );

	return ret;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值