不同的排序算法在大型数组上失败
Different sorting algorithms fail on large arrays
我正在尝试使用不同的算法对数组进行排序。当我 运行 具有少量数组的应用程序时,它会工作并产生结果。当数组大于:131072 时,它停止响应。
可能是什么原因?这段代码有什么问题吗?
这是我的功能:
boolean runTest(String[] text, int[] number, String url, String out, Sort sort) {
PrintWriter filename;
boolean tobeReturned = true;
String beforeSorting = "";
String afterSorting = "";
long startTime;
double timeTaken;
try {
filename = createWriter(out);
for(File directory : new File(url).listFiles()){
File[] listOfFiles = directory.listFiles();
filename.println("Number of Records: \t" + directory.getName());
for (File file : listOfFiles) {
text = loadStrings(file);
number = int(text);
if (isSorted(number)) { beforeSorting = "Sorted";} else { beforeSorting = "NOT Sorted"; };
startTime = startTime();
sort.sortInteger(number);
timeTaken = stopTime(startTime);
if (isSorted(number)) { afterSorting = "Sorted"; } else { afterSorting = "NOT Sorted"; };
filename.println("File Set " + file.getName() + ": \t\t" + beforeSorting + ": \t" + afterSorting + ": \t" + timeTaken);
timeTaken = 0;
}
filename.println("\n");
}
filename.flush();
filename.close();
}
catch (Exception e) {
tobeReturned = false;
}
return tobeReturned;
}
接口:
interface Sort{
public int[] sortInteger(int[] input);
}
排序之一class(插入)
class Insertion implements Sort{
Insertion() {
}
int[] sortInteger(int[] input) {
int i, j, tobeSorted;
for (i = 1; i < input.length; i++) {
tobeSorted = input[i];
j = i;
while (j > 0 && input[j - 1] > tobeSorted) {
input[j] = input[j - 1];
j--;
}
input[j] = tobeSorted;
}
//println(input);
return input;
}
}
Numbers 文件夹:
文件:
记录:
插入排序结果:
归并排序结果:
******更新******
完整的简化处理代码
import java.util.*;
long a = 9; // total loop, 9 means = 65536, 10 means = 131072 ...
long b = 2; // multiplier, 2 means = 512,1024,2048...
long c = 512; // starting number
long d = 5; // times random text file
String url;
Insertion insertion;
Merge merge;
Bubble bubble;
Shell shell;
QuickSort quickSort;
void setup() {
url = sketchPath("_numbers/");
insertion = new Insertion();
merge = new Merge();
bubble = new Bubble();
shell = new Shell();
quickSort = new QuickSort();
generateFiles(a,b,c,d);
boolean runSortTest = false;
runSortTest = runTest(url, "_results/a_insertion.txt", insertion);
runSortTest = runTest(url, "_results/b_merge.txt", merge);
runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
runSortTest = runTest(url, "_results/d_shell.txt", shell);
runSortTest = runTest(url, "_results/e_quickSort.txt", quickSort);
if(runSortTest){
println("Done");
}else{
println("Error");
}
}
boolean generateFiles(long totalLoop, long multiplier, long power, long fileNumber){
PrintWriter pw;
//int orderCount = 1;
int count = 1;
//boolean tobeReturned = true;
try {
for (int i = 1; i < totalLoop; i = i+1) {
for (int j = 1; j < fileNumber+1; j = j+1) {
pw = createWriter("/_numbers/" + power + "/" + count + ".txt");
for (int k = 0; k < power; k = k+1) {
pw.println(randomNumber(0, power));
//pw.write(int(randomNumber(0, power)) + "\t");
}
count++;
pw.flush(); // Writes the remaining data to the file
pw.close(); // Finishes the file
}
count = 1;
//orderCount++;
power *= multiplier;
}
//orderCount = 1;
return true;
} catch (Exception e) {
return false;
}
}
long randomNumber(long min, long max){
long randomN = (long)random(min,(max + 1));
return randomN;
}
//####################################################################################################
//## Runs the test and produces a log file for each algorithms
//####################################################################################################
boolean runTest(String url, String out, Sort sort) {
PrintWriter filename;
boolean tobeReturned = true;
String beforeSorting = "";
String afterSorting = "";
long startTime;
double timeTaken;
try {
filename = createWriter(out);
for(File directory : new File(url).listFiles()){
File[] listOfFiles = directory.listFiles();
filename.println("Number of Records: \t" + directory.getName());
for (File file : listOfFiles) {
String[] text; int[] number;
text = loadStrings(file);
number = int(text);
if (isSorted(number)) { beforeSorting = "Sorted";} else { beforeSorting = "NOT Sorted"; };
startTime = startTime();
sort.sortInteger(number);
timeTaken = stopTime(startTime);
if (isSorted(number)) { afterSorting = "Sorted"; } else { afterSorting = "NOT Sorted"; };
filename.println("File Set " + file.getName() + ": \t\t" + beforeSorting + ": \t" + afterSorting + ": \t" + timeTaken);
timeTaken = 0;
Arrays.fill(text, null);
number = null;
}
filename.println("\n");
}
filename.flush();
filename.close();
}
catch (Exception e) {
e.printStackTrace();
tobeReturned = false;
}
return tobeReturned;
}
boolean isSorted(int[] array) {
for (int i = 0; i < array.length-1; i ++) {
if (array[i] > array[i+1]) {
return false;
}
}
return true;
}
//####################################################################################################
//## Time comparison
//####################################################################################################
long startTime() {
return System.nanoTime();
}
double stopTime(long startTime) {
double finalTime = (System.nanoTime() - startTime)/1000000000.0;
return finalTime;
}
/*
Interface
# Last update: 20 October 2015
*/
interface Sort{
public int[] sortInteger(int[] input);
}
/*
Insertion class, implements Sort interface
# Last update: 25 October 2015
*/
class Insertion implements Sort{
Insertion() {
}
int[] sortInteger(int[] input) {
int i, j, tobeSorted;
for (i = 1; i < input.length; i++) {
tobeSorted = input[i];
j = i;
while (j > 0 && input[j - 1] > tobeSorted) {
input[j] = input[j - 1];
j--;
}
input[j] = tobeSorted;
}
//println(input);
return input;
}
}
/*
Merge class, implements Sort interface
# Last update: 25 October 2015
*/
class Merge implements Sort{
Merge() {
}
int[] sortInteger(int[] input) {
if (input.length > 1) {
// split array into two halves
int[] left = leftHalf(input);
int[] right = rightHalf(input);
// recursively sort the two halves
sortInteger(left);
sortInteger(right);
// merge the sorted halves into a sorted whole
merge(input, left, right);
}
return input;
}
// Returns the first half of the given array.
int[] leftHalf(int[] array) {
int size1 = array.length / 2;
int[] left = new int[size1];
for (int i = 0; i < size1; i++) {
left[i] = array[i];
}
return left;
}
// Returns the second half of the given array.
int[] rightHalf(int[] array) {
int size1 = array.length / 2;
int size2 = array.length - size1;
int[] right = new int[size2];
for (int i = 0; i < size2; i++) {
right[i] = array[i + size1];
}
return right;
}
void merge(int[] result, int[] left, int[] right) {
int i1 = 0; // index into left array
int i2 = 0; // index into right array
for (int i = 0; i < result.length; i++) {
if (i2 >= right.length || (i1 < left.length &&
left[i1] <= right[i2])) {
result[i] = left[i1]; // take from left
i1++;
} else {
result[i] = right[i2]; // take from right
i2++;
}
}
}
}
/*
Bubble class, implements Sort interface
# Last update: 25 October 2015
*/
class Bubble implements Sort {
Bubble() {
}
int[] sortInteger(int[] input) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < input.length - j; i++) {
if (input[i] > input[i + 1]) {
tmp = input[i];
input[i] = input[i + 1];
input[i + 1] = tmp;
swapped = true;
}
}
}
return input;
}
}
/*
Shell class, implements Sort interface
# Last update: 25 October 2015
*/
class Shell implements Sort {
Shell() {
}
int[] sequence = {59724292, 26544130, 11797391, 5243258, 2330349, 1035711, 460316, 204585, 90927, 40412, 17961, 7983, 3548, 1577, 701, 301, 132, 57, 23, 10, 4, 1};
/*
int number = 701;
for(int i=0; i<15; i++){
int newN = int(number*2.25);
println(number);
number = newN;
}
*/
int[] sortInteger (int[] input) {
int size = input.length;
int i, j, temp;
for ( int s : sequence ) {
i = s;
while ( i < size ) {
temp = input[i];
j = i-s;
while ( j >= 0 && input[j] > temp ) {
input[j + s] = input[j];
j -= s;
}
input[j + s] = temp;
i ++;
}
}
return input;
}
}
/*
QuickSort class, implements Sort interface
# Last update: 26 October 2015
*/
class QuickSort implements Sort {
QuickSort() {
}
int[] sortInteger(int[] input) {
quickSort(input, 0, input.length-1) ;
return input;
}
public void quickSort(int arr[], int low, int high)
{
int i = low, j = high;
int temp;
int pivot = arr[(low + high) / 2];
/** partition **/
while (i <= j)
{
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j)
{
/** swap **/
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
/** recursively sort lower half **/
if (low < j)
quickSort(arr, low, j);
/** recursively sort upper half **/
if (i < high)
quickSort(arr, i, high);
}
}
解决这个问题的第一步是隔离问题。这就是我们要求 MCVE 时的意思。您必须准确找出问题发生的位置。一种简单的方法是添加 println()
语句:
boolean runSortTest = false;
println("1");
runSortTest = runTest(url, "_results/a_insertion.txt", insertion);
println("2");
runSortTest = runTest(url, "_results/b_merge.txt", merge);
println("3");
runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
println("4");
runSortTest = runTest(url, "_results/d_shell.txt", shell);
println("5");
runSortTest = runTest(url, "_results/e_quickSort.txt", quickSort);
println("6");
这样做,我们会看到 1、2 和 3 被打印出来,但 4、5 和 6 没有。这意味着你在某个地方陷入了冒泡排序。我们可以通过注释掉冒泡排序并查看会发生什么来确认:
boolean runSortTest = false;
println("1");
runSortTest = runTest(url, "_results/a_insertion.txt", insertion);
println("2");
runSortTest = runTest(url, "_results/b_merge.txt", merge);
println("3");
//runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
println("4");
runSortTest = runTest(url, "_results/d_shell.txt", shell);
println("5");
runSortTest = runTest(url, "_results/e_quickSort.txt", quickSort);
println("6");
现在,程序可以正常执行了。所以现在我们已经知道问题出在冒泡排序上,所以我们可以摆脱其他一切:
import java.util.*;
long a = 9; // total loop, 9 means = 65536, 10 means = 131072 ...
long b = 2; // multiplier, 2 means = 512,1024,2048...
long c = 512; // starting number
long d = 5; // times random text file
String url;
Bubble bubble;
void setup() {
url = sketchPath("_numbers/");
bubble = new Bubble();
generateFiles(a, b, c, d);
boolean runSortTest = false;
runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
if (runSortTest) {
println("Done");
} else {
println("Error");
}
}
boolean generateFiles(long totalLoop, long multiplier, long power, long fileNumber) {
PrintWriter pw;
//int orderCount = 1;
int count = 1;
//boolean tobeReturned = true;
try {
for (int i = 1; i < totalLoop; i = i+1) {
for (int j = 1; j < fileNumber+1; j = j+1) {
pw = createWriter("/_numbers/" + power + "/" + count + ".txt");
for (int k = 0; k < power; k = k+1) {
pw.println(randomNumber(0, power));
//pw.write(int(randomNumber(0, power)) + "\t");
}
count++;
pw.flush(); // Writes the remaining data to the file
pw.close(); // Finishes the file
}
count = 1;
//orderCount++;
power *= multiplier;
}
//orderCount = 1;
return true;
}
catch (Exception e) {
return false;
}
}
long randomNumber(long min, long max) {
long randomN = (long)random(min, (max + 1));
return randomN;
}
//####################################################################################################
//## Runs the test and produces a log file for each algorithms
//####################################################################################################
boolean runTest(String url, String out, Sort sort) {
PrintWriter filename;
boolean tobeReturned = true;
String beforeSorting = "";
String afterSorting = "";
long startTime;
double timeTaken;
try {
filename = createWriter(out);
for (File directory : new File(url).listFiles()) {
File[] listOfFiles = directory.listFiles();
filename.println("Number of Records: \t" + directory.getName());
for (File file : listOfFiles) {
String[] text;
int[] number;
text = loadStrings(file);
number = int(text);
if (isSorted(number)) {
beforeSorting = "Sorted";
} else {
beforeSorting = "NOT Sorted";
};
startTime = startTime();
sort.sortInteger(number);
timeTaken = stopTime(startTime);
if (isSorted(number)) {
afterSorting = "Sorted";
} else {
afterSorting = "NOT Sorted";
};
filename.println("File Set " + file.getName() + ": \t\t" + beforeSorting + ": \t" + afterSorting + ": \t" + timeTaken);
timeTaken = 0;
Arrays.fill(text, null);
number = null;
}
filename.println("\n");
}
filename.flush();
filename.close();
}
catch (Exception e) {
e.printStackTrace();
tobeReturned = false;
}
return tobeReturned;
}
boolean isSorted(int[] array) {
for (int i = 0; i < array.length-1; i ++) {
if (array[i] > array[i+1]) {
return false;
}
}
return true;
}
//####################################################################################################
//## Time comparison
//####################################################################################################
long startTime() {
return System.nanoTime();
}
double stopTime(long startTime) {
double finalTime = (System.nanoTime() - startTime)/1000000000.0;
return finalTime;
}
/*
Interface
# Last update: 20 October 2015
*/
interface Sort {
public int[] sortInteger(int[] input);
}
/*
Bubble class, implements Sort interface
# Last update: 25 October 2015
*/
class Bubble implements Sort {
Bubble() {
}
int[] sortInteger(int[] input) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < input.length - j; i++) {
if (input[i] > input[i + 1]) {
tmp = input[i];
input[i] = input[i + 1];
input[i + 1] = tmp;
swapped = true;
}
}
}
return input;
}
}
这可能会进一步缩短,但想法是这样的:删除与问题没有直接关系的任何内容。
现在我们已经删除了一些额外的信息,我们可以仔细看看您的冒泡排序。同样,println()
语句是您最好的朋友:
int[] sortInteger(int[] input) {
println("input length: " + input.length);
使用这个,可以看到确实还是运行ning,因为打印出来的是:
input length: 1024
input length: 1024
input length: 1024
input length: 1024
input length: 1024
input length: 16384
input length: 16384
input length: 16384
input length: 16384
input length: 16384
input length: 2048
input length: 2048
input length: 2048
input length: 2048
input length: 2048
input length: 32768
input length: 32768
input length: 32768
input length: 32768
input length: 32768
input length: 4096
input length: 4096
input length: 4096
input length: 4096
input length: 4096
input length: 512
input length: 512
input length: 512
input length: 512
input length: 512
input length: 65536
input length: 65536
input length: 65536
input length: 65536
input length: 65536
input length: 8192
input length: 8192
input length: 8192
input length: 8192
input length: 8192
Done
事实上:这很好,你只需要给它几分钟。这是我在 c_bubble.txt
:
中得到的输出
记录数:1024
File Set 1.txt: NOT Sorted: Sorted: 0.009598049335181713
File Set 2.txt: NOT Sorted: Sorted: 0.0011289309477433562
File Set 3.txt: NOT Sorted: Sorted: 0.0026859149802476168
File Set 4.txt: NOT Sorted: Sorted: 0.002715847920626402
File Set 5.txt: NOT Sorted: Sorted: 0.0015163590433076024
Number of Records: 16384
File Set 1.txt: NOT Sorted: Sorted: 0.38029658794403076
File Set 2.txt: NOT Sorted: Sorted: 0.37928950786590576
File Set 3.txt: NOT Sorted: Sorted: 0.3931492865085602
File Set 4.txt: NOT Sorted: Sorted: 0.3918215036392212
File Set 5.txt: NOT Sorted: Sorted: 0.38513386249542236
Number of Records: 2048
File Set 1.txt: NOT Sorted: Sorted: 0.0040453351102769375
File Set 2.txt: NOT Sorted: Sorted: 0.0041389851830899715
File Set 3.txt: NOT Sorted: Sorted: 0.004071420058608055
File Set 4.txt: NOT Sorted: Sorted: 0.004472961183637381
File Set 5.txt: NOT Sorted: Sorted: 0.0041146110743284225
Number of Records: 32768
File Set 1.txt: NOT Sorted: Sorted: 1.6499463319778442
File Set 2.txt: NOT Sorted: Sorted: 1.6393990516662598
File Set 3.txt: NOT Sorted: Sorted: 1.628066897392273
File Set 4.txt: NOT Sorted: Sorted: 1.6488127708435059
File Set 5.txt: NOT Sorted: Sorted: 1.6586071252822876
Number of Records: 4096
File Set 1.txt: NOT Sorted: Sorted: 0.0184687077999115
File Set 2.txt: NOT Sorted: Sorted: 0.018312623724341393
File Set 3.txt: NOT Sorted: Sorted: 0.018741531297564507
File Set 4.txt: NOT Sorted: Sorted: 0.01845288649201393
File Set 5.txt: NOT Sorted: Sorted: 0.018356671556830406
Number of Records: 512
File Set 1.txt: NOT Sorted: Sorted: 3.81015008315444E-4
File Set 2.txt: NOT Sorted: Sorted: 3.322649863548577E-4
File Set 3.txt: NOT Sorted: Sorted: 3.3953398815356195E-4
File Set 4.txt: NOT Sorted: Sorted: 3.314100031275302E-4
File Set 5.txt: NOT Sorted: Sorted: 3.42526996973902E-4
Number of Records: 65536
File Set 1.txt: NOT Sorted: Sorted: 6.721750736236572
File Set 2.txt: NOT Sorted: Sorted: 6.752647399902344
File Set 3.txt: NOT Sorted: Sorted: 6.7578630447387695
File Set 4.txt: NOT Sorted: Sorted: 6.696788787841797
File Set 5.txt: NOT Sorted: Sorted: 6.759160995483398
Number of Records: 8192
File Set 1.txt: NOT Sorted: Sorted: 0.08915259689092636
File Set 2.txt: NOT Sorted: Sorted: 0.09149085730314255
File Set 3.txt: NOT Sorted: Sorted: 0.0899868980050087
File Set 4.txt: NOT Sorted: Sorted: 0.08892638236284256
File Set 5.txt: NOT Sorted: Sorted: 0.08631659299135208
现在我们知道您的冒泡排序已完成,让我们回头看看整个事情是否完成。是的,确实如此:
这完成得很好,似乎提供了结果。
我猜你实际上没有问题,但你希望草图能做一些视觉上的事情,而不是只给你一个灰色的框。但是由于您没有 draw()
函数,您只会看到一个灰色框。如果您不想弹出 window,请尝试在 setup()
函数末尾添加对 exit()
的调用。
如果您仍然认为它不起作用,请考虑以下事项:
- 添加更多打印语句,以便您可以更好地查看代码中发生的情况。
- 检查文件的输出目录。
- 请注意,由于您没有
draw()
函数,您的程序不会执行任何可视化操作,所以它所做的只是显示一个灰色框。 这并不意味着您的程序没有响应!这只是意味着您没有告诉它做任何事情。考虑在 setup()
函数的末尾添加对 exit()
的调用。
- 如果一切都失败了,请尝试通过上述过程隔离问题。尝试将其缩小到几条不符合您预期的线条,而不是整个草图。
编辑
您提到您得到了类似的结果,并且您只是在增加输入大小时才看到问题。 这正是您所期望的。
同样,添加打印语句是您最好的朋友。让我们从插入排序开始:
int[] sortInteger(int[] input) {
println("input length: " + input.length);
这将显示您的输入长度为 1,048,576。由于插入排序是 O(n^2),这意味着您必须进行 1,048,576 ^ 2 次比较。那是 1,099,511,627,776 次比较!假设您的计算机每秒可以进行 1,000 次比较,完成此算法需要 34 年。
(你的电脑大概每秒可以做1000多次比较,但是如果它每秒可以做100万次比较,它仍然需要12天才能完成。如果它每秒可以进行10亿次比较,它会需要 18 分钟,这只是一个算法的单个 运行。)
为了进一步调查这一点,println()
语句是您最好的朋友。尝试在插入排序循环中添加一个 println()
语句来显示 i
的值:
int i, j, tobeSorted;
for (i = 1; i < input.length; i++) {
tobeSorted = input[i];
j = i;
while (j > 0 && input[j - 1] > tobeSorted) {
input[j] = input[j - 1];
j--;
}
input[j] = tobeSorted;
println("i: " + i);
}
作为您的程序 运行s,您会看到这个数字在上升。即使计算机速度很快,处理您的全部输入仍然需要很长时间。这告诉您您的程序没有挂起,只是需要很长时间才能执行。
这就是研究这些算法的全部意义。计算机不是神奇的计算器,它们在合理的时间内可以完成的计算次数是有限的.这就是为什么你的算法是线性缩放还是指数缩放很重要:将输入大小加倍是需要两倍的时间,还是需要指数级的更长?
如果您仍然不相信结果,请继续尝试找出问题所在。当您认为程序“只是坐在那里”时,请尝试弄清楚您的程序到底在做什么。你应该确切地知道你的程序需要做多少计算,然后打印出到目前为止已经完成了多少计算。换句话说:打印出循环应该执行的次数,然后打印出循环到目前为止执行的次数。你会看到第一个值有多大,然后第二个值达到它需要多长时间。
编辑 2
这是草图的简化版本,可让您更轻松地更改输入的长度,以更“简洁”的方式获得不同算法的特定时间:
void setup() {
int[] input = getInput(1000);
int start = millis();
bubbleSort(input);
int elapsed = millis() - start;
println("Elapsed: " + elapsed);
exit();
}
int[] getInput(int n) {
int[] input = new int[n];
for (int i = 0; i < n; i++) {
input[i] = (int)random(n);
}
return input;
}
int[] bubbleSort(int[] input) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < input.length - j; i++) {
if (input[i] > input[i + 1]) {
tmp = input[i];
input[i] = input[i + 1];
input[i + 1] = tmp;
swapped = true;
}
}
}
return input;
}
只需更改传递给 getInput()
函数的值,您就可以看到它如何影响算法完成所需的时间。
这是冒泡排序:
N: 1,000 Time: 7
N: 10,000 Time: 145
N: 100,000 Time: 14600
N: 1,000,000 Time: 1467533
所以您看到将输入大小乘以 10 不会将您的时间乘以 10,它会乘以 100。这是因为冒泡排序是 O(n^2),所以它花费的时间呈二次方增长,而不仅仅是线性增长。如果我们尝试将 N 增加到 10,000,000,冒泡排序将需要大约 40 个小时!
归并排序更宽容,因为它是 O(n*log(n)):
N: 1,000 Time: 1
N: 10,000 Time: 5
N: 100,000 Time: 38
N: 1,000,000 Time: 221
N: 10,000,000 Time: 2202
这是在这里学到的重要一课:冒泡排序需要 40 个小时来排序 1000 万个项目,但合并排序只需要 2 秒!
所以大输入需要很长时间来排序的事实正是要点。这不是错误。您的程序没有挂起,只是需要很长时间才能对那么多项目进行排序。尝试像我的示例一样将您的问题分解成更小的草图,这样您就可以更轻松地仔细观察它到底在做什么。然后添加 println()
语句以查看您的程序将时间花在哪里。 这就是您解决问题的方法。
编辑 3
现在您提到您在任务管理器中收到“未响应”消息。同样,这正是我所期望的。您告诉 Processing 进行大量计算,虽然这些计算是 运行ning,但程序不会响应。大量输入可能需要数小时(或数天,甚至更长!)才能完成。因此,您的程序不会在一夜之间完成并且 OS 表示它没有响应,这一点也不让我感到惊讶。这就是 threads 的想法变得有用的地方,但那是一个完全独立的蠕虫罐头。
如果您仍然遇到问题,请考虑使用我的小示例来重复该问题,然后您将能够提出更具体的问题(在一个新问题中,而不是在对这个问题的编辑中)。确保包括您正在使用的精确排序算法、您正在使用的 N 值以及程序是否仍在执行或是否已抛出错误。同样,println()
语句是您最好的朋友。
我正在尝试使用不同的算法对数组进行排序。当我 运行 具有少量数组的应用程序时,它会工作并产生结果。当数组大于:131072 时,它停止响应。
可能是什么原因?这段代码有什么问题吗?
这是我的功能:
boolean runTest(String[] text, int[] number, String url, String out, Sort sort) {
PrintWriter filename;
boolean tobeReturned = true;
String beforeSorting = "";
String afterSorting = "";
long startTime;
double timeTaken;
try {
filename = createWriter(out);
for(File directory : new File(url).listFiles()){
File[] listOfFiles = directory.listFiles();
filename.println("Number of Records: \t" + directory.getName());
for (File file : listOfFiles) {
text = loadStrings(file);
number = int(text);
if (isSorted(number)) { beforeSorting = "Sorted";} else { beforeSorting = "NOT Sorted"; };
startTime = startTime();
sort.sortInteger(number);
timeTaken = stopTime(startTime);
if (isSorted(number)) { afterSorting = "Sorted"; } else { afterSorting = "NOT Sorted"; };
filename.println("File Set " + file.getName() + ": \t\t" + beforeSorting + ": \t" + afterSorting + ": \t" + timeTaken);
timeTaken = 0;
}
filename.println("\n");
}
filename.flush();
filename.close();
}
catch (Exception e) {
tobeReturned = false;
}
return tobeReturned;
}
接口:
interface Sort{
public int[] sortInteger(int[] input);
}
排序之一class(插入)
class Insertion implements Sort{
Insertion() {
}
int[] sortInteger(int[] input) {
int i, j, tobeSorted;
for (i = 1; i < input.length; i++) {
tobeSorted = input[i];
j = i;
while (j > 0 && input[j - 1] > tobeSorted) {
input[j] = input[j - 1];
j--;
}
input[j] = tobeSorted;
}
//println(input);
return input;
}
}
Numbers 文件夹:
文件:
记录:
插入排序结果:
归并排序结果:
******更新******
完整的简化处理代码
import java.util.*;
long a = 9; // total loop, 9 means = 65536, 10 means = 131072 ...
long b = 2; // multiplier, 2 means = 512,1024,2048...
long c = 512; // starting number
long d = 5; // times random text file
String url;
Insertion insertion;
Merge merge;
Bubble bubble;
Shell shell;
QuickSort quickSort;
void setup() {
url = sketchPath("_numbers/");
insertion = new Insertion();
merge = new Merge();
bubble = new Bubble();
shell = new Shell();
quickSort = new QuickSort();
generateFiles(a,b,c,d);
boolean runSortTest = false;
runSortTest = runTest(url, "_results/a_insertion.txt", insertion);
runSortTest = runTest(url, "_results/b_merge.txt", merge);
runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
runSortTest = runTest(url, "_results/d_shell.txt", shell);
runSortTest = runTest(url, "_results/e_quickSort.txt", quickSort);
if(runSortTest){
println("Done");
}else{
println("Error");
}
}
boolean generateFiles(long totalLoop, long multiplier, long power, long fileNumber){
PrintWriter pw;
//int orderCount = 1;
int count = 1;
//boolean tobeReturned = true;
try {
for (int i = 1; i < totalLoop; i = i+1) {
for (int j = 1; j < fileNumber+1; j = j+1) {
pw = createWriter("/_numbers/" + power + "/" + count + ".txt");
for (int k = 0; k < power; k = k+1) {
pw.println(randomNumber(0, power));
//pw.write(int(randomNumber(0, power)) + "\t");
}
count++;
pw.flush(); // Writes the remaining data to the file
pw.close(); // Finishes the file
}
count = 1;
//orderCount++;
power *= multiplier;
}
//orderCount = 1;
return true;
} catch (Exception e) {
return false;
}
}
long randomNumber(long min, long max){
long randomN = (long)random(min,(max + 1));
return randomN;
}
//####################################################################################################
//## Runs the test and produces a log file for each algorithms
//####################################################################################################
boolean runTest(String url, String out, Sort sort) {
PrintWriter filename;
boolean tobeReturned = true;
String beforeSorting = "";
String afterSorting = "";
long startTime;
double timeTaken;
try {
filename = createWriter(out);
for(File directory : new File(url).listFiles()){
File[] listOfFiles = directory.listFiles();
filename.println("Number of Records: \t" + directory.getName());
for (File file : listOfFiles) {
String[] text; int[] number;
text = loadStrings(file);
number = int(text);
if (isSorted(number)) { beforeSorting = "Sorted";} else { beforeSorting = "NOT Sorted"; };
startTime = startTime();
sort.sortInteger(number);
timeTaken = stopTime(startTime);
if (isSorted(number)) { afterSorting = "Sorted"; } else { afterSorting = "NOT Sorted"; };
filename.println("File Set " + file.getName() + ": \t\t" + beforeSorting + ": \t" + afterSorting + ": \t" + timeTaken);
timeTaken = 0;
Arrays.fill(text, null);
number = null;
}
filename.println("\n");
}
filename.flush();
filename.close();
}
catch (Exception e) {
e.printStackTrace();
tobeReturned = false;
}
return tobeReturned;
}
boolean isSorted(int[] array) {
for (int i = 0; i < array.length-1; i ++) {
if (array[i] > array[i+1]) {
return false;
}
}
return true;
}
//####################################################################################################
//## Time comparison
//####################################################################################################
long startTime() {
return System.nanoTime();
}
double stopTime(long startTime) {
double finalTime = (System.nanoTime() - startTime)/1000000000.0;
return finalTime;
}
/*
Interface
# Last update: 20 October 2015
*/
interface Sort{
public int[] sortInteger(int[] input);
}
/*
Insertion class, implements Sort interface
# Last update: 25 October 2015
*/
class Insertion implements Sort{
Insertion() {
}
int[] sortInteger(int[] input) {
int i, j, tobeSorted;
for (i = 1; i < input.length; i++) {
tobeSorted = input[i];
j = i;
while (j > 0 && input[j - 1] > tobeSorted) {
input[j] = input[j - 1];
j--;
}
input[j] = tobeSorted;
}
//println(input);
return input;
}
}
/*
Merge class, implements Sort interface
# Last update: 25 October 2015
*/
class Merge implements Sort{
Merge() {
}
int[] sortInteger(int[] input) {
if (input.length > 1) {
// split array into two halves
int[] left = leftHalf(input);
int[] right = rightHalf(input);
// recursively sort the two halves
sortInteger(left);
sortInteger(right);
// merge the sorted halves into a sorted whole
merge(input, left, right);
}
return input;
}
// Returns the first half of the given array.
int[] leftHalf(int[] array) {
int size1 = array.length / 2;
int[] left = new int[size1];
for (int i = 0; i < size1; i++) {
left[i] = array[i];
}
return left;
}
// Returns the second half of the given array.
int[] rightHalf(int[] array) {
int size1 = array.length / 2;
int size2 = array.length - size1;
int[] right = new int[size2];
for (int i = 0; i < size2; i++) {
right[i] = array[i + size1];
}
return right;
}
void merge(int[] result, int[] left, int[] right) {
int i1 = 0; // index into left array
int i2 = 0; // index into right array
for (int i = 0; i < result.length; i++) {
if (i2 >= right.length || (i1 < left.length &&
left[i1] <= right[i2])) {
result[i] = left[i1]; // take from left
i1++;
} else {
result[i] = right[i2]; // take from right
i2++;
}
}
}
}
/*
Bubble class, implements Sort interface
# Last update: 25 October 2015
*/
class Bubble implements Sort {
Bubble() {
}
int[] sortInteger(int[] input) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < input.length - j; i++) {
if (input[i] > input[i + 1]) {
tmp = input[i];
input[i] = input[i + 1];
input[i + 1] = tmp;
swapped = true;
}
}
}
return input;
}
}
/*
Shell class, implements Sort interface
# Last update: 25 October 2015
*/
class Shell implements Sort {
Shell() {
}
int[] sequence = {59724292, 26544130, 11797391, 5243258, 2330349, 1035711, 460316, 204585, 90927, 40412, 17961, 7983, 3548, 1577, 701, 301, 132, 57, 23, 10, 4, 1};
/*
int number = 701;
for(int i=0; i<15; i++){
int newN = int(number*2.25);
println(number);
number = newN;
}
*/
int[] sortInteger (int[] input) {
int size = input.length;
int i, j, temp;
for ( int s : sequence ) {
i = s;
while ( i < size ) {
temp = input[i];
j = i-s;
while ( j >= 0 && input[j] > temp ) {
input[j + s] = input[j];
j -= s;
}
input[j + s] = temp;
i ++;
}
}
return input;
}
}
/*
QuickSort class, implements Sort interface
# Last update: 26 October 2015
*/
class QuickSort implements Sort {
QuickSort() {
}
int[] sortInteger(int[] input) {
quickSort(input, 0, input.length-1) ;
return input;
}
public void quickSort(int arr[], int low, int high)
{
int i = low, j = high;
int temp;
int pivot = arr[(low + high) / 2];
/** partition **/
while (i <= j)
{
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j)
{
/** swap **/
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
/** recursively sort lower half **/
if (low < j)
quickSort(arr, low, j);
/** recursively sort upper half **/
if (i < high)
quickSort(arr, i, high);
}
}
解决这个问题的第一步是隔离问题。这就是我们要求 MCVE 时的意思。您必须准确找出问题发生的位置。一种简单的方法是添加 println()
语句:
boolean runSortTest = false;
println("1");
runSortTest = runTest(url, "_results/a_insertion.txt", insertion);
println("2");
runSortTest = runTest(url, "_results/b_merge.txt", merge);
println("3");
runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
println("4");
runSortTest = runTest(url, "_results/d_shell.txt", shell);
println("5");
runSortTest = runTest(url, "_results/e_quickSort.txt", quickSort);
println("6");
这样做,我们会看到 1、2 和 3 被打印出来,但 4、5 和 6 没有。这意味着你在某个地方陷入了冒泡排序。我们可以通过注释掉冒泡排序并查看会发生什么来确认:
boolean runSortTest = false;
println("1");
runSortTest = runTest(url, "_results/a_insertion.txt", insertion);
println("2");
runSortTest = runTest(url, "_results/b_merge.txt", merge);
println("3");
//runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
println("4");
runSortTest = runTest(url, "_results/d_shell.txt", shell);
println("5");
runSortTest = runTest(url, "_results/e_quickSort.txt", quickSort);
println("6");
现在,程序可以正常执行了。所以现在我们已经知道问题出在冒泡排序上,所以我们可以摆脱其他一切:
import java.util.*;
long a = 9; // total loop, 9 means = 65536, 10 means = 131072 ...
long b = 2; // multiplier, 2 means = 512,1024,2048...
long c = 512; // starting number
long d = 5; // times random text file
String url;
Bubble bubble;
void setup() {
url = sketchPath("_numbers/");
bubble = new Bubble();
generateFiles(a, b, c, d);
boolean runSortTest = false;
runSortTest = runTest(url, "_results/c_bubble.txt", bubble);
if (runSortTest) {
println("Done");
} else {
println("Error");
}
}
boolean generateFiles(long totalLoop, long multiplier, long power, long fileNumber) {
PrintWriter pw;
//int orderCount = 1;
int count = 1;
//boolean tobeReturned = true;
try {
for (int i = 1; i < totalLoop; i = i+1) {
for (int j = 1; j < fileNumber+1; j = j+1) {
pw = createWriter("/_numbers/" + power + "/" + count + ".txt");
for (int k = 0; k < power; k = k+1) {
pw.println(randomNumber(0, power));
//pw.write(int(randomNumber(0, power)) + "\t");
}
count++;
pw.flush(); // Writes the remaining data to the file
pw.close(); // Finishes the file
}
count = 1;
//orderCount++;
power *= multiplier;
}
//orderCount = 1;
return true;
}
catch (Exception e) {
return false;
}
}
long randomNumber(long min, long max) {
long randomN = (long)random(min, (max + 1));
return randomN;
}
//####################################################################################################
//## Runs the test and produces a log file for each algorithms
//####################################################################################################
boolean runTest(String url, String out, Sort sort) {
PrintWriter filename;
boolean tobeReturned = true;
String beforeSorting = "";
String afterSorting = "";
long startTime;
double timeTaken;
try {
filename = createWriter(out);
for (File directory : new File(url).listFiles()) {
File[] listOfFiles = directory.listFiles();
filename.println("Number of Records: \t" + directory.getName());
for (File file : listOfFiles) {
String[] text;
int[] number;
text = loadStrings(file);
number = int(text);
if (isSorted(number)) {
beforeSorting = "Sorted";
} else {
beforeSorting = "NOT Sorted";
};
startTime = startTime();
sort.sortInteger(number);
timeTaken = stopTime(startTime);
if (isSorted(number)) {
afterSorting = "Sorted";
} else {
afterSorting = "NOT Sorted";
};
filename.println("File Set " + file.getName() + ": \t\t" + beforeSorting + ": \t" + afterSorting + ": \t" + timeTaken);
timeTaken = 0;
Arrays.fill(text, null);
number = null;
}
filename.println("\n");
}
filename.flush();
filename.close();
}
catch (Exception e) {
e.printStackTrace();
tobeReturned = false;
}
return tobeReturned;
}
boolean isSorted(int[] array) {
for (int i = 0; i < array.length-1; i ++) {
if (array[i] > array[i+1]) {
return false;
}
}
return true;
}
//####################################################################################################
//## Time comparison
//####################################################################################################
long startTime() {
return System.nanoTime();
}
double stopTime(long startTime) {
double finalTime = (System.nanoTime() - startTime)/1000000000.0;
return finalTime;
}
/*
Interface
# Last update: 20 October 2015
*/
interface Sort {
public int[] sortInteger(int[] input);
}
/*
Bubble class, implements Sort interface
# Last update: 25 October 2015
*/
class Bubble implements Sort {
Bubble() {
}
int[] sortInteger(int[] input) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < input.length - j; i++) {
if (input[i] > input[i + 1]) {
tmp = input[i];
input[i] = input[i + 1];
input[i + 1] = tmp;
swapped = true;
}
}
}
return input;
}
}
这可能会进一步缩短,但想法是这样的:删除与问题没有直接关系的任何内容。
现在我们已经删除了一些额外的信息,我们可以仔细看看您的冒泡排序。同样,println()
语句是您最好的朋友:
int[] sortInteger(int[] input) {
println("input length: " + input.length);
使用这个,可以看到确实还是运行ning,因为打印出来的是:
input length: 1024
input length: 1024
input length: 1024
input length: 1024
input length: 1024
input length: 16384
input length: 16384
input length: 16384
input length: 16384
input length: 16384
input length: 2048
input length: 2048
input length: 2048
input length: 2048
input length: 2048
input length: 32768
input length: 32768
input length: 32768
input length: 32768
input length: 32768
input length: 4096
input length: 4096
input length: 4096
input length: 4096
input length: 4096
input length: 512
input length: 512
input length: 512
input length: 512
input length: 512
input length: 65536
input length: 65536
input length: 65536
input length: 65536
input length: 65536
input length: 8192
input length: 8192
input length: 8192
input length: 8192
input length: 8192
Done
事实上:这很好,你只需要给它几分钟。这是我在 c_bubble.txt
:
记录数:1024
File Set 1.txt: NOT Sorted: Sorted: 0.009598049335181713
File Set 2.txt: NOT Sorted: Sorted: 0.0011289309477433562
File Set 3.txt: NOT Sorted: Sorted: 0.0026859149802476168
File Set 4.txt: NOT Sorted: Sorted: 0.002715847920626402
File Set 5.txt: NOT Sorted: Sorted: 0.0015163590433076024
Number of Records: 16384
File Set 1.txt: NOT Sorted: Sorted: 0.38029658794403076
File Set 2.txt: NOT Sorted: Sorted: 0.37928950786590576
File Set 3.txt: NOT Sorted: Sorted: 0.3931492865085602
File Set 4.txt: NOT Sorted: Sorted: 0.3918215036392212
File Set 5.txt: NOT Sorted: Sorted: 0.38513386249542236
Number of Records: 2048
File Set 1.txt: NOT Sorted: Sorted: 0.0040453351102769375
File Set 2.txt: NOT Sorted: Sorted: 0.0041389851830899715
File Set 3.txt: NOT Sorted: Sorted: 0.004071420058608055
File Set 4.txt: NOT Sorted: Sorted: 0.004472961183637381
File Set 5.txt: NOT Sorted: Sorted: 0.0041146110743284225
Number of Records: 32768
File Set 1.txt: NOT Sorted: Sorted: 1.6499463319778442
File Set 2.txt: NOT Sorted: Sorted: 1.6393990516662598
File Set 3.txt: NOT Sorted: Sorted: 1.628066897392273
File Set 4.txt: NOT Sorted: Sorted: 1.6488127708435059
File Set 5.txt: NOT Sorted: Sorted: 1.6586071252822876
Number of Records: 4096
File Set 1.txt: NOT Sorted: Sorted: 0.0184687077999115
File Set 2.txt: NOT Sorted: Sorted: 0.018312623724341393
File Set 3.txt: NOT Sorted: Sorted: 0.018741531297564507
File Set 4.txt: NOT Sorted: Sorted: 0.01845288649201393
File Set 5.txt: NOT Sorted: Sorted: 0.018356671556830406
Number of Records: 512
File Set 1.txt: NOT Sorted: Sorted: 3.81015008315444E-4
File Set 2.txt: NOT Sorted: Sorted: 3.322649863548577E-4
File Set 3.txt: NOT Sorted: Sorted: 3.3953398815356195E-4
File Set 4.txt: NOT Sorted: Sorted: 3.314100031275302E-4
File Set 5.txt: NOT Sorted: Sorted: 3.42526996973902E-4
Number of Records: 65536
File Set 1.txt: NOT Sorted: Sorted: 6.721750736236572
File Set 2.txt: NOT Sorted: Sorted: 6.752647399902344
File Set 3.txt: NOT Sorted: Sorted: 6.7578630447387695
File Set 4.txt: NOT Sorted: Sorted: 6.696788787841797
File Set 5.txt: NOT Sorted: Sorted: 6.759160995483398
Number of Records: 8192
File Set 1.txt: NOT Sorted: Sorted: 0.08915259689092636
File Set 2.txt: NOT Sorted: Sorted: 0.09149085730314255
File Set 3.txt: NOT Sorted: Sorted: 0.0899868980050087
File Set 4.txt: NOT Sorted: Sorted: 0.08892638236284256
File Set 5.txt: NOT Sorted: Sorted: 0.08631659299135208
现在我们知道您的冒泡排序已完成,让我们回头看看整个事情是否完成。是的,确实如此:
这完成得很好,似乎提供了结果。
我猜你实际上没有问题,但你希望草图能做一些视觉上的事情,而不是只给你一个灰色的框。但是由于您没有 draw()
函数,您只会看到一个灰色框。如果您不想弹出 window,请尝试在 setup()
函数末尾添加对 exit()
的调用。
如果您仍然认为它不起作用,请考虑以下事项:
- 添加更多打印语句,以便您可以更好地查看代码中发生的情况。
- 检查文件的输出目录。
- 请注意,由于您没有
draw()
函数,您的程序不会执行任何可视化操作,所以它所做的只是显示一个灰色框。 这并不意味着您的程序没有响应!这只是意味着您没有告诉它做任何事情。考虑在setup()
函数的末尾添加对exit()
的调用。 - 如果一切都失败了,请尝试通过上述过程隔离问题。尝试将其缩小到几条不符合您预期的线条,而不是整个草图。
编辑
您提到您得到了类似的结果,并且您只是在增加输入大小时才看到问题。 这正是您所期望的。
同样,添加打印语句是您最好的朋友。让我们从插入排序开始:
int[] sortInteger(int[] input) {
println("input length: " + input.length);
这将显示您的输入长度为 1,048,576。由于插入排序是 O(n^2),这意味着您必须进行 1,048,576 ^ 2 次比较。那是 1,099,511,627,776 次比较!假设您的计算机每秒可以进行 1,000 次比较,完成此算法需要 34 年。
(你的电脑大概每秒可以做1000多次比较,但是如果它每秒可以做100万次比较,它仍然需要12天才能完成。如果它每秒可以进行10亿次比较,它会需要 18 分钟,这只是一个算法的单个 运行。)
为了进一步调查这一点,println()
语句是您最好的朋友。尝试在插入排序循环中添加一个 println()
语句来显示 i
的值:
int i, j, tobeSorted;
for (i = 1; i < input.length; i++) {
tobeSorted = input[i];
j = i;
while (j > 0 && input[j - 1] > tobeSorted) {
input[j] = input[j - 1];
j--;
}
input[j] = tobeSorted;
println("i: " + i);
}
作为您的程序 运行s,您会看到这个数字在上升。即使计算机速度很快,处理您的全部输入仍然需要很长时间。这告诉您您的程序没有挂起,只是需要很长时间才能执行。
这就是研究这些算法的全部意义。计算机不是神奇的计算器,它们在合理的时间内可以完成的计算次数是有限的.这就是为什么你的算法是线性缩放还是指数缩放很重要:将输入大小加倍是需要两倍的时间,还是需要指数级的更长?
如果您仍然不相信结果,请继续尝试找出问题所在。当您认为程序“只是坐在那里”时,请尝试弄清楚您的程序到底在做什么。你应该确切地知道你的程序需要做多少计算,然后打印出到目前为止已经完成了多少计算。换句话说:打印出循环应该执行的次数,然后打印出循环到目前为止执行的次数。你会看到第一个值有多大,然后第二个值达到它需要多长时间。
编辑 2
这是草图的简化版本,可让您更轻松地更改输入的长度,以更“简洁”的方式获得不同算法的特定时间:
void setup() {
int[] input = getInput(1000);
int start = millis();
bubbleSort(input);
int elapsed = millis() - start;
println("Elapsed: " + elapsed);
exit();
}
int[] getInput(int n) {
int[] input = new int[n];
for (int i = 0; i < n; i++) {
input[i] = (int)random(n);
}
return input;
}
int[] bubbleSort(int[] input) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < input.length - j; i++) {
if (input[i] > input[i + 1]) {
tmp = input[i];
input[i] = input[i + 1];
input[i + 1] = tmp;
swapped = true;
}
}
}
return input;
}
只需更改传递给 getInput()
函数的值,您就可以看到它如何影响算法完成所需的时间。
这是冒泡排序:
N: 1,000 Time: 7
N: 10,000 Time: 145
N: 100,000 Time: 14600
N: 1,000,000 Time: 1467533
所以您看到将输入大小乘以 10 不会将您的时间乘以 10,它会乘以 100。这是因为冒泡排序是 O(n^2),所以它花费的时间呈二次方增长,而不仅仅是线性增长。如果我们尝试将 N 增加到 10,000,000,冒泡排序将需要大约 40 个小时!
归并排序更宽容,因为它是 O(n*log(n)):
N: 1,000 Time: 1
N: 10,000 Time: 5
N: 100,000 Time: 38
N: 1,000,000 Time: 221
N: 10,000,000 Time: 2202
这是在这里学到的重要一课:冒泡排序需要 40 个小时来排序 1000 万个项目,但合并排序只需要 2 秒!
所以大输入需要很长时间来排序的事实正是要点。这不是错误。您的程序没有挂起,只是需要很长时间才能对那么多项目进行排序。尝试像我的示例一样将您的问题分解成更小的草图,这样您就可以更轻松地仔细观察它到底在做什么。然后添加 println()
语句以查看您的程序将时间花在哪里。 这就是您解决问题的方法。
编辑 3
现在您提到您在任务管理器中收到“未响应”消息。同样,这正是我所期望的。您告诉 Processing 进行大量计算,虽然这些计算是 运行ning,但程序不会响应。大量输入可能需要数小时(或数天,甚至更长!)才能完成。因此,您的程序不会在一夜之间完成并且 OS 表示它没有响应,这一点也不让我感到惊讶。这就是 threads 的想法变得有用的地方,但那是一个完全独立的蠕虫罐头。
如果您仍然遇到问题,请考虑使用我的小示例来重复该问题,然后您将能够提出更具体的问题(在一个新问题中,而不是在对这个问题的编辑中)。确保包括您正在使用的精确排序算法、您正在使用的 N 值以及程序是否仍在执行或是否已抛出错误。同样,println()
语句是您最好的朋友。