CẤU TRÚC dữ LIỆU ĐỘNG

39 372 0
CẤU TRÚC dữ LIỆU ĐỘNG

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

CẤU TRÚC DỮ LIỆU ĐỘNG MỞ ĐẦU Cấu trúc dữ liệu là một lĩnh vực nghiên cứu lâu đời của khoa học máy tính. Hầu hết các chương trình được viết ra, chạy trên máy tính, dù lớn hay nhỏ, dù đơn giản hay phức tạp, đều phải sử dụng cấu trúc dữ liệu. Việc hiểu biết về các cấu trúc dữ liệu giúp các lập trình viên có nhiều lựa chọn hơn trong việc đưa ra các giải pháp hiệu quả giải quyết các bài toán tin. Với các cấu trúc dữ liệu được xây dựng từ các kiểu cơ sở như: kiểu thực, kiểu nguyên, kiểu ký tự... hoặc từ các cấu trúc đơn giản như mẩu tin, tập hợp, mảng... lập trình viên có thể giải quyết hầu hết các bài toán đặt ra. Các đối tượng dữ liệu được xác định thuộc những kiểu dữ liệu này có đặc điểm chung là không thay đổi được kích thước, cấu trúc trong quá trình sống, do vậy thường cứng nhắc, gò bó khiến đôi khi khó diễn tả được thực tế vốn sinh động, phong phú. Các kiểu dữ liệu kể trên được gọi là các kiểu dữ liệu tĩnh. Một số đối tượng dữ liệu trong chu kỳ sống của nó có thể thay đổi về cấu trúc, độ lớn, như danh sách các học viên trong một lớp học có thể tăng thêm, giảm đi... Khi đó nếu cố tình dùng những cấu trúc dữ liệu tĩnh đã biết như mảng để biểu diễn những đối tượng đó lập trình viên phải sử dụng những thao tác phức tạp, kém tự nhiên khiến chương trình trở nên khó đọc, do đó khó bảo trì và nhất là khó có thể sử dụng bộ nhớ một cách có hiệu quả. Do bản chất của các dữ liệu tĩnh, chúng sẽ chiếm vùng nhớ đã dành cho chúng suốt quá trình hoạt động của chương trình. Tuy nhiên, trong thực tế, có thể xảy ra trường hợp một dữ liệu nào đó chỉ tồn tại nhất thời hay không thường xuyên trong quá trình hoạt động của chương trình. Vì vậy việc dùng các CTDL tĩnh sẽ không cho phép sử dụng hiệu quả bộ nhớ. Do vậy, nhằm đáp ứng nhu cầu thể hiện sát thực bản chất của dữ liệu cũng như xây dựng các thao tác hiệu quả trên dữ liệu, cần phải tìm cách tổ chức kết hợp dữ liệu với những hình thức mới linh động hơn, có thể thay đổi kích thước, cấu trúc trong suốt thời gian sống. Các hình thức tổ chức dữ liệu như vậy được gọi là cấu trúc dữ liệu động. Trong khuôn khổ tài liệu này, tác giả sẽ giới thiệu về một số cấu trúc dữ liệu động đặc biệt như danh sách liên kết, ngăn xếp và hàng đợi và một số ứng dụng của chúng đặc biệt trong việc khử đệ qui. Tác giả rất mong nhận được những đóng góp của các thầy, cô giáo và học sinh để chuyên đề này được hoàn thiện hơn. Xin trân trọng cảm ơn.! MỤC LỤC 1. DANH SÁCH LIÊN KẾT.......................................................................................................3 1.1 Khái niệm..........................................................................................................................3 1. 2 Cấu tạo của danh sách liên kết.........................................................................................4 1.3 Các thao tác cơ bản với danh sách liên kết........................................................................4 1. 3. 1 Khai báo....................................................................................................................4 1.3.2 Khởi tạo danh sách.....................................................................................................4 1.3.3 Bổ sung một nút vào đầu danh sách...........................................................................4 1.3.4. Bổ sung một nút vào cuối danh sách.........................................................................5 1.3.5 Duyệt danh sách.........................................................................................................5 1.3.6 Bổ sung một nút vào sau nút được trỏ bởi p...............................................................5 1.3.7. Xoá một nút khỏi danh sách......................................................................................6 1.4. Mảng hay danh sách liên kết?..........................................................................................6 1.5. Ví dụ làm việc với danh sách liên kết..............................................................................7 2. NGĂN XẾP – STACK..........................................................................................................14 2.1. Khái niệm.......................................................................................................................14 2.2 Các thao tác cơ bản của ngăn xếp....................................................................................14 2.4. Ứng dụng Stack..............................................................................................................15 2.4.1 Ứng dụng Stack khử đệ quy.....................................................................................15 2.4.2 Tính giá trị một biểu thức dạng hậu tố.....................................................................22 2.4.3 Chuyển biểu thức từ trung tố sang hậu tố.................................................................25 3. HÀNG ĐỢI – Queue.............................................................................................................27 3.1. Khái niệm.......................................................................................................................27 3.2 Các thao tác cơ bản của hàng đợi....................................................................................28 3.3. So sánh việc cài đặt Queue bằng mảng và danh sách liên kết........................................31 3.4 Ứng dụng.........................................................................................................................31 2 1. DANH SÁCH LIÊN KẾT Danh sách là một dãy hữu hạn các phần tử thuộc cùng một lớp đối tượng nào đó. Ví dụ : danh sách sinh viên, danh sách vật tư, danh sách các hoá đơn, danh sách các số thực. Chúng ta đã dùng mảng để biểu thị một danh sách, cách này có các nhược điểm: kích thước của mảng phải định trước nên tốn bộ nhớ (số phần tử thực tế dùng nhiều khi rất ít so với khai báo), khi thêm một phần tử vào mảng hoặc xoá một phần tử ra khỏi mảng ta phải mất nhiều thời gian để dồn mảng. Danh sách liên kết dùng để cài đặt một danh sách sẽ khắc phục được các nhược điểm trên của mảng. 1.1 Khái niệm R. Sedgewick (Alogrithms in Java – 2002) định nghĩa danh sách liên kết như sau: Danh sách liên kết là một cấu trúc dữ liệu bao gồm một tập các phần tử, trong đó mỗi phần tử là một phần của một nút có chứa liên kết đến phần tử kế tiếp. “Mối phần tử là một phần của một nút” vì mỗi nút có ít nhất hai trường, một trường gọi là dữ liệu (data), trường còn lại là trường liên kết trỏ đến nút tiếp theo trong danh sách. Trường liên kết của phần tử thứ i của danh sách sẽ trỏ tới phần tử thứ (i+1) của danh sách. Tuy nhiên nó cũng có thể trỏ đến chính nó. Có thể nói danh sách liên kết là một cấu trúc dữ liệu được định nghĩa kiểu đệ quy, vì trong định nghĩa một nút của danh sách có tham chiếu tới khái niệm nút. Có nhiều loại danh sách liên kết khác nhau tùy thuộc vào cấu trúc của mỗi phần tử trong danh sách (số trường liên kết với các phần tử khác trong danh sách) nhưng cơ bản nhất là danh sách liên kết đơn (single linked list), mỗi phần tử có một trường liên kết như trên hình vẽ minh họa, và khi chúng ta nói đến danh sách liên kết, nếu không có các chú giải đi kèm thì ngầm hiểu đó là danh sách liên kết đơn. Danh sách liên kết kép: mỗi phần tử liên kết với các phần tử đứng trước và sau nó trong danh sách: Danh sách liên kết vòng : phần tử cuối danh sách liên kết với phần tử đầu danh sách: 3 1. 2 Cấu tạo của danh sách liên kết Cấu tạo của danh sách liên kết: có một con trỏ First chứa địa chỉ của phần tử đầu tiên của danh sách, phần tử đầu có phần dữ liệu và một con trỏ Next để chứa địa chỉ của phần tử thứ hai, tổng quát phần tử thứ i có phần dữ liệu và một con trỏ next để chứa địa chỉ của phần tử thứ i+1, đối với phần tử cuối cùng giá trị của con trỏ next bằng NIL. Để thuận tiện khi thêm phần tử mới vào cuối danh sách liên kết ta dùng một con trỏ Last chứa địa chỉ của phần tử cuối cùng. Khởi tạo một danh sách rỗng first = NIL. Nhắc lại 2 thủ tục cơ bản với biển trỏ: + Cấp phát vùng nhớ cho biến trỏ p: New(p) + Giải phóng vùng nhớ cho biến trỏ p: Dispose(p) 1.3 Các thao tác cơ bản với danh sách liên kết 1. 3. 1 Khai báo Để khai báo một danh sách động trước hết ta khai báo kiểu của mỗi nút trong danh sách. Type = ^ ; = Record Data: DataType; Next: ; End; Var First: ; First là địa chỉ của nút đầu tiên trong danh sách, dựa vào trường next của nút này ta bết được địa chỉ của nút thứ hai, cứ như vậy ta biết được địa chỉ của tất cả các nút trong danh sách. 1.3.2 Khởi tạo danh sách First : =Nil; 1.3.3 Bổ sung một nút vào đầu danh sách +Tạo ra nút mới New(p); p^.Data :=X; + Bổ sung vào đầu danh sách p^.Next :=First; 4 First :=p; 1.3.4. Bổ sung một nút vào cuối danh sách Xuất phát danh sách không có nút nào cả. Nút mới thêm vào sẽ nằm cuối danh sách. Khi đó ta cần hai biến con trỏ First và Last lần lượt trỏ đến các nút đầu và cuối danh sách. Procedure Khoitao; var p: TroNut; Begin First := nil; Last:= nil; While do Begin New(p); Readln(p^.data); p^.Next := Nil; If First = Nil then First := p Else Last^.next := p; Last := p; End; End; 1.3.5 Duyệt danh sách Duyệt danh sách là thăm và xử lý từng nút trong danh sách. Procedure Duyet; Var p: TroNut; Begin P := First; While p nil do Begin ; P := p^.Next; {duyệt qua nút tiếp theo} End; End; 1.3.6 Bổ sung một nút vào sau nút được trỏ bởi p Thủ tục sau thực hiện việc bổ sung một nút có nội dung x vào sau nút được trỏ bởi p. Procedure Bosung(p,x); Var q: TroNut; Begin New(q); q^.data:=x; if first = nil then begin q^.next := nil; 5 end else begin first := q; q^.next:= p^.next; p^.next:= q; End; end; 1.3.7. Xoá một nút khỏi danh sách Thủ tục sau thực hiện việc xóa một nút trỏ bởi p ra khỏi danh sách. Procedure Xoa(p); Var q: TroNut; Begin if First = nil then exit; if p = First then First := First^.next else begin q:= First; While q^.next p do q:= q^.next; q^.next:= p^.next; end; Dispose(p); End; 1.4. Mảng hay danh sách liên kết? Chúng ta đã từng làm quen với kiểu mảng, lưu danh sách gồm nhiều thành phần có cùng kiểu. Mỗi thành phần là một biến tĩnh và số lượng thành phần của danh sách là cố định. Tuy nhiên việc sử dụng mảng có các nhược điểm: kích thước của mảng phải định trước nên tốn bộ nhớ (số phần tử thực tế dùng nhiều khi rất ít so với khai báo), khi thêm một phần tử vào mảng hoặc xoá một phần tử ra khỏi mảng ta phải mất nhiều thời gian để dồn mảng. Danh sách liên kết dùng để cài đặt một danh sách sẽ khắc phục được các nhược điểm trên của mảng. Tuy nhiên không thể kết luận phương pháp cài đặt nào hiệu quả hơn, mà nó hoàn toàn tuỳ thuộc vào từng ứng dụng hay tuỳ thuộc vào các phép toán trên danh sách. Tuy nhiên ta có thể tổng kết một số ưu nhược điểm của từng phương pháp làm cơ sở để lựa chọn phương pháp cài đặt thích hợp cho từng ứng dụng: Cài đặt bằng mảng đòi hỏi phải xác định số phần tử của mảng, do đó nếu không thể ước lượng được số phần tử trong danh sách thì khó áp dụng cách cài đặt này một cách hiệu quả vì nếu khai báo thiếu chỗ thì mảng thường xuyên bị đầy, không thể làm việc được còn nếu khai báo quá thừa thì lãng phí bộ nhớ. 6 Cài đặt bằng con trỏ thích hợp cho sự biến động của danh sách, danh sách có thể rỗng hoặc lớn tuỳ ý chỉ phụ thuộc vào bộ nhớ tối đa của máy. Tuy nhiên ta phải tốn thêm vùng nhớ cho các con trỏ (trường next). Cài đặt bằng mảng thì thời gian xen hoặc xoá một phần tử tỉ lệ với số phần tử đi sau vị trí xen/ xóa. Trong khi cài đặt bằng con trỏ các phép toán này mất chỉ một hằng thời gian. Phép truy nhập vào một phần tử trong danh sách chỉ tốn một hằng thời gian đối với cài đặt bằng mảng, trong khi đối với danh sách cài đặt bằng con trỏ ta phải tìm từ đầu danh sách cho đến vị trí trước vị trí của phần tử hiện hành. Nói chung danh sách liên kết thích hợp với danh sách có nhiều biến động, tức là ta thường xuyên thêm, xoá các phần tử. 1.5. Ví dụ làm việc với danh sách liên kết Xét danh sách liên kết đơn biểu diễn một dãy số nguyên. Nút đầu tiên trong danh sách được trỏ bởi First. Cho khai báo mỗi nút trong danh sách như sau: Type TroNut = ^ Nut; Nut = Record Data: Integer; Next: TroNut; End; Var First: TroNut; Viết chương trình thực hiện các yêu cầu sau: a. Nhập dãy các số nguyên và lưu vào danh sách có nút đầu trỏ bởi First, quá trình nhập dừng khi dữ liệu đưa vào không phải là số nguyên. Program Vi_du_1; Type TroNut = ^ Nut; Nut = Record Data: Integer; Next: TroNut; End; Var First: TroNut; p: pointer; Procedure Nhap; Var n:integer; kq:boolean; last,p: tronut; begin first:=nil; last:= nil; repeat 7 write(‘Nhap gia tri mot nut – Ket thuc bang ky tu Q: ‘); {$I-} readln(n); {$I+} kq:= IOResult=0; if kq then begin new(p); p^.Data:=n; p^.Next:=nil; if first = nil then first:= p; else last^.Next:= p; last:=p; end; until not kq; end; b. In ra màn hình giá trị các nút lớn hơn 0. Procedure In_so_duong; Var p: Tronut; begin p:= first; while p nil do begin if p^.Data > 0 then write(p^.Data:8); p:=p^.Next; end; end; Begin Mark(p); Nhap; In_so_duong; Release(p); Readln; End. c. Viết thủ tục đếm số nút có giá trị lớn hơn 0 và tính giá trị trung bình cộng của các nút đó. 8 Procedure Nut_duong(var dem: word; tb:real); Var p: Tronut; tong:longint; begin dem:=0; tong:=0; p:= first; while p nil do begin if p^.Data > 0 then begin inc(dem); tong:=tong+p^.Data; end; p:=p^.Next; if dem = 0 then tb:=0 else tb:= tong /dem; end; d. Giả sử dãy giá trị các nút trong danh sách đã được sắp tăng dần. Viết các thủ tục và hàm sau: Procedure Insert(var first: TroNut; m: integer) thực hiện việc bổ sung một nút vào danh sách sao cho tính tăng dần được bảo toàn. Procedure Insert(var first: TroNut; m: integer); Var p,q: Tronut; begin new(p); p^.Data:= m; if (first = nil) or (first^.Data < m ) then begin p^.Next:=nil; first:= p; end else begin q:= first; while (q^.Next nil) and ((q^.Next)^.Data < m) do q:= q^.Next; 9 end; p^.Next:= q^.Next; q^.Next:= p; end; Procedure InitList thực hiện việc tạo danh sách có tính chất trên bằng cách nhập dữ liệu từ bàn phím và quá trinh nhập dừng khi nhấn phím ESC (yêu cầu: sử dụng thủ tục Insert). Procedure InitList; Var m: integer; Begin first:= nil; repeat write(‘Nhap gia tri cua mot nut: ‘); readln(m); insert(first,m); until readkey = #27; end; Procedure List(First: TroNut) in dãy giá trị các nút trong danh sách. Procedure List(First: Tronut); Var p:Tronut; begin p:= first; while p nil do begin write(p^.Data); p:=p^.Next; end; end; Procedure DeleteZero( Var First: TroNut) thực hiện việc xoá tất cả các nút có giá trị 0 trong danh sách. Procedure DeleteZero(Var First: TroNut); var p,q: Tronut; begin p:= first; while (p nil) and (p^.Data < 0) do begin q:= p; p:= p^.Next; 10 end; while (p nil) and (p^.Data = 0) do begin q^.Next:= p^.Next; dispose(p); p:= q^.Next; end; end; Function TroMax(First: TroNut): TroNut trả về địa chỉ của nút đầu tiên đạt giá trị lớn nhất (tính từ đầu danh sách, nếu có, ngược lại hàm trả về giá trị Nil). Function Tromax(First: TroNut); var p.q: Tronut; m:integer; begin if first = nil then TroMax:= nil else begin p:= first; m:= p^.Data; q:= p^.Next; while (q nil) do begin if q^.Data > m then begin p:= q; m:= p^.Data; end; q:= q^.Next; end; TroMax:=p; end; end; e. Giả sử danh sách khác rỗng. Viết các thủ tục và hàm sau: Function DataMax(First: TroNut): integer trả về giá trị lớn nhất của nút có trong danh sách. Function DataMax(First: TroNut): integer; var m: integer; p, q: Tronut; begin 11 p:= first; m:= p^.Data; q:= p^.Next; while q nil do begin if q^.Data > m then m:=q^.Data; q:= q^.Next; DataMax:= m; end; Function DataMin(First: TroNut): Integer trả về giá trị nhỏ nhất của nút có trong danh sách. Function DataMax(First: TroNut): integer; var m: integer; p,q: Tronut; begin p:= first; m:= p^.Data; q:= p^.Next; while q nil do begin if q^.Data < m then m:=q^.Data; q:= q^.Next; DataMin:= m; end; f. Cho danh sách liên kết đơn có nút đầu trỏ bởi First, được khai báo như sau Type TroNut = ^nut; Nut = Record Data: real; Next: TroNut; End; Var First: Tronut; Viết các thủ tục và hàm sau: Function Search(First: TroNut; k: word): TroNut trả về địa chỉ của nút thứ k (nếu có, ngược lại, hàm trả về giá trị Nil). Function Search(First: TroNut; k: word): Tronut; Var d: word; 12 Begin p: Tronut; d:=0; p:=first; while (p nil) do begin inc(d); if d = k then break; p:= p^.next; end; Search:= p; End; Procedure Delete_K(Var First: TroNut; k: word) thực hiện việc xoá nút thứ k trong danh sách (nếu có). Procedure Delete_K(Var first: Tronut; k:word); var d: word; p,q: Tronut; begin d:=1; p:= first; while (p nil) and (d Nil Do Begin GT:=GT* Top(S); Pop(S); End; Writeln (GT); End; b) Bài toán tính số Fibonaci Dãy số Fibonaci xác định như sau: Bắt đầu từ 2 số 0 và 1 tiếp sau đó là các số Fibonaci sau bằng tổng của 2 số Fibonaci trước đó. F1=0; F2=1; FN = FN-1+ FN-2 ∀ N ≥ 2 Ví dụ dãy số Fibonaci: 0 1 1 2 3 5 8… Đệ quy hàm Fibonaci như sau: Function Fibo(N:Integer): Longint; 16 Begin If N=1 then Fibo:=0 Else If N=2 then Fibo:=1 Else Fibo:=Fibo(N-1) * Fibo(N-2); End; Khử đệ quy bằng Stack: S: Stack; Fibo: Longint; Khoitao(S); If (N=0) or (N=1) then Fibo:=N Else Begin Push(N,S); While N0 Do Begin N:=N-1; Push(N,S); End; If Top(S) 2 then Begin T:=0; Pop(S); K:= 1; Pop(S); End; Whike Not Stack_empty Do Begin Fibo:=T+K; T:=K; K:=Fibo; Pop(S); End; End; Writeln(Fibo); c) Khử đệ quy thuật toán sắp xếp Quicksort B1: Khởi tạo một stack rỗng B2: Mảng A ta đang xét từ phần tử thứ 1 đến phần tử thứ N, gán L:=1, R:=N, đẩy hai giá trị 1 và N vào Stack. B3: Lấy lại L, R từ Stack ra B4: Phân hoạch dãy A[L]..A[R] thành hai dãy: A[L]..A[j-1] và dãy A[j+1]...A[R] B5: Nếu j+1 < R thì đẩy (j+1) và R vào Stack. 17 B6: Nếu L< j-1 thì quay lại bước 4 để phân hoạch dãy A[L]..A[j-1] nếu không chuyển sang bước 7. B7: Nếu Stack khác rỗng thì quay lại B3 để phân hoạch tiếp, nếu Stack rỗng thì kết thúc. Const Nmax=5000; Var n, i, j, x, l, r, tg:Integer; s:0.. Nmax; A: Array[1..Nmax] of Integer; Stack: Array [1.. Nmax] of Record 1, r : Integer;End; Procedure Sort; Begin S:=1; Stack[s].1:=1; Stack[s].r :=n ; Repeat 1:=Stack[s].1; r: = Stack[s].r; Dec(s); Repeat i:=1; j:=r;x:=A[(1+r)div 2] Repeat While a[i] < x Do Inc(i); While a [j] > x Do Dec (j); if i < = j then Begin Tg := a[i]; a[i] : = a[j]; a[j] : = tg; Inc(i); Dec(j); End; Until i >j; If i < r then Begin S : = s+1 ; Stack[s].1: = 1; Stack [s].r:=r; End; r:=j; Until 1>r ; Until S=0; End; e) Cài đặt thuật toán Tìm kiếm theo chiều sâu bằng ngăn xếp 18 Cho đơn đồ thị vô hướng G=(V,E) gồm N đỉnh, M cạnh. Các đỉnh được đánh số thứ tự từ 1 đến N. Xuất phát tại đỉnh S, Tìm đường đi từ đỉnh xuất phát S đến đỉnh kết thúc F; Tư tưởng dùng đệ quy của thuật toán tìm kiếm theo chiều sâu (DFS): Trước hết, mọi đỉnh x kề với S tất nhiên sẽ đến được từ S. Với mỗi đỉnh x kề với S đó thì tất nhiên những đỉnh y kề với x cũng đến được từ S. Điều đó gợi ý cho ta viết một thủ tục đệ quy DFS(u) mô tả việc duyệt từ đỉnh u bằng cách thông báo thăm đỉnh u và tiếp tục quá trình duyệt DFS(v), với v là một đỉnh chưa thăm kề với u. Để không một đinh nào bị liệt kê tới 2 lần, ta sử dụng kĩ thuật đánh dấu, mỗi lần thăm một đỉnh, ta đánh dẫu đỉnh đó lại để các bước duyệt đệ quy kế tiếp không duyệt lại đỉnh đó nữa. Để lưu lại đường đi từ đỉnh xuất phát S, trong thủ tục DFS(u), trước khi gọi đệ quy DFS(v), với v kề với u mà chưa đánh dấu, ta lưu lại vết đường đi từ u->v bằng cách Trace[v]:=u, tức là trước khi đến đỉnh v là đỉnh u. Procedure DFS(u:integer); Var v: Integer; Begin Begin Trace[v]:=u; DFS(v); End; End; Khi mô tả quá trình đệ quy bằng ngăn xếp, ta luôn luôn để cho ngăn xếp để lưu lại dây chuyền duyệt sâu từ nút gốc (đỉnh xuất phát S). < Thăm S, đánh dấu S đã thăm> < Đẩy S vào ngăn xếp> Repeat < Lấy u khỏi ngăn xếp> If < u có đỉnh kề chưa thăm> then Begin < Chỉ chọn một đỉnh v, là đỉnh đầu tiên kề với u mà chưa thăm> < Thông báo thăm v> < Đẩy u trở lại ngăn xếp> 19 < Đẩy tiếp v vào ngăn xếp> End; Until < Ngăn xếp rỗng> Chương trình cài đặt Program Depth_First_Search; const max = 100; var a: array[1..max, 1..max] of Boolean; Free: array[1..max] of Boolean; Trace: array[1..max] of Integer; Stack: array[1..max] of Integer; n, S, F, Last: Integer; procedure Enter; var i, u, v, m: Integer; begin FillChar(a, SizeOf(a), False); Readln(n, m, S, F); for i := 1 to m do begin Readln(u, v); a[u, v] := True; a[v, u] := True; end; end; procedure Init; begin FillChar(Free, n, True); Last := 0; end; procedure Push(V: Integer); begin 20 Inc(Last); Stack[Last] := V; end; function Pop: Integer; begin Pop := Stack[Last]; Dec(Last); end; procedure DFS; var u, v: Integer; begin Write(S, ', '); Free[S] := False; Push(S); repeat u := Pop; for v := 1 to n do if Free[v] and a[u, v] then begin Write(v, ', '); Free[v] := False; Trace[v] := u; Push(u); Push(v); Break; end; until Last = 0; end; procedure Result; begin Writeln; if Free[F] then ', F) Writeln('Not found any path from ', S, ' to else 21 begin while F S do begin Write(F, '[...]... lấy ra khỏi hàng đợi Xếp hàng mua vé xem phim là một hình ảnh trực quan của khái niệm trên, người mới đến thêm vào cuối hàng còn người ở đầu hàng mua vé và ra khỏi hang, vì vậy hàng còn được gọi là cấu trúc FIFO (first in - first out) hay "vào trước - ra trước" 3.2 Các thao tác cơ bản của hàng đợi 3.2.1 Cài đặt hàng đợi bằng mảng Ta dùng một mảng để chứa các phần tử của hàng, khởi đầu phần tử đầu tiên... hệ điều hành, tổ chức bộ đệm bàn phím, … Ví dụ rất dễ thấy là quản lí in trên mạng, nhiều máy tính yêu cầu in đồng thời và ngay cả một máy tính cũng yêu cầu in nhiều lần Nói chung có nhiều yêu cầu in dữ liệu, nhưng máy in không thể đáp ứng tức thời tất cả các yêu cầu đó nên chương trình quản lí in sẽ thiết lập một hàng đợi để quản lí các yêu cầu Yêu cầu nào mà chương trình quản lí in nhận trước nó sẽ... minh rằng biểu thức hậu tố không cần phải có dấu ngoặc vẫn có thể tính được một cách đúng đắn bằng cách đọc lần lượt biểu thức từ trái qua phải và dùng một Stack để lưu kết quả trung gian Bước 1: Khởi động Stack rỗng Bước 2: Đọc lần lượt các phần tử của biểu thức từ trái qua phải, với mỗi phần tử đó ta kiểm tra: - Nếu phần tử này là một toán hạng thì đẩy giá trị của nó vào Stack - Nếu phần tử này là... (Pop) khỏi stack 2.2 Các thao tác cơ bản của ngăn xếp Đối với một ngăn xếp chỉ có hai thao tác cơ bản: thao tác thêm một phần tử vào Stack và thao tác loại bỏ một phần tử khỏi Stack Trong khuôn khổ tài liệu này tác giả chỉ đưa ra cách cài đặt Stack bằng DSLK Stack dùng danh sách liên kết hoàn toàn giống danh sách liên kết thuận, nhưng chỉ có điều khác là khi thêm phần tử mới hay huỷ một phần tử ta luôn... 2.4.2 Tính giá trị một biểu thức dạng hậu tố Biểu thức trung tố, hiểu đơn giản tức là toán tử sẽ được đặt giữa hai toán hạng, dĩ nhiên đây phải là toán tử hai ngôi Vậy dựa vào vị trí của của toán tử, liệu ta có thể biểu diễn biểu thức đại số dưới dạng khác? Câu trả lời là được, và như đã nói, ta có ba cách là biểu thức tiền tố (prefix), trung tố (infix) và hậu tố (postfix) Hãy xem một chút giới thiệu... Trace[F]; end; Writeln(S); end; end; 33 begin Assign(Input, 'GRAPH.INP'); Reset(Input); Assign(Output, 'GRAPH.OUT'); Rewrite(Output); Enter; Init; BFS; Result; Close(Input); Close(Output); end 34 TÀI LIỆU THAM KHẢO PHỤ LỤC Một số bài ứng dụng stack hoặc Queue trên SPOJ: 1 Huyền thoại Lục Vân Tiên (http://vn.spoj.com/problems/MINK/) MINK Dạo này tivi cũng đang chiếu phim Lục Vân Tiên, sẵn tiện lấy luôn ... TÀI LIỆU THAM KHẢO Lê Minh Hoàng; “chuyên đề Cấu trúc liệu Giải thuật” Nguyễn Hữu Tuân, 2007; “Bài giảng Cấu trúc liệu Gải thuật” “Chuyên đề Cấu trúc liệu ; Đại học cần thơ, 2003 Cấu trúc liệu. .. nói danh sách liên kết cấu trúc liệu định nghĩa kiểu đệ quy, định nghĩa nút danh sách có tham chiếu tới khái niệm nút Có nhiều loại danh sách liên kết khác tùy thuộc vào cấu trúc phần tử danh sách... kết sau: Danh sách liên kết cấu trúc liệu bao gồm tập phần tử, phần tử phần nút có chứa liên kết đến phần tử “Mối phần tử phần nút” nút có hai trường, trường gọi liệu (data), trường lại trường

Ngày đăng: 14/10/2015, 14:00

Từ khóa liên quan

Mục lục

  • 1. DANH SÁCH LIÊN KẾT

    • 1.1 Khái niệm

    • 1. 2 Cấu tạo của danh sách liên kết

    • 1.3 Các thao tác cơ bản với danh sách liên kết

      • 1. 3. 1 Khai báo

      • 1.3.2 Khởi tạo danh sách

      • 1.3.3 Bổ sung một nút vào đầu danh sách

      • 1.3.4. Bổ sung một nút vào cuối danh sách

      • 1.3.5 Duyệt danh sách

      • 1.3.6 Bổ sung một nút vào sau nút được trỏ bởi p

      • 1.3.7. Xoá một nút khỏi danh sách

      • 1.4. Mảng hay danh sách liên kết?

      • 1.5. Ví dụ làm việc với danh sách liên kết

      • 2. NGĂN XẾP – STACK

        • 2.1. Khái niệm

        • 2.2 Các thao tác cơ bản của ngăn xếp

        • 2.4. Ứng dụng Stack

          • 2.4.1 Ứng dụng Stack khử đệ quy

          • 2.4.2 Tính giá trị một biểu thức dạng hậu tố

          • 2.4.3 Chuyển biểu thức từ trung tố sang hậu tố

          • 3. HÀNG ĐỢI – Queue

            • 3.1. Khái niệm

            • 3.2 Các thao tác cơ bản của hàng đợi

            • 3.3. So sánh việc cài đặt Queue bằng mảng và danh sách liên kết

            • 3.4 Ứng dụng

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

Tài liệu liên quan