先拆后合
分为两部分,两部分都有序后再合并
终止条件: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;
}