之前在merge这段函数
for (int k = p; k <= r; k++)
之前写成k<r 导致最后输出的结果不正确
设置哨兵的
#include "stdafx.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
const int maxVal = 10000 + 5;
const int maxLength = 20;
void mergeSort(int a[], int, int);
void merge(int a[], int, int, int);
int main(){
int a[] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
mergeSort(a, 0, 12); // 此处传入参数 为 数组首地址,数组首元素的下标,数组最后一个元素的下标
for (size_t i = 0; i < 13; i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
void mergeSort(int a[], int p, int r){
if (p < r){
int q = (p + r) / 2;
mergeSort(a, p, q);
mergeSort(a, q + 1, r);
merge(a, p, q, r);
}
}
void merge(int a[], int p, int q, int r){
int n1 = q - p + 1;
int n2 = r - q;
int left[maxLength];
int right[maxLength];
left[n1] = maxVal; // 设置哨兵
right[n2] = maxVal; // 设置哨兵
for (size_t i = 0; i < n1; i++)
{
left[i] = a[p + i];
}
for (size_t j = 0; j < n2; j++)
{
right[j] = a[q + j + 1];
}
size_t i = 0;
size_t j = 0;
for (int k = p; k <= r; k++)
{
if (left[i] <= right[j])
{
a[k] = left[i];
++i;
}
else
{
a[k] = right[j];
++j;
}
}
}
根据2.3-2重写不使用哨兵,而是一旦L或R数组的所有元素复制回A后立刻停止,然后将另一个数组余下的部分复制回A
#include "stdafx.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
const int maxVal = 10000 + 5;
const int maxLength = 2000+5;
void mergeSort(int a[], int ,int );
void merge(int a[], int, int, int);
int main(){
int a[1999];
for (size_t i = 0, j = 1999; i < 1999;i++,j--)
{
a[i] = j;
}
mergeSort(a, 0, 1998); // 此处传入的长度参数 为 数组长度-1
for (size_t i = 0; i < 1998;i++)
{
cout << a[i]<<" ";
}
cout << endl;
return 0;
}
void mergeSort(int a[], int p, int r){
if (p < r){
int q = (p + r) / 2;
mergeSort(a, p, q);
mergeSort(a, q + 1, r);
merge(a, p, q, r);
}
}
void merge(int a[], int p, int q, int r){
int n1 = q - p + 1;
int n2 = r - q ;
int left[maxLength];
int right[maxLength];
// left[n1] = maxVal; // 设置哨兵
// right[n2] = maxVal; // 设置哨兵
for (size_t i = 0; i < n1; i++)
{
left[i] = a[p + i];
}
for (size_t j = 0; j < n2; j++)
{
right[j] = a[q + j + 1];
}
size_t i = 0;
size_t j = 0;
for (int k = p; k <= r; k++)
{
if (left[i] <= right[j])
{
a[k] = left[i];
++i;
}
else
{
a[k] = right[j];
++j;
}
if (i == n1 && j<n2){
for (int currK = k+1; currK <= r;currK++)
{
a[currK] = right[j];
++j;
}
break;
}
if (j == n2 && i<n1){
for (int currK = k+1; currK <= r; currK++)
{
a[currK] = left[i];
++i;
}
break;
}
}
}