算法练习(分治法,分区思想)

来源:互联网 发布:火车票选座位软件 编辑:程序博客网 时间:2024/05/16 15:01


GetMaxMin.h

#ifndef _GETMAXMIN_H_#define _GETMAXMIN_H////Demo1struct 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]*/);}}////Dem3void 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;}}}///Demo4int Partition(int *arr,int beg,int end){int pivot = beg;int s = arr[beg];int i = beg + 1,j = end;//----i = beg + 1while(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);}}//Demo5void 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]);elsebreak;/*else//i>=j{//0 -6 -6 -5 6 9 4  --> j = -5   //swap(arr[j],p_val);//可以不交换return j;}*/}}//Demo6//RWBvoid swap(char &a,char &b){char tmp;tmp = a;a = b;b = tmp;}//RRBWBRvoid 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;} 



0 0
原创粉丝点击