C ++中的插入排序实现会导致多个错误

时间:2015-12-13 09:36:52

标签: c++ sorting

这是CodeBlocks 13.12上的控制台应用程序。

运行此插入排序时出现各种错误。

有时它会打印出原始数组中没有的大值。或者有时它会运行并对阵列进行排序。

任何人都可以指出可能出错的地方吗?对不起,我是个菜鸟。

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;    

void insertionSort(int arr[], int size);

int main()
{
    int size;
    srand(time(NULL));
    cout << "Specify the size of your array: ";
    cin >> size;
    int theArray[size]; // creates an array of a size the user chooses

    cout << endl << "Your current array: {";

    for (int i = 0; i < size; i++) //prints out the original array
    {
        theArray[i] = rand() % 10000;
        cout << theArray[i];

        if (i != size - 1) // to beautify output
        {
            cout << ", ";
        }
        if (i % 10 == 0 && i != 0)
        {
            cout << endl;
        }
    }
    cout << "}" << endl << endl;

    insertionSort(theArray, size);
}

void insertionSort(int arr[], int size)
{
    int begin = clock(); // are for timing the sort
    for (int i = 0; i < size; i++) //does the sorting
    {
        int j = i + 1;
        int temp = arr[j];

        while (arr[i] > arr[j])
        {
            arr[j] = arr[i];
            arr[i] = temp;
            j--;
            i--;
        }
    }
    int end = clock(); // are for timing the sort

    cout << endl << "Your sorted array is: {";

    for (int i = 0; i < size; i++) // prints out sorted array
    {
        cout << arr[i];
        if (i != size - 1)
        {
            cout << ", ";
        }
        if (i % 10 == 0 && i != 0)
        {
            cout << endl;
        }
    }

    cout << "}" << endl << endl << "Your sort took: " << end - begin << " milliseconds" << endl << endl;
}

4 个答案:

答案 0 :(得分:1)

至少这是错误的:

void insertionSort(int arr[], int size)
{
    int begin = clock(); // are for timing the sort
    for (int i = 0; i < size; i++) //does the sorting
    {
        int j = i + 1;

当i是size-1然后j等于size并且你越过数组的边界(有效值从0到size-1包括在内)。您需要将for循环限制为i&lt;大小-1

答案 1 :(得分:1)

除了@ marom的答案之外,在你的while循环中,你没有对 i j 施加限制,因此你试图访问arr [-1] ,arr [-2]等等。此外,您将返回到已排序数组的开头,因为您减少了 i 。看看这段用g ++ 4.8.1编译的代码没有错误。此外,尝试使用头文件<utility>中定义的std :: swap,从c ++ 11开始,或者在头文件<algorithm>中使用,直到c ++ 11。

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <utility>

using namespace std;    

void insertionSort(int arr[], int size);

int main()
{
    int size;
    srand(time(NULL));
    cout << "Specify the size of your array: ";
    cin >> size;
    int theArray[size]; // creates an array of a size the user chooses

    cout << endl << "Your current array: {";

    for (int i = 0; i < size; i++) //prints out the original array
    {
        theArray[i] = rand() % 10000;
        cout << theArray[i];

        if (i != size - 1) // to beautify output
        {
            cout << ", ";
        }
        if (i % 10 == 0 && i != 0)
        {
            cout << endl;
        }
    }
    cout << "}" << endl << endl;

    insertionSort(theArray, size);
}

void insertionSort(int arr[], int size)
{
    int begin = clock(); // are for timing the sort
    for (int i = 0; i < size - 1; i++) //does the sorting
    {
        int j = i + 1;
        int temp = arr[j];

        while (j > 0 && arr[j] < arr[j - 1])
        {
            // ^^ this ensures that we don't try to access arr[-1]
            swap(arr[j], arr[j-1]); //prefer std functions if they do the job you want
            j--;//we don't go back
        }
    }
    int end = clock(); // are for timing the sort

    cout << endl << "Your sorted array is: {";

    for (int i = 0; i < size; i++) // prints out sorted array
    {
        cout << arr[i];
        if (i != size - 1)
        {
            cout << ", ";
        }
        if (i % 10 == 0 && i != 0)
        {
            cout << endl;
        }
    }

    cout << "}" << endl << endl << "Your sort took: " << end - begin << " milliseconds" << endl << endl;
}

答案 2 :(得分:0)

第一条建议:不要在排序功能中执行所有打印或时钟测量。保留主程序。您的排序功能必须保持清晰简洁,没有副作用。 现在,我发现将代码分成两个简单的函数会更好:

首先,如果假设arr已经对索引n-1进行了排序 你想在pos偏移处插入适当的元素元素 arr将被分类到索引n:

void insert(int arr[], int n){
 int i=n, temp=arr[n];
 while ( (arr[i-1]>temp) && (i>0) ) 
    {
     arr[i]=arr[i-1];
     i--;
    }
 arr[i]=temp;
}

现在我们只需要为arr中的所有偏移调用我们的插入,除了第一个:

void insertionSort(int arr[], int size)
{
 for(int n=1; n<size; n++) insert(arr,n);
}

答案 3 :(得分:0)

正如marom在他的回答中已经提到的,当i = size - 1设置j = size并且访问内存超出范围时,同样地,考虑将j设置为最小元素的情况。在这种情况下,你通过交换元素并递减来到达数组最左边的位置,最终i将变为负数(因为你没有设置检查i是否变为小于0),j也是如此,你将再次访问你的界限。

此外,你也减少了i的值,这是没有意义的,因为通过递减i的值,你正在为外部for循环进行额外的运行

所以,你的函数看起来像这样::

for (int i = 0; i < size - 1; i++) //changed the limit of for loop
{
    int j = i + 1;
    int temp = arr[j];

    while ((j > 0) && (arr[j - 1] > arr[j])) //instead of working with the values of i, now we are doing everything with j
    {
        arr[j] = arr[j - 1];
        arr[j - 1] = temp;
        j--;
    }
}

希望这有帮助!