Thuật toán sắp xếp

4 3.9K 27
Thuật toán sắp xếp

Đang tải... (xem toàn văn)

Thông tin tài liệu

Thuật toán sắp xếp

Lại bàn về giải thuật sắp xếpTạ Tiến ĐạtCác bạn thân mến! Hôm nay qua bài viết này tôimuốn đề cập tới một thuật toán sắp xếp ổn định để giải bài toán mã hóa Burrows (mà hẳn nhiều bạn đã quen thuộc).Nếu bạn nào chưa rõ về bài toán này có thể tìm đọc số báo tháng11 năm 2001, bài "Lựa chọn giải thuật sắp xếp " của thầy Nguyễn XuânHuy để rõ hơn. Sau đây tôisẽ đi ngay vào phân tích thuật toán sắp xếp mà tôi định nói đếnlà Sắp xếp bằng phép đếm phân phối(Distribution Counting). Yêu cầu bàitoán là cho một dãy khóa k1, k2 kn (nguyênkhông âm) và đưa ra dãy đã sắp tăng (hoặc giảm tùy ý) Giả sử tađã xây dựng được dãy c1, c2 c(n+1) vớiý nghĩa ci là số lần xuất hiện của giá trị i trong dãy sốban đầu. Dựa vào dãy biến đếm trên ta hoàn toàn có thể suy ra giátrị kj sẽ thuộc vào đoạn nào trong dãy sau khi sắp xếp. Cụthể sau khi có dãy c ta xây dựng lại nó như sau: c0= 0 c1= c0 + c1 c2= c0 + c1 + c2 … cn= c0 + c1 + c2 + + cn khi đó giátrị i trong dãy ban đầu khi được sắp tăng thì nó sẽ nằm ở đoạn ci-1 + 1 tới ci và ta dễ dàngsuy ra dãy khóa sau khi sắp tăng dựa vào dãy c này. Ta có cách cài đặt củathuật toán như sau: procedureDistributionCounting; begin fillchar(c, sizeof(c), 0); for i := 1 to n do inc(c[k[i]]); for i := 2 to n do c[i] := c[i-1] + c[i]; for i := n downto 1 do begin x[c[k[i]] := k[i]; {x là dãy khóa phụ chứa các giá trị của dãyk sau khi sắp} dec(c[k[i]]); end; end; Đánhgiá: - Thuật toáncó độ phức tạp O(Max(M, n)) trong đó M là giá trị lớn nhất trong dãysố ban đầu, hơn hẳn thuật toán sắp xếp chèn và nổi bọt có độ phứctạp O(n2). - Nhược điểmcủa thuật toán là với M quá lớn thì không thể biểu diễn được dãykhóa c, tuy nhiên với bài toán của chúng ta thì các kí tự chỉ có vịtrí trong bảng mã ≤ 255 mà thôi nên việc áp dụng thuật toán nàylà hoàn toàn có thể. (ta sắp xếp dựa vào hàm Ord(ch: Char) trả về vịtrí của kí tự ch trong bảng mã ANSI) Dưới đâylà cách cài đặt của tôi với bài toán mã hóa BURROWS, áp dụng thuậttoán sắp xếp bằng phép đếm phân phối (với một chút thay đổi so vớiở trên): {$A+,B-,D+,E+,F+,G-,I+,L+,N+,Ơ,P-,Q+,R+,S+,T-,V+,X+,Y+} {$M16384,0,655360} programCode; const inputfile = ’BURROWS.INP’; outputfile = ’BURROWS.OUT’; max = 1000; maxC = 255; var a: array[0 max] of Char; c: array[0 maxC] of integer; id: array[0 max] of integer; n, d: integer; f, g: text; procedureEnter; begin n := 0; while not seekeoln(f) do begin inc(n); read(f, a[n]); end; readln(f, d); end; procedureDistributionCounting; var i: integer; begin fillchar(c, sizeof(c), 0); for i := 1 to n do inc(c[Ord(a[i])]); for i := 2 to maxC do c[i] := c[i] + c[i - 1]; for i := n downto 1 do begin id[c[Ord(a[i])]] := i; dec(c[Ord(a[i])]); end; end; procedureProcess; var i: integer; begin fillchar(id, sizeof(id), 0); DistributionCounting; end; procedureResult; var count: integer; begin count := 0; repeat write(g, a[id[d]]); d := id[d]; inc(count); until count = n; writeln(g); end; procedureSolve; begin assign(f, inputfile); reset(f); assign(g, outputfile); rewrite(g); while not seekeof(f) do begin Enter; Process; Result; end; close(f); close(g); end; begin Solve; end. Các bạn có để ý tại saotrong thủ tục DistributionCounting, chúng ta lại cho duyệt ngược dãy khóatừ cuối không? Điều đó là để đảm bảo cho tính ổn định của thuật toán, mặc dù việc duyệt từ đầu hay từ cuối đều không ảnhhưởng tới việc sắp tăng giá trị của dãy khóa ban đầu. . bàn về giải thuật sắp xếpTạ Tiến ĐạtCác bạn thân mến! Hôm nay qua bài viết này tôimuốn đề cập tới một thuật toán sắp xếp ổn định để giải bài toán mã hóa. đi ngay vào phân tích thuật toán sắp xếp mà tôi định nói đếnlà Sắp xếp bằng phép đếm phân phối(Distribution Counting). Yêu cầu bàitoán là cho một dãy khóa

Ngày đăng: 11/09/2012, 15:26

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan