請教關於合併排序法的問題 |
尚未結案
|
poemkevin
初階會員 發表:26 回覆:77 積分:30 註冊:2002-10-19 發送簡訊給我 |
請教各位大大, 以下是一個c語言的合併排序法, 小弟將之轉成
delphi語法, 只是呼叫函數時, 都會出錯,
可否幫我看一下是那裏有問題? 謝謝!
再請教一個問題就是, 各位大大平常都使用那種排序函數,
那種比較有效率.
假設有好幾萬筆資料要排序,
也許可以將資料切成多段行程,
然後個別處理,
最後再一起合併在一起做總整合.
這樣是否應該會比較快.
只是要轉成適當的副程式, 就很傷腦筋!?
void mrge_sort(int a[],int f, int u) /* 合併排序法副程式 */ { int i,j,k,m; if (f < u) { m= (u 1) / 2; merge_sort(a,f,m); /* 利用合併排序法排左半邊的資料 */ merge_sort(a,m 1,u); /* 利用合拼排序法排右半邊的資料 */ for (i = m 1; i> f; i--) b[i-1]=a[i-1]; for(j=m; j < u; j ) b[u m-j] = a[j 1]; for (k=f; k<=u;k ) { if (b[i] < b[j]) { a[k]=b[i]; i=i 1; } else { a[k] = b[j]; j=j-1; } /* else */ } /* for */ getch(); }/* if */ }/* merge */ //用delphi寫的, 不知那裏出錯, 唉.... procedure merge_sort(var a:array of integer;f:integer;u:integer); var i,j,k,m:integer; b:array of integer; begin if (f < u) then begin m:=(u 1) shr 1; merge_sort(a,f,m); merge_sort(a,m 1,u); for i := m 1 downto f 1 do b[i-1]:=a[i-1]; for j :=m to u-1 do b[u m-j]:=a[j 1]; for k:=f to u do begin if (b[i] < b[j]) then begin a[k]:=b[i]; inc(i); end else begin a[k] := b[j]; dec(j); end; end; end; end;發表人 - poemkevin 於 2005/02/25 09:16:57 |
StrongLemon
高階會員 發表:10 回覆:166 積分:105 註冊:2004-04-18 發送簡訊給我 |
|
poemkevin
初階會員 發表:26 回覆:77 積分:30 註冊:2002-10-19 發送簡訊給我 |
引言: 您好: b陣列沒有設定長度 SetLength(b,n); n->應該是a的長度 所以->SetLength(b,Length(a));StrongLemon大大: 加了 setlength(b,Length(a)); 會發生堆疊溢位的問題, 而不加也會發生錯誤, 陣列變數被拒絕的問題 小弟是想寫一個動態陣列的排序函數 不管陣列大小, 只要叫進這函數就可以幫你自動排序 只有找到現成的c語言排序函數, 將它轉成delphi語法, 只是不知為什麼, 一直run都錯誤 真的蠻無奈的.. 不管是否能解決問題, 還是蠻感謝您的幫忙的 procedure merge_sort(var a:array of integer;f:integer;u:integer); var i,j,k,m:integer; b:array of integer; begin setlength(b,Length(a)); if (f < u) then begin m:=(u 1) shr 1; merge_sort(a,f,m); merge_sort(a,m 1,u); for i := (m 1) downto (f 1) do b[i-1]:=a[i-1]; for j := m to (u-1) do b[u m-j]:=a[j 1]; for k:=f to u do begin if (b[i] < b[j]) then begin a[k]:=b[i]; inc(i); end else begin a[k] := b[j]; dec(j); end; end; end; end; procedure TForm1.Button1Click(Sender: TObject); var x:array of integer; i:integer; begin Randomize; setlength(x,101); for i :=0 to 100 do x[i]:=random(100); for i :=low(x) to high(x) do memo1.Lines.Append(inttostr(x[i])); merge_sort(x,1,9); for i :=low(x) to high(x) do memo1.Lines.Append(inttostr(x[i])); end; procedure TForm1.Button3Click(Sender: TObject); var x:array of integer; i:integer; str:tstringlist; begin Randomize; setlength(x,101); for i :=0 to 100 do x[i]:=random(101); try str:=Tstringlist.Create; str.Clear; for i :=low(x) to high(x) do begin str.Add(format('%0.3d',[x[i]])) ; end; str.Sort; for i :=0 to str.Count-1 do x[i]:=strtoint(str.Strings[i]); for i :=low(x) to high(x) do memo1.Lines.Append(inttostr(x[i])); finally freeandnil(str); end; end;以下是修改論壇一位大大的程式,可以用, 只是不知為什麼我將c轉成delphi寫的merge_sort函數 不是堆疊錯誤, 就是陣列會出錯. //數值陣列快速排序,這是修改論壇上一位大大的程式, //可以用來排序數值陣列 procedure adquicksort(var AryRec:array of integer); //有傳回值 procedure QuickSort(iLo, iHi: Integer); var Lo,Hi:Integer; ComPare:Longint; SwapRec :integer; begin Lo := iLo; Hi := iHi; ComPare := AryRec[(Lo Hi) shr 1]; repeat while AryRec[Lo] < ComPare do Inc(Lo); while AryRec[Hi] > ComPare do Dec(Hi); if Lo <= Hi then begin SwapRec :=AryRec[Lo]; AryRec[Lo] :=AryRec[Hi]; AryRec[Hi] :=SwapRec; Inc(Lo); Dec(Hi); end; until Lo > Hi; if Hi > iLo then QuickSort(iLo, Hi); if Lo < iHi then QuickSort(Lo, iHi); end; begin if Length(AryRec) < 2 then Exit; QuickSort(Low(AryRec),High(AryRec)); end;發表人 - poemkevin 於 2005/02/25 15:30:08 發表人 - poemkevin 於 2005/02/25 16:10:25 |
StrongLemon
高階會員 發表:10 回覆:166 積分:105 註冊:2004-04-18 發送簡訊給我 |
您好:我修正過如下
修正解釋:
1.Stack Overflow通常發生原因是在於遇到無窮迴圈
2.原本c這段Code:
m= (u 1) / 2;有問題 假設u=5那m就都一直3,發生在merge_sort(a,m 1,u); m{3}= (u{5} 1 )/2; merge_sort(a,m{3} 1,u{5});右半 剛剛想到m= (u 1) / 2;應該是m=( u f )/2; procedure merge_sort(var a:array of integer;f:integer;u:integer); var i,j,k,m:integer; b:array of integer; begin //setlength(b,Length(a)); if (f < u) then begin //m:=(u 1) shr 1; //if Odd(f u)=True then // m:=(f u-1) div 2 //else // m:=(f u) div 2; m:=(u f) div 2; merge_sort(a,f,m); merge_sort(a,m 1,u); setlength(b,Length(a));//搬到這來是為了效能,有使用才動作 for i := (m 1) downto (f 1) do b[i-1]:=a[i-1]; for j := m to (u-1) do b[u m-j]:=a[j 1]; for k:=f to u do begin if (b[i] < b[j]) then begin a[k]:=b[i]; inc(i); end else begin a[k] := b[j]; dec(j); end; end; end; end;發表人 - StrongLemon 於 2005/02/27 06:42:27 發表人 - StrongLemon 於 2005/02/27 06:44:23 |
poemkevin
初階會員 發表:26 回覆:77 積分:30 註冊:2002-10-19 發送簡訊給我 |
謝謝StrongLemon大大的指導 m= (u 1) / 2;
這一行
剛去看c語言資料結構的書那篇合併排序法,
原來這一行是我抄錯了, 呵呵, 真傷腦筋,
之前的變數是L, 我怕混淆, 所以把l的變數, 重新命名為f,
結果還是不小心抄錯.
難怪我之前一直run不起來
還是StrongLemon大大比較厲害, 能夠一下子就找出小弟的錯誤.
真是感激不盡!! 另外, 請教一個問題, 關於排序法
假設是二維陣列以上的排序法
要用函數副程式來寫, 有什麼樣的排序法比較簡捷又有效率?
最近有空時, 小弟正試著將以前讀書時的c語言資料結構的程式碼,
轉成delphi程式碼.順便做練習.
好久沒到書局了, 或許已經有現成的delphi資料結構語法的書了吧!
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |