这是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;
}
答案 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--;
}
}
希望这有帮助!