下面的代碼對大數組(大於400000個字,儘管我沒有發現有限制)進行排序的單詞數組進行排序。它被通過它傳遞的話數組(從文件中讀取)進行排序,並測試其成功的一個項目叫做:C:僅適用於大文件的合併排序上的段錯誤
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "csort.h"
#include "sort.h"
// array points to array of pointers to strings, count is number of entries in array
void sortC(char** array, unsigned int count){
array = merge_sort(array, count);
// testing:
/*for (int i = 0; i < count; i++){
printf("%s ", array[i]);
}*/
}
char** merge_sort(char** array, int count){
if (count <= 1) return array;
else {
int lcount = 0;
int rcount = 0;
int middle = count/2;
lcount = middle;
char* left[lcount];
subArray(array, left, 0, middle);
rcount = count-middle;
char* right[rcount];
subArray(array, right, middle, count);
return merge(merge_sort(left, lcount), merge_sort(right, rcount), array, 0, lcount, rcount);
}
}
void subArray(char** array, char** subarray, int start, int end){
int ai; // index in original array
int si; // index in subarray
for (ai = start, si = 0; ai < end; ai++, si++){
subarray[si] = array[ai];
}
}
char** merge(char** left, char** right, char** output, int oi, int lcount, int rcount){
if (lcount > 0 && rcount > 0){
int lmin = findMinimum(left, lcount);
int rmin = findMinimum(right, rcount);
if (strcmp(left[lmin], right[rmin]) < 0){
output[oi] = left[lmin];
removeFromArray(left, lmin, lcount);
lcount--;
}
else {
output[oi] = right[rmin];
removeFromArray(right, rmin, rcount);
rcount--;
}
}
else if (lcount == 0) {
if (rcount == 1) {
output[oi] = right[0];
return output;
} else {
int rmin = findMinimum(right, rcount);
output[oi] = right[rmin];
removeFromArray(right, rmin, rcount);
rcount--;
}
}
else if (rcount == 0) {
if (lcount == 1) {
output[oi] = left[0];
return output;
} else {
int lmin = findMinimum(left, lcount);
output[oi] = left[lmin];
removeFromArray(left, lmin, lcount);
lcount--;
}
}
return merge(left, right, output, ++oi, lcount, rcount);
}
int findMinimum(char** array, int count){
char* minvalue = array[0];
char* currentvalue = minvalue;
int minindex = 0;
for (int i = 1; i < count; i++){
currentvalue = array[i];
if (strcmp(currentvalue, minvalue) < 0){
minvalue = currentvalue;
minindex = i;
}
}
return minindex;
}
void removeFromArray(char** array, int index, int count){
// removes specified index from an array
for (int i = index; i < count; i++){
if (i+1 == count){
array[i] = 0; // this entry will be gone when count decrements
} else {
array[i] = array[i+1];
}
}
}
這裏有一個具體問題嗎?你有沒有在調試器中運行它以查看它在哪裏進行分割? – 2011-04-21 17:11:42
(gdb)運行 輸入文件名:kjvbible.txt 790691單詞被讀取。 編程接收到的信號SIGSEGV,分段故障。 0x08048a1d在合併中(左= 0xff518910,右= 0xff5006e0,輸出= 0xff530bd0,oi = 35226,lcount = 7036,rcount = 7157)at csort.c:48 /home/elijah_houle/cs261/sort/csort.c:48 :1185:乞求:0x8048a1d – Elijah 2011-04-21 17:14:03
爲什麼它會出現故障?回溯沒有幫助,因爲它只顯示「merge()」被稱爲數千次。 – Elijah 2011-04-21 17:15:26