GetMaxMin.h
#ifndef _GETMAXMIN_H_
#define _GETMAXMIN_H
Demo1
struct MaxMin
{
int min;
int max;
};
MaxMin GetMaxMin(int *arr,int beg,int end)
{
MaxMin maxmin,maxmin1,maxmin2;
int mid;
if(beg == end)
{
maxmin.min = arr[beg];
maxmin.max = arr[end];
return maxmin;//
}
else if(end - 1 == beg)
{
maxmin.max = arr[beg] > arr[end] ? arr[beg]: arr[end];
maxmin.min = arr[beg] < arr[end] ? arr[beg]: arr[end];
return maxmin;//
}
else
{
mid = (beg + end)/2;
maxmin1 = GetMaxMin(arr,beg,mid);
maxmin2 = GetMaxMin(arr,mid + 1,end);
//合并两个区间的最大值和最小值
maxmin.max = maxmin1.max > maxmin2.max ? maxmin1.max : maxmin2.max;
maxmin.min = maxmin1.min < maxmin2.min ? maxmin1.min : maxmin2.min;
return maxmin;//
}
}
///Demo2
//arr[0...n-1]中大于arr[n]的数字
int GreaterNumCount(int *arr,int n/*,int num*/)
{
int count = 0;
for(int i = 0;i<=n ;i++)
if(arr[i] > arr[n+1])
count++;
return count;
}
//f(0) = 0; f(1) = 1 or 0; f(n) = f(n-1) + arr[0...n-1]中大于arr[n]的数字
int GetReverseNum(int *arr,int n)
{
if(n == 0)
return 0;
else if(n == 1)
return arr[0] > arr[1] ? 1 : 0;
else// n >=2
{
return GetReverseNum(arr,n-1) + GreaterNumCount(arr,n-1/*,arr[n]*/);
}
}
Dem3
void swap(int &a,int &b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
int Partion(int *arr,int n)//0-n
{
int pivot = 0;
int p_val = arr[0];
int i = 1,j=n;
while(1)
{
while(arr[i] < p_val)
{
i++;
if(i > n)
{
//can do nothing here
//swap(arr[pivot],arr[n]);
return n;
}
}
while(arr[j] > p_val)
j--;
if(i<j)
swap(arr[i],arr[j]);
else//i>=j
{
//0 -6 -6 -5 6 9 4 --> j = -5
//swap(arr[j],p_val);//可以不交换
return j;
}
}
}
///Demo4
int Partition(int *arr,int beg,int end)
{
int pivot = beg;
int s = arr[beg];
int i = beg + 1,j = end;//----i = beg + 1
while(1)
{
while(arr[i] < s)
{
i++;
if(i > end)// 5 4 3 2
{
swap(arr[end],arr[pivot]);
return end;
}
}
while(arr[j] > s)
j--;
if(i < j)
swap(arr[i],arr[j]);
else//i<=j
{
//swap(arr[j],s);//error 应该交换数组对应位置的元素
swap(arr[j],arr[pivot]);
return j;
}
}
}
void QS(int *arr,int beg,int end)
{/*如递归所有控件路径,函数将导致运行时堆栈溢出*/
//int s = Partition(arr,beg,end);
int s;
if(beg<end)
{
s = Partition(arr,beg,end);
QS(arr,beg,s-1);//
QS(arr,s+1,end);
}
}
//Demo5
void PartionOddEven(int *arr,int n)//0-n
{
int pivot = 0;
int p_val = arr[0];
//int i = 1,j=n;
int i = 0,j = n;
while(1)
{
while(arr[i]%2 == 1) //奇数
{
i++;
if(i > n)//注意 全是偶数的情况
{
//can do nothing here
//swap(arr[pivot],arr[n]);
//return n;
break;
}
}
while(arr[j]%2 ==0)//
{
j--;
if(j < 0)//注意 全是偶数的情况
break;//
}
if(i<j)
swap(arr[i],arr[j]);
else
break;
/*
else//i>=j
{
//0 -6 -6 -5 6 9 4 --> j = -5
//swap(arr[j],p_val);//可以不交换
return j;
}
*/
}
}
//Demo6
//RWB
void swap(char &a,char &b)
{
char tmp;
tmp = a;
a = b;
b = tmp;
}
//RRBWBR
void RangeFlag(char *arr,int n)
{
int beg = 0,end = n;//beg前面的都已经排好了 end后面的都已经排好了
int cur = 0;
char tmp;
while(cur <= end)//end的右边全是B 停止判断
{
if(arr[cur] == 'R')
{
swap(arr[beg],arr[cur]);
//beg = cur;
beg ++;//-------
cur ++;
}
else if(arr[cur] == 'W')
{
cur ++;
}
else//B
{
swap(arr[cur],arr[end]);
end --;
}
}
}
/*
设置两个标志位begin和end分别指向这个数组的开始和末尾,然后用一个标志位current从头开始进行遍历:
1)若遍历到的位置为R,则说明它一定属于前部,于是就和begin位置进行交换,然后current向前进,
begin也向前进(表示前边的已经都排好了)。
2)若遍历到的位置为W,则说明它一定属于中部,根据总思路,中部的我们都不动,然后current向前进。
3)若遍历到的位置为B,则说明它一定属于后部,于是就和end位置进行交换,由于交换完毕后current指向的可能是属于前部的,
若此时current前进则会导致该位置不能被交换到前部,所以此时current不前进。而同1),end向后退1。
*/
#endif
#include <iostream>
#include <string.h>
#include <algorithm>
#include "GetMaxMin.h"
using namespace std;
int main()
{
//1.同时求最大值和最小值
cout << "Max and Min:" << endl;
int arr[11] = {-119,8,9,2,5,-7,10,200,3,-7,201};
MaxMin maxmin;
maxmin = GetMaxMin(arr,0,10);
cout << "max: " << maxmin.max << " min:" << maxmin.min << endl;
//求逆置数的对数
//int arr2[5] = {2,3,3,2,1};
int arr2[5] = {2,2,2,2,2};
cout << "GetReverseNum: " << GetReverseNum(arr2,4) << endl;
//负数放到正数前面
cout << "负数放到正数前面:" << endl;
//int arr3[7] = {0,-3,-9,-8,-5,-2,-9};
int arr3[7] = {0,-3,4,6,7,-2,9};
int p = Partion(arr3,6);//---------------------
cout << "partion point:" << p << endl;
for(int i = 1;i<=6;i++)
cout << arr3[i] << " ";
cout << endl;
//快速排序
int arr4[7] = {0,-3,-9,2,-5,11,11};
QS(arr4,0,6);
cout<< "QuickSort:"<< endl;
for(int i = 0;i<=6;i++)
cout << arr4[i] << " ";
cout << endl;
copy(arr4,arr4 + 7,ostream_iterator<int,char>(cout," "));//注意第二个参数应该为超尾迭代器
cout << endl;
//奇数放到偶数前面
cout << "奇数放到偶数前面:" << endl;
//int arr5[6] = {3,8,1,9,4,0};
//int arr5[6] = {2,8,9,2,6,4};
//int arr5[6] = {2,8,20,2,6,4};
int arr5[6] = {1,9,3,5,21,33};
PartionOddEven(arr5,5);
copy(arr5,arr5 + 6,ostream_iterator<int,char>(cout," "));
cout << endl;
//三色国旗
cout << "三色国旗:" << endl;
//char *flags = "RRBWBR";//error 常量不可修改
char flags[] = {"RRBWRWBBBRWR"};
//char flags[] = {"BBBBBBBBB"};
//char flags[] = {"RRRRRRRR"};
//char flags[] = {"RRWWBB"};
//char flags[] = {"WBRRWRBW"};
RangeFlag(flags,strlen(flags) - 1);
cout << flags << endl;
return 0;
}