我已经实现了插入排序,我猜它很好。它从文件读取并正确排序它们输入10,100,1000,10000,10000。
然而,当我给出一百万输入时,它什么也没做。我甚至等了10分钟检查它是否太慢了 我动态创建了我的数组,并尝试合并排序。一百万次输入完全正常工作但我无法理解为什么只有插入排序算法不能用百万输入。这是代码的一部分完成工作;
#include <iostream>
#include <fstream>
using namespace std;
void InsertionSort(int* array, int& size);
int main()
{
int size;
ifstream myfile("data.txt");
myfile.open("data.txt");
cout << "How many elements do you want to read" << endl;
cin >> size;
int* array = new int[size];
for (int i = 0; i < size; i++) {
myfile >> array[i];
}
InsertionSort(array, size);
delete[] array;
}
void InsertionSort(int* array, int& size)
{
int temp, j;
for (int i = 1; i < size; i++) {
j = i;
while (j > 0 && array[j - 1] > array[j]) {
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
j--;
}
}
}
答案 0 :(得分:8)
你的程序在O(n²)时间内运行,因为你有两个嵌套循环,它们都取决于输入的大小。因此,一旦你从10,000到1,000,000个元素,你的程序将需要100²=一万倍的时间来完成。此外,您的数据集之前可能适合处理器的缓存,但它不再使用100万个元素,因此这会使速度更慢。
O(n²)算法使得事情变得非常缓慢。输入大小为10⁶,这意味着您的程序将完成10¹的操作。假设您的处理器最多以每秒10⁹的运算速度运行,并且您的算法每步将确实使用多个操作,则程序完成所需的时间将超过10³秒。
答案 1 :(得分:0)
在最坏的情况下,合并排序为O(n lg(n)),插入排序平均为二次方(不仅在最坏的情况下)。
差异很大。
假设你有两个算法,A和B.
对于任何大小为n的输入,A采用n 2 运算,而B采用n * lg(n)运算。
如果你输入加倍,算法A需要(2n) 2 = 4n 2 操作 - 这是四倍。
B取2n * lg(2n)= 2n *(lg(n)+ 1)= 2n * lg(n)+ 2 = 2(n * lg(n)+ 1),这只是一点点超过两倍多。
为了说明从10,000到1,000,000个元素的区别(为简单起见使用十个对数):
10,000 * 10,000 = 100,000,000
1,000,000 * 1,000,000 = 1,000,000,000,000
这是10,000倍。
10,000 * log(10,000) = 40,000
1,000,000 * log(1,000,000) = 6,000,000
那是150倍。
因此,如果一万个案例花费大约相同的时间,插入排序将比百万案例的合并排序花费更长时间,这并不意外。