归并排序

先拆后合
分为两部分,两部分都有序后再合并
终止条件:left = right

//作者:蒋伟泉
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
const int MAX_SIZE = 15;
const int NUM = 100;
vector<int> generate(){//for test
	srand(time(NULL));
	vector<int>v;
	int size = rand() % MAX_SIZE+1;
	for (int i = 0; i < size; i++){
		int temp = rand() % NUM;
		v.push_back(temp);
	}
	return v;
}
void show(vector<int>&v){//for test
	for (int i = 0; i < v.size(); i++){
		cout << v[i] << " ";
	}
	cout << endl;
}
void merge(vector<int>&v, int left, int mid, int right){
	vector<int>help (right-left+1,0);//注意这里vector的大小
	int p1 = left, p2 = mid+1;
	int i = 0;
	while (p1 <= mid&&p2 <= right){
		while (p1 <= mid&&p2 <= right){
			help[i++] = v[p1] < v[p2] ? v[p1++] : v[p2++];
		}
		while (p1 <= mid){
			help[i++] = v[p1++];
		}
		while (p2 <= right){
			help[i++] = v[p2++];
		}
	}
	for (i = 0; i < help.size(); i++){
		v[left + i] = help[i];
	}
}
void mergesort(vector<int>&v, int left, int right){
	if (left == right)
		return;
	int mid = (left + right) / 2;
	mergesort(v, left, mid);
	mergesort(v,mid + 1, right);
	merge(v, left, mid, right);
}
void mergesort(vector<int>&v){
	if (v.size() <= 1){
		return;
	}
	mergesort(v, 0, v.size() - 1);
}
void test(){
	vector<int>v = generate();
	show(v);
	mergesort(v);
	show(v);
}
int main()
{
	test();
	system("pause");
	return 0;
}

小和问题
在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和。 求一个数组
的小和。
例子:[1,3,4,2,5]
1左边比1小的数, 没有;
3左边比3小的数, 1;
4左边比4小的数, 1、 3;
2左边比2小的数, 1;
5左边比5小的数, 1、 3、 4、 2;
所以小和为1+1+3+1+1+3+4+2=16

//作者:蒋伟泉
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
const int MAX_SIZE = 8;
const int NUM = 10;
vector<int> generate(){
	srand(time(NULL));
	vector<int>v;
	int size = rand() % MAX_SIZE + 1;
	for (int i = 0; i < size; i++){
		int temp = rand() % NUM;
		v.push_back(temp);
	}
	return v;
}
void show(vector<int>&v){
	for (int i = 0; i < v.size(); i++){
		cout << v[i] << " ";
	}
	cout << endl;
}
int merge(vector<int>v, int left, int mid, int right){
	vector<int>help(right - left + 1, 0);
	int p1 = left, p2 = mid + 1;
	int res = 0, i = 0;
	while (p1 <= mid&&p2 <= right){
		res += (right - p2 + 1)*(v[p1] < v[p2] ? v[p1] : 0);
		help[i++] = v[p1] < v[p2] ? v[p1++] : v[p2++];
	}
	while (p1<=mid)
	{
		help[i++] = v[p1++];
	}
	while (p2 <= right){
		help[i++] = v[p2++];
	}
	for (i = 0; i < help.size(); i++){
		v[left + i] = help[i];
	}
	return res;
}
int smallsum(vector<int>v, int left, int right){
	if (left == right)
		return 0;
	int mid = (left + right) / 2;
	return smallsum(v, left, mid) + smallsum(v,mid + 1, right) +
		merge(v, left, mid, right);
}
int smallsum(vector<int>&v){
	if (v.size() == 0)
		return 0;
	return smallsum(v, 0, v.size() - 1);
}
void test(){
	vector<int>v = generate();
	show(v);
	cout << smallsum(v);
}
int main(){
	test();
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值