不知怎的,我使用向量实现了Merge排序,问题是: 它可以在少于9个输入的情况下正常工作,但是有9个或更多输入它可以做一些我不太了解的事情,如下所示:
Input:
5-4-3-2-1 --- 6-5-4-3-2-1 --- 9-8-7-6-5-4-3-2-1
Output:
1-2-3-4-5 --- 1-2-3-4-5-6 --- 1-2-3-4-5-7-6-8-9
以下是代码:
#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace std;
void showvector(vector<int> numbers){
for (vector<int>::iterator i = numbers.begin(); i != numbers.end(); i++)
{
cout << *i;
if (i != numbers.end() - 1)cout << " - ";
}
}
vector<int> getvector(){
vector<int> numbers(0);
cout << "please enter you numbers :::\n''entering any characters but numbers is the end of entry''\n";
int counter = 0;
do{
int newnumber = 0;
cout << "element(" << counter << ") = ";
counter++;
cin >> newnumber; getchar();
if (cin.good())
numbers.push_back(newnumber);
if (cin.fail()){
cout << "numbers are :";
showvector(numbers);
}
} while (cin.good()); getchar();
return numbers;
}
void mergesort(vector<int>& numbers);
vector<int> merge(vector<int>& one, vector<int>& two){
cout << "\ncomparing vector one with "; showvector(one); cout << " element(s) with vector two with "; showvector(two); cout << " element(s)\n";
vector<int>::iterator j = two.begin();
vector<int>::iterator i;
for (i = one.begin(); i != one.end(); i++){
cout << "comparing " << *i << " with " << *j<<endl;
if (*i > *j){
cout << "exchanging " << *i << " with " << *j << endl;;
int c = *i;
*i = *j;
*j = c;
j++;
}
}
if (j != two.end() && i==one.end())
mergesort(two);
cout << "\npushing vector two with "; showvector(two); cout << " element(s) back to vector one with "; showvector(one); cout << " element(s)\n";
for (j=two.begin(); j != two.end();j++)
one.push_back(*j);
cout << "returning sorted vector as\n";
showvector(one);
return one;
}
void mergesort(vector<int>& numbers){
if (numbers.size() > 1){
vector<int> halfone(numbers.begin(), numbers.begin() + numbers.size() / 2);
mergesort(halfone);
vector<int> halftwo(numbers.begin() + numbers.size() / 2, numbers.end());
mergesort(halftwo);
numbers = merge(halfone, halftwo);
}
}
int main(){
vector<int> numbers(getvector());
mergesort(numbers);
cout << "\nnumbers are :";
showvector(numbers);
getchar();
}
答案 0 :(得分:1)
这是一对合并排序示例,有些优化,可能比学生的预期要多一些。
顶部示例是自上而下合并排序。 a []是要排序的数组,b []是与[]大小相同的临时数组。通过一对递归函数来避免复制数据,这些递归函数根据递归的级别交替合并的方向。
底部示例是自下而上合并排序。请注意,排序后的数组最终可以是[]或b []。这可以通过计算通过次数来避免,如果通过次数是奇数,则在第一次通过时就地交换。
两个排序示例都使用两个数组并使用索引进行合并。主要区别在于自上而下使用递归来重复分割索引对,直到索引表示运行大小为1,然后它开始实际的合并过程,而自下而上跳过此步骤并开始运行大小为1并且立即开始合并。大部分时间都花在合并上,因此与排序所需的总时间相比,递归生成索引的额外开销很小。
自上而下合并排序
int * TopDownMergeSort(int a[], int b[], size_t n)
{
if(n < 2) // if size < 2 return
return a;
TopDownSplitMergeAtoA(a, b, 0, n);
return a;
}
void TopDownSplitMergeAtoA(int a[], int b[], size_t ll, size_t ee)
{
if((ee - ll) == 1) // if size == 1 return
return;
size_t rr = (ll + ee)>>1; // midpoint, start of right half
TopDownSplitMergeAtoB(a, b, ll, rr);
TopDownSplitMergeAtoB(a, b, rr, ee);
TopDownMerge(b, a, ll, rr, ee); // merge b to a
}
void TopDownSplitMergeAtoB(int a[], int b[], size_t ll, size_t ee)
{
if((ee - ll) == 1){ // if size == 1 copy a to b
b[ll] = a[ll];
return;
}
size_t rr = (ll + ee)>>1; // midpoint, start of right half
TopDownSplitMergeAtoA(a, b, ll, rr);
TopDownSplitMergeAtoA(a, b, rr, ee);
TopDownMerge(a, b, ll, rr, ee); // merge a to b
}
void TopDownMerge(int a[], int b[], size_t ll, size_t rr, size_t ee)
{
size_t o = ll; // b[] index
size_t l = ll; // a[] left index
size_t r = rr; // a[] right index
while(1){ // merge data
if(a[l] <= a[r]){ // if a[l] <= a[r]
b[o++] = a[l++]; // copy a[l]
if(l < rr) // if not end of left run
continue; // continue (back to while)
while(r < ee){ // else copy rest of right run
b[o++] = a[r++];
}
break; // and return
} else { // else a[l] > a[r]
b[o++] = a[r++]; // copy a[r]
if(r < ee) // if not end of right run
continue; // continue (back to while)
while(l < rr){ // else copy rest of left run
b[o++] = a[l++];
}
break; // and return
}
}
}
自下而上合并排序
int * BottomUpMergeSort(int a[], int b[], size_t n)
{
for(size_t s = 1; s < n; s <<= 1){ // s = run size
size_t ee = 0; // init end index
while(ee < n){ // merge pairs of runs
size_t ll = ee; // ll = start of left run
size_t rr = ll+s; // rr = start of right run
if(rr >= n){ // if only left run
rr = n;
BottomUpCopy(a, b, ll, rr); // copy left run
break; // end of pass
}
ee = rr+s; // ee = end of right run
if(ee > n)
ee = n;
BottomUpMerge(a, b, ll, rr, ee);
}
std::swap(a, b); // swap a and b ptrs
}
return a; // return sorted array
}
void BottomUpCopy(int a[], int b[], size_t ll, size_t rr)
{
while(ll < rr){ // copy left run
b[ll] = a[ll];
ll++;
}
}
void BottomUpMerge(int a[], int b[], size_t ll, size_t rr, size_t ee)
{
size_t o = ll; // b[] index
size_t l = ll; // a[] left index
size_t r = rr; // a[] right index
while(1){ // merge data
if(a[l] <= a[r]){ // if a[l] <= a[r]
b[o++] = a[l++]; // copy a[l]
if(l < rr) // if not end of left run
continue; // continue (back to while)
while(r < ee){ // else copy rest of right run
b[o++] = a[r++];
}
break; // and return
} else { // else a[l] > a[r]
b[o++] = a[r++]; // copy a[r]
if(r < ee) // if not end of right run
continue; // continue (back to while)
while(l < rr){ // else copy rest of left run
b[o++] = a[l++];
}
break; // and return
}
}
}