1. Trang chủ
  2. » Trung học cơ sở - phổ thông

Chuyên đề “cấu trúc dữ liệu nâng cao

34 28 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 34
Dung lượng 163,81 KB

Nội dung

Khi giải một bài toán, ta cần định nghĩa tập hợp dữ liệu để biểu diễn dữ liệu vào và kết quả ra. Việc lựa chọn này tùy thuộc vào vấn đề cần giải quyết và những thao tác sẽ tiến hành trên dữ liệu. Có những thuật toán chỉ thích ứng với một cách tổ chức dữ liệu nhất định, nếu sử dụng những cách tổ chức dữ liệu khác sẽ kém hiệu quả hoặc không thể thực hiện được. Chính vì vậy khi tìm kiếm thuật toán giải quyết vấn đề không tách rời bước xây dựng cấu trúc dữ liệu. Chuyên đề “Cấu trúc dữ liệu nâng cao ” sẽ trình bày một số kiểu dữ liệu nâng cao thường được sử dụng.

I ĐẶT VẤN ĐỀ Khi giải toán, ta cần định nghĩa tập hợp liệu để biểu diễn liệu vào kết Việc lựa chọn tùy thuộc vào vấn đề cần giải thao tác tiến hành liệu Có thuật tốn thích ứng với cách tổ chức liệu định, sử dụng cách tổ chức liệu khác hiệu khơng thể thực Chính tìm kiếm thuật tốn giải vấn đề khơng tách rời bước xây dựng cấu trúc liệu Chuyên đề “Cấu trúc liệu nâng cao ” trình bày số kiểu liệu nâng cao thường sử dụng II NỘI DUNG Danh sách (List) Danh sách tập thứ tự phần tử kiểu 1.1 Tổ chức danh sách 1.1.1 Tổ chức danh sách mảng chiều Khi cài đặt mảng chiều ta sử dụng biến nguyên N để lưu số phần tử có danh sách * Các thao tác với danh sách: - Chèn phần tử vào danh sách: Nếu muốn chèn phần tử V vào danh sách vị trí P, ta dồn tất vị trí từ P đến vị trí N sau vị trí, sau đặt V vào vị trí P, tăng số lượng phần tử lên đơn vị - Xóa phần tử khỏi danh sách: Nếu muốn xóa phần tử P giữ nguyên thứ tự, ta dồn tất phần tử từ vị trí P+1 tới vị trí N lên trước vị trí, giảm số lượng phần tử đơn vị 1.1.2 Tổ chức danh sách liên kết nối đơn Danh sách liên kết nối đơn gồm nút nối với theo chiều Mỗi nút ghi gồm hai trường: trường chứa giá trị trường chứa liên kết tới nút Nút gọi chốt danh sách, để duyệt danh sách ta chốt, dựa vào trường liên kết để tiếp gặp giá trị đặc biệt dừng lại * Các thao tác với danh sách: - Chèn phần tử vào danh sách: Nếu muốn chèn nút chứa giá trị V vào danh sách vị trí nút P, ta tạo nút chứa giá trị V, sau tìm nút q đứng trước nút p, thấy chỉnh lại liên kết: q liên kết đến nút mới, nút liên kết tới p, khơng tìm thấy P chốt, ta chỉnh lại liên kết nút liên kết tới chốt (cũ) chốt đặt lại nút - Xóa phần tử khỏi danh sách: Nếu muốn xóa nút P khỏi danh sách liên kết, ta tìm nút q đứng trước nút p danh sách, thấy chỉnh lại liên kết: q liên kết đến nút liền sau p; khơng thấy có nghĩa p nút chốt, ta cần đặt lại chốt nút đứng chốt (cũ) danh sách; Sau giải phóng bọ nhớ cấp phát cho nút p 1.1.3 Tổ chức danh sách liên kết nối kép Danh sách liên kết nối kép gồm nút nối với theo hai chiều Mỗi nút ghi gồm ba trường: trường thứ chứa giá trị, trường thứ hai chứa liên kết tới nút (Next), trường thứ ba chứa liên kết tới nút liền trước (Prev) Danh sách nối kép có hai chốt: Nút gọi First, nút cuối gọi Last Để duyệt danh sách ta có hai cách: Hoặc First, cách duyệt danh sách liên kết nối đơn; Hoặc Last, dựa vào liên kết Prev để sang nút liền trước, đến duyệt đến giá trị đặc biệt (duyệt qua nút đầu) dừng lại Các thao tác với danh sách tương tự danh sách liên kết nối đơn Hàng đợi ngăn xếp 2.1 Ngăn xếp (Stack) Là danh sách tổ chức theo kiểu LIFO (“vào sau, trước”) Trong ngăn xếp, phần tử thêm vào sau lấy khỏi ngăn xếp trước Số lượng phần tử ngăn xếp gọi chiều cao ngăn xếp phản ánh vị trí phần tử cuối vừa nạp vào, biến top quản lý 2.1.1 Tổ chức ngăn xếp 2.1.1.1 Tổ chức ngăn xếp mảng - Ngăn xếp bị tràn bổ sung vào mà số phần tử vượt số lượng tối đa mảng (mảng đầy) - Ngăn xếp rỗng số lượng phần tử thực mảng không - Việc bổ sung phần tử vào ngăn xếp tương đương với thêm phần tử vào cuối mảng - Việc loại bỏ phàn tử khỏi ngăn xếp tương đương với việc loại bỏ phần tử cuối mảng 2.1.1.2 Tổ chức ngăn xếp danh sách liên kết nối đơn kiểu LIFO Khi cài đặt ngăn xếp danh sách liên kết nối đơn kiểu LIFO, ngăn xếp bị tràn vùng khơng gian nhớ dùng cho biến động khơng cịn đủ để thêm phần tử Tuy nhiên, việc kiểm tra khó phụ thuộc vào máy tính ngơn ngữ lập trình, tổ chức ngăn xếp liên kết nối đơn kiểu LIFO 2.2 Hàng đợi (Queue) Là danh sách tổ chức theo kiểu FIFO (“vào trước, trước”) Phần tử nạp vào (đẩy vào) vị trí cuối hàng đợi (biến rear last quản lý vị trí này), phần tử lấy vị trí đầu hàng đợi (biến front first quản lý vị trí này) 2.2.1 Tổ chức hàng đợi 2.2.1.1 Tổ chức hàng đợi mảng Khi mô tả hàng đợi mảng, ta dùng front lưu số phần tử đầu hàng đợi, rear lưu số cuối hàng đợi, khởi tạo hàng đợi rỗng: front:=1 rear:=0; - Để thêm phần tử vào hàng đợi, ta tăng rear lên đưa gía trị vào phần tử thứ rear - Để loại phần tử khỏi hàng đợi, ta tăng rear lên đưa giá trị vào phần tử thứ rear - Để loại phần tử khỏi hàng đợi, ta lấy giá trị vị trí front tăng front lên - Hàng đợi đầy rear tăng lên hết khoảng số mảng - Hàng đợi rỗng front > rear 2.2.1.2 Tổ chức hàng đợi danh sách liên kết nối đơn kiểu FIFO Tương tự tổ chức ngăn xếp danh sách liên kết nối đơn kiểu LIFO, ta không kiểm tra hàng đợi tràn tổ chức danh sách liên kết nối đơn kiểu FIFO [1] Cây (Tree) Cây tập hợp nút, nút có quan hệ phân cấp (thường gọi quan hệ “cha, con”) Có thể cài đặt mảng cấu trúc liên kết Một dạng quan trọng nhị phân Biểu diễn danh sách nhị phân cách tổ chức liệu thường xuyên cập nhật có hiệu toán thống kê động Cây nhị phân (Binary Tree) Mỗi nút có tối đa nhánh gọi trái phải nút Cây nhị phân đầy đủ nhị phân mà nút nhánh có nhánh Cây nhị phân hoàn chỉnh nhị phân đầy đủ mà độ sâu Từ nhị phân hồn chỉnh bỏ số gọi gần hồn chỉnh Cây nhị phân tìm kiếm (BST) Cây nhị phân tìm kiếm nhị phân mà nút chứa khóa Khóa nút khơng nhỏ khóa nhánh trái khơng lớn khóa nhánh phải [2] Hàng đợi ưu tiên (Priority queue) Hàng đợi ưu tiên kiểu danh sách mà phần tử gán với mức độ ưu tiên giúp trình xử lý chúng theo quan hệ chúng Hàng đợi ưu tiên thuận tiện cho việc lấy phần tử ưu tiên liệu luôn cập nhật Heap (hay Binary Heap) hàng đợi ưu tiên thông dụng Heap thường có dạng nhị phân gần hồn chỉnh Có hai loại: MaxHeap MinHeap Trong MaxHeap, nút lưu phần tử danh sách có độ ưu tiên không nhỏ độ ưu tiên phần tử nằm hai nhánh Ngược lại, MinHeap, nút lưu phần tử danh sách có độ ưu tiên khơng lớn độ ưu tiên phần tử nằm hai nhánh Cây khoảng (Interval Tree) Cây khoảng có quan hệ thứ tự phận dùng lưu trữ khoảng sở Cây khoảng cho phép cập nhật, tìm kiếm khoảng hiệu Có thể cài đặt khoảng Heap Ví dụ tốn quản lí dãy số ngun A={a 0, a2, …, an-1} mà dãy số thường xuyên cập nhật, tổ chức khoảng (interval tree) sau: Trên nhị phân nút gán cho đoạn chứa số phần tử dãy Nút gốc đoạn [a0; an-1] chứa phần tử dãy, hai nút gốc tương ứng với hai đoạn liên tiếp: nút trái gốc gán cho đoạn [a 0; (a0+an-1) div 2], nút phải gán cho đoạn [1+(a0+an-1) div 2; an-1]….Cuối nút lá, quản lý đoạn có điểm đầu điểm cuối trùng nhau, nghĩa chứa số nguyên dãy Cây khoảng thường dùng để xử lý liệu khoảng mà khoảng luôn cập nhật thay đổi Một số tốn như: tìm khoảng chứa số k cho trước tìm số lớn nhất, nhỏ chứa khoảng trình cập nhật khoảng Cây mục (BIT - Binary indexed tree) Binary Indexed Trees thường dùng lưu trữ tần số tích luỹ tần số (cộng dồn tần số) liệu thường xuyên cập nhật bảng Nó đáp ứng yêu cầu sau n đối tượng: (1) Yêu cầu 1: cập nhật (lấy ra, nạp vào, sửa đổi giá trị…) đối tượng i? (2) Yêu cầu 2: Tính tổng giá trị (hoặc tần số) đối tượng từ i tới k [2] Bài tập minh họa Bài Sắp tô pô Cho N công việc, công việc i phải làm trước số công việc N cơng việc Hãy xếp lịch thực đủ N công việc Dữ liệu vào từ file XL.IN: Dòng đầu số nguyên dương N Các dòng sau thể quan hệ thứ tự phận: đầu dòng số i, số j i1, ji2, , jis thể công việc i phải làm trước công việc ji1, ji2, , jis Kết ghi file XL.OUT dòng N số hiệu cơng việc làm Ví dụ XL.OUT Gợi ý Thuật tốn tơ pơ (sắp cho bảo đảm thứ tự phận) dùng ngăn xếp sau: Xây dựng đồ thị đỉnh công việc Công việc i làm trước công việc j có cung nối từ đỉnh i tới đỉnh j Các đỉnh khơng có cung tới gọi đỉnh (tương ứng công việc không bị phụ thuộc cơng việc nào) Sau tiến hành bước sau: + Tìm đỉnh bậc nạp vào Stack + Thực vịng lặp: Trong Stack chưa rỗng thì: - Lấy phần tử i đỉnh Stack, đánh dấu xét i, xác nhận mảng chiều T có thêm phần tử i - Xố cung từ i - Nạp đỉnh vào Stack + Nếu số lượng phần tử mảng T N dãy T[1], T[2], , T[N] cách N phần tử cho bảo đảm thứ tự phận Chương trình uses crt; const max = 100; fi = 'xl.in'; fo = 'xl.out'; type m1 = array[1 max] of integer; m2 = array[1 max,1 max] of integer; var t, d, s : m1; a : m2; n, sl, top : byte; g : text; procedure nhap; begin {Lấy giá trị cho biến N mảng A(N,N)} end; function bac_0(i: byte): boolean; begin {Xác định đỉnh i có đỉnh bậc hay khơng} end; function dinhbac0: byte; begin {Dựa vào hàm bac_0, tìm đỉnh bậc chưa đánh dấu end; procedure nap(i: byte); begin {Nạp phần tử i vào stack} end; function lay: byte; begin {Lấy phần tử đỉnh stack khỏi stack} end; procedure hien; var i: byte; begin if sl0 begin i := lay; inc(sl); t[sl]:= i; d[i] := 1; xoa(i); pt := dinhbac0; if pt>0 then nap(pt); end; hien; end; procedure khoitri; begin {Khởi trị mảng t, s, d biến top, sl} end; BEGIN khoitri; nhap; assign(g,fo);rewrite(g); sap_topo; close(g); END Bài Biểu thức hậu tố Các biểu thức toán học chứa phép tính cộng (+), trừ (-), nhân (*), chia (/), dấu ngoặc trái: '(' dấu ngoặc phải: ')' toán hạng viết dạng biểu thức trung tố Ví dụ : T="7.2*8.5(2+3.4)" Biểu thức trung tố tính tốn phải tn theo quy tắc ưu tiên phép tính ưu tiên thứ tự thực phép tính : + thực ngoặc trước, ngồi ngoặc sau + ngoặc thực nhân chia trước, cộng trừ sau Những quy tắc khó xử lý biểu thức có nhiều ngoặc, người ta xây dựng cách biểu diễn khác để máy tính dễ thực tính biểu thức hơn: cách viết biểu thức dạng hậu tố (trong khơng có dấu ngoặc) H="7.2 8.5 * 3.4 + - " Việc tính biểu thức dễ dàng sử dụng ngăn xếp (Stack) Hãy viết chương trình chuyển biểu thức trung tố thành biểu thức hậu tố, sau tính giá trị biểu thức Dữ liệu vào từ tệp “BL4.INP” gồm số dòng, dòng biểu thức trung tố Kết ghi vào tệp “BL4.OUT”, dòng kết tương ứng với dòng tệp liệu vào có dạng sau: Biểu thức trung tố  Biểu thức hậu tố = Giá trị biểu thức Ví dụ: 7.2*8.5-(2+3.4)  7.2 8.5 * 3.4 + - = 54.4 Gợi ý Quy tắc chuyển từ biểu thức trung tố thành biểu thức hậu tố: • Gán biểu thức hậu tố xâu rỗng H :=””(xâu rỗng) • Đọc biểu thức trung tố T từ trái qua phải: + Nếu gặp dấu mở ngoặc '(' nạp vào ngăn xếp + Nếu gặp dấu đóng ngoặc ')' lấy phần tử đỉnh ngăn xếp nối vào đuôi biểu thức hậu tố gặp dấu mở ngoặc nằm ngăn xếp lấy dấu mở ngoặc khỏi ngăn xếp bỏ ( không nối vào H ) +Nếu gặp dấu phép tốn so phép tốn với phép tốn đỉnh ngăn xếp (nếu có); phép tốn ưu tiên phép tốn đỉnh ngăn xếp lấy phép tốn đỉnh ngăn xếp nối vào H, đồng thời nạp phép tốn vào đỉnh ngăn xếp Trong trường hợp ngược lại trường hợp đỉnh ngăn xếp khơng có phép tốn nạp phép toán vào ngăn xếp + Nếu gặp toán hạng nối tốn hạng vào H • Sau đọc xong biểu thức trung tố T, lấy nốt phần tử đỉnh ngăn xếp nối vào đuôi H ngăn xếp rỗng cịn dấu đóng ngoặc '(' Tính biểu thức hậu tố Máy tính dễ dàng tính biểu thức hậu tố theo quy tắc sau : Đọc biểu thức hậu tố từ đầu cuối (từ trái sang phải): • Nếu gặp tốn hạng cho tốn hạng vào ngăn xếp • Nếu gặp dấu phép tốn lấy khỏi ngăn xếp toán hạng thứ toán hạng thứ hai, sau đem tốn hạng thứ hai thực phép toán với toán hạng thứ nhất, kết thu lại cho vào ngăn xếp • Số cuối cịn lại ngăn xếp giá trị biểu thức cần tính Chương trình uses crt; const max = 255; fi ='Bl4.inp'; fo ='Bl4.out'; type stack = array[1 max] of char; var s : stack; t,h : string; i,top : byte; f1,f2 : text; procedure nap(ch : char); begin if top0 then begin h := h+ s[top]+' '; dec(top); end; end; function tl( ch : char) : byte; begin case ch of '(' : tl := 0; '+','-' : tl := 1; '*','/' : tl := 2; end; end; procedure chuyen; var i : byte; function chuyenso : string; var so : string; begin so := ''; while t[i] in ['0' '9','.'] begin so := so+t[i]; inc(i); end; chuyenso := so; dec(i); end; begin h := ''; i := 1; top := 0; while i=tl(t[i]))do lay; nap(t[i]); end else if t[i] in ['0' '9'] then h := h + chuyenso + ' '; end; inc(i); end; while (top>0) and (s[top]'(') lay; end; procedure tinh; var i : byte; a : real; s : array[1 max] of real; function so : real; var so1 : real; xau : string; j,cod : integer; begin j := i; while (h[i]' ') and (imid) and (j>=i)then phu := sum(i,j,mid+1,right,2*d+1) else if (j=i) then phu := sum(i,j,left,mid,2*d) else phu:=sum(i,mid,left,mid,2*d)+sum(mid+1,j,mid+1,right,2*d+1); sum := phu; end; var i : longint; BEGIN assign(f,fi); reset(f); assign(g,fo); rewrite(g); readln(f,n,m); fillchar(t,sizeof(t),0); preprocess(1,n,1); for i:=1 to n write(pos[i],' '); readln; for i:=0 to n-1 begin read(f,value); modify(i+1,value); end; readln(f); for i:=0 to m-1 begin readln(f,ch,u,v); case ch of 'Q': writeln(g,sum(u+1,v+1,1,n,1)); 'C': modify(u+1,v); end; end; close(f); close(g); END Bài MARS Map – Baltic OI 2001 Trong năm 2051, số thám hiểm Hỏa khám phá khu vực khác hành tinh tạo đồ khu vực Bây giờ, BASA (Cơ quan Vũ trụ vùng Baltic) có kế hoạch đầy tham vọng: họ muốn tạo đồ toàn hành tinh Để thực họ cần cố gắng tính tổng diện tích miền bị phủ khu vực đồ có Đây nhiệm vụ bạn Nhiệm vụ 22 Viết chương trình với yêu cầu là: + Đọc miêu tả đồ vùng có từ tệp input MAR.IN + Tính tổng miền bị phủ khu vực có đồ + Viết kết vào tệp output MARS.OUT Dữ liệu vào Dịng tệp MARS.IN có số nguyên N (1 ≤ N ≤ 10000) số đồ có Mỗi dịng N dịng miêu tả đồ Mỗi đồ miêu tả khu vực khám phá được, hình chữ nhật qua số nguyên x 1, y1, x2, y2 ((0 ≤ x1

Ngày đăng: 09/03/2021, 13:55

TỪ KHÓA LIÊN QUAN

w