2016-12-04 101 views
-1

我试图得到一个合并排序程序工作,以及已经工作,使用向量的基数排序。合并排序 - 向量下标超出范围

但是,合并排序总是给我“Vector下标超出范围”的错误。我知道为什么会出现这个错误,但我无法弄清楚我应该采取什么措施来阻止它。

代码:

#include "Includes.h" 

class Mergesort 
{ 
public: 

std::vector<int> mergeSort(std::vector<int> list, int low, int high, int max) 
{ 
    int mid; 

    if (low < high) // Does not continue to merge sort when low is less than high. 
    { // This will be when the given set is a single number. 
     mid = low + (high - low)/2; 
     list = mergeSort(list, low, mid, max); // Split the given set into two halves down the middle. 
     list = mergeSort(list, mid + 1, high, max); 
     list = merge(list, low, mid, high, max); 
    } 

    return list; 
} 

std::vector<int> merge(std::vector<int> list, int low, int mid, int high, int max) // Call requires the bottom, middle and top numbers of the set. 
{ 
    int h, i, j, k; 
    std::vector<int> listb(max); // Merged list. 
    h = low - 1; 
    i = low - 1; 
    j = mid; 

    while ((h <= mid) && (j <= high)) 
    { 
     if (list[h] <= list[j]) // If the low part of the array is less than the upper middle of the array, 
     { 
      listb[i] = list[h]; // The next number in the merged array becomes h (initially low part). 
      h++; // Increment h to the next part of the array 
     } 
     else // Otherwise, 
     { 
      listb[i] = list[j]; // The next number in the merged array becomes j (initially upper middle). 
      j++; // Increment j to the next part of the array. 
     } 
     i++; // Always increment i, the position of the merged array. Starts at the bottom of the array. 
    } // End of while loop 

    if (h > mid) // If h - the progress from the bottom of the array - is beyond the middle. 
    { 
     for (k = j; k <= high; k++) // Loop until k is out of the array's range. 
     { 
      listb[i] = list[k]; // Set the next element in the merged array to the k element in the unmerged. 
      i++; // I.e. this starts from the middle, goes to the top of the array copying it into the merged one. 
     } 
    } 
    else // Otherwise, progress has not reached the the j value 
    { 
     for (k = h; k <= mid; k++) // K will start from h instead 
     { 
      listb[i] = list[k]; 
      i++; 
     } 
    } 
    // Then, 
    for (k = low; k <= high; k++) // Loop through the entire original array, copying the merged array into it. 
    { 
     list[k] = listb[k]; 
    } 

    return list; 
} 
}; 

和主:

#include "Mergesort.h" 
#include "Radixsort.h" 

// Import things we need from the standard library 
using std::chrono::duration_cast; 
using std::chrono::milliseconds; 
using std::cout; 
using std::endl; 
using std::this_thread::sleep_for; 

// Define the alias "the_clock" for the clock type we're going to use. 
// (You can change this to make the code below use a different clock.) 
typedef std::chrono::steady_clock the_clock; 

using namespace std; 

Mergesort mergeSorter; 
Radixsort radixSorter; 

void main() 
{ 
int num, i = 0, j = 0, k = 0; 
int inputNumber = 0; 

cout << "Please input the size of the list to sort, then press enter:" << endl; 
cin >> num; 

vector<int> intList(num); 

cout << endl << "Please enter a 1 for manual input or 2 for random generation between 0 and 99, then press enter:" << endl; 
while (j != 1 && j != 2) 
{ 
    cin >> j; 
    if (j != 1 && j != 2) 
    { 
     cout << "Please enter 1 or 2." << endl; 
    } 
    else 
    { 
     cout << endl; 
    } 
} 
if (j == 1) 
{ 
    cout << "Now, Please enter the " << num << " numbers, pressing enter between each:" << endl; 
    for (i = 0; i < num; i++) 
    { 
     cin >> inputNumber; 
     intList[i] = (inputNumber); 
    } 
} 
else if (j == 2) 
{ 
    for (i = 0; i < num; i++) 
    { 
     inputNumber = rand() % 100; 
     intList[i] = (inputNumber); 
    } 
    cout << "The list generated is: "; 
    for (std::vector<int>::iterator it = intList.begin(); it != intList.end(); it++) // Loops through the list, printing it out. 
    { 
     cout << *it << " "; 
    } 
    cout << endl << endl; 
} 

cout << endl << "Now, Please enter a 1 for merge sort or 2 for radix sort, then press enter:" << endl; 
while (k != 1 && k != 2) 
    { 
     cin >> k; 
     if (k != 1 && k != 2) 
     { 
      cout << "Please enter 1 or 2." << endl; 
     } 
    } 

if (k == 1) 
{ 
    intList = mergeSorter.mergeSort(intList, 1, num, num); 
    cout << endl << "So, the sorted list using merge sort will be:"; 
} 
else if (k == 2) 
{ 
    intList = radixSorter.radixSort(intList, num); 
    cout << endl << "So, the sorted list using radix sort will be:"; 
} 
cout << endl << endl; 

for (std::vector<int>::iterator it = intList.begin(); it != intList.end(); it++) // Loops through the list, printing it out. 
{ 
    cout << *it << " "; 
} 
cout << endl << endl; 
} 
+0

超出范围的异常将是调试器中捕获的*动态*东西。 – WhozCraig

+0

我们可以看到你如何调用mergeSort和什么参数。 – Surt

回答

0

参数Max从未使用过。通常,mergesort的正确索引是结束索引(比向量中的最后一个索引多一个索引)。在merge()中,将h和i设置为low-1会导致超出范围的问题,将它们都设置为低,而不是-1。由于合并拷贝回列表,然后归并和合并应该是使用用于参数参考空隙功能:

void mergeSort(std::vector<int> &list, int low, int high) 

void merge(std::vector<int> &list, int low, int mid, int high) 

在归并的主要代码应该是:

if ((high-low) > 1) // nothing to do if 0 or 1 elements 
    { // This will be when the given set is a single number. 
     mid = low + (high - low)/2; 
     mergeSort(list, low, mid); 
     mergeSort(list, mid, high); 
     merge(list, low, mid, high; 

在合并早期线路应:

h = low; 
    i = low; 
    j = mid; 

    while ((h < mid) && (j < high)) // change <= to < 

使用<其他行=应改为使用<。

的初始调用归并排序应该是:

mergeSort(std::vector<int> list, 0, list.size()); 

您可能需要使用的size_t的指标,而不是INT。

+0

干杯,我做了你的改变。我保持最大值,因为我用它来创建合并函数中的列表,这是我在停止崩溃时的初始尝试。 但它现在崩溃,调试似乎显示它无限循环mergesort函数的返回。有什么建议? –

+0

@DuncanBurgess - 我忘了提及,在mergesort()中第一个if应该是if((high - low)> 1)...。我更新了我的答案以表明这一点。 – rcgldr