算法设计--分治法

1.归并排序

#include<iostream>
using namespace std;

// 合并子序列 
void merge(int r[], int r1[], int s, int m, int t) {
	int i=s, j=m+1, k=s;
	
	//取r[i] r[j]中较小的放进r1[k]
	while(i<=m && j<=t) {
		if(r[i] <= r[j])   
			r1[k++] = r[i++];
		else
			r1[k++] = r[j++];
	}
	
	while(i<=m) //若第一个子序列没有处理完 进行收尾工作
		r1[k++] = r[i++];
		
	while(j<=t) //若第二个子序列没有处理完 进行收尾工作
		r1[k++] = r[j++]; 
}

// 对序列r[s]~r[t]进行归并排序 
void mergesort(int r[], int s, int t) 
{
	int m, r1[1000];
	if(s == t) return;	//递归边界条件 只有一个记录 已经有序 
	else {
		m = (s+t)/2; //划分
		mergesort(r,s,m); //求解子问题1 归并排序前半个子序列 
		mergesort(r,m+1,t); //求解子问题2 归并排序后半个子序列 
		merge(r,r1,s,m,t); //合并两个有序子序列存入数组r1中
		for(int i=s; i<=t; i++)
			r[i] = r1[i]; 
	} 
}

int main()
{
	int array[8] = {8,3,2,6,7,1,5,4};
	mergesort(array,0,7);
	for(int i=0; i<8; i++)
	cout << array[i] << " ";
	cout << endl;
	return 0;
} 

2.快速排序


int partition(int* arr, int low, int high) {
	int pivot = arr[low];
	while(low<high) {
		//从右向左搜索 找第一个<=pivot的元素 
		while(low<high && arr[high]>=pivot)
			--high;
		arr[low] = arr[high];  //把比枢轴小的元素移到左子表 
		//从左向右搜索 找第一个>=pivot的元素
		while(low<high && arr[low]<=pivot)
			++low; 
		arr[high] = arr[low]; //把比枢轴大的元素移到右子表
	}
	arr[low]=pivot; //把枢轴移动到正确的位置 
	return low; //返回枢轴位置 
} 

void quicksort(int *arr, int low, int high) {
	int pivotloc;
	if(low<high) {
		pivotloc=partition(arr,low,high);
		quicksort(arr,low,pivotloc-1); //对左子表递归排序 
		quicksort(arr,pivotloc+1,high); //对右子表递归排序 
	}
}

3.最大子段问题

int max_sum(int a[], int left, int right) {
	int sum=0, mid_sum=0, left_sum=0, right_sum=0;
	int center, s1, s2, lefts, rights;
	if(left == right) 
		sum = a[left];
	else {
		center = (left+right)/2;
		left_sum = max_sum(a, left, center);
		right_sum = max_sum(a, center+1, right);
		s1 = 0;lefts=0;
		for(int i=center; i>=left; i--) {
			lefts += a[i];
			if(lefts>s1) s1=lefts;
		}
		s2=0; rights=0;
		for(int j=center+1; j<right; j++) {
			rights += a[j];
			if(rights>s2) s2=rights;
		}
		mid_sum = s1+s2;
		
		if(mid_sum < left_sum) sum = left_sum;
		else sum = mid_sum;
		if(sum < right_sum) return right_sum;
		else return sum;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值