Giáo trình môn Cấu trúc dữ liệu và giải thuật (Phần 2)

CHƢƠNG 6 : CÂY

6.1. ĐỊNH NGHĨA VÀ KHÁI NIỆM

a. Định nghĩa

Một cây là một tập hữu hạn các nút trong đó có một nút đặc biệt gọi là gốc

(root). Giữa các nút có một quan hệ phân cấp gọi là "quan hệ cha con ".

Có thể định nghĩa cây là một cách đệ quy như sau :

1. Một nút là một cây. Nút đó cũng là gốc của cây ấy

5. Nút n là một nút và T1 , T2 , ., Tk là các cây với n1, n2, ., nk lần lượt là các gốc,

thì một cây mới T sẽ được tạo lập bằng cách cho nút n trở thành cha của nút

n1 , n2 , ., nk; nghĩa là trên gốc lúc đó n1 , n2, ., nk là con của nút n.

Để tiện , người ta cho phép tồn tại một cây không có nút nào, mà ta gọi là cây

rỗng (null tree)

Ví dụ: Mục lục của một cuốn sách của một chương trong sách có cấu trúc của

một cây. Chẳng hạn, mục lục của chương 6 này:

Chương 6 : Cây

6.1 Định nghĩa và các khái niệm

6.2 Cây nhị phân

6.2.1 Định nghĩa và tính chất

6.2.2 Biểu diễn cây nhị phân

6.2.3 Phép duyệt cây nhị phân

6.2.4 Cây nhị phân nối vòng

6.3 Cây tổng quát

6.3.1 Biểu diễn cây tổng quát

6.3.2 Phép duyệt cây tổng quát

6.4 áp dụng

6.4.1 Cây biểu diễn biểu thức

6.4.2 Cây biểu diễn các tập

6.4.3 Các quyết định

Ta có thể biểu diễn bởi một cây có dạng như sau :

* Biểu thức số học x + y * (z- t ) + u/v có thể biểu diễn dưới dạng cây như hình

* Các tập bao nhau có thể biểu diễn như hình 6.4

Đối với cây, chẳng hạn xét cây ở hình 6.1

Nút A được gọi là gốc của cây

B, C, D là gốc của cây con của A

A là cha của B, C, D;

B, C, D là con của A

pdf98 trang | Chia sẻ: Thục Anh | Ngày: 12/05/2022 | Lượt xem: 391 | Lượt tải: 0download
Bạn đang xem trước 20 trang nội dung tài liệu Giáo trình môn Cấu trúc dữ liệu và giải thuật (Phần 2), để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
If Kt_nt(A[i]) then dem := dem +1; return dem; End; b. Bổ sung phần tử vào dãy đã sắp xếp Procedure Bosung(A, n, x) {Bổ sung phần tử có giá trị bằng x vào dãy A đã được sắp xếp không giảm dần} Begin n := n+1; i := n; while (i>1) and (A[i-1]>x) do Begin A[i] := A[i-1]; i := i-1; End; A[i] := x; End; c. Loại bỏ phần tử trong dãy để dãy không có hai phần tử có giá trị bằng nhau Procedure Thanh_loc( A, n) Begin i := 1; while i <n do Begin j := i+1; while ( j  n) do if A[j] = A[i] then Begin for k := j to n-1 do A[k] := A[k+1]; n := n-1; End; else j := j+1; i := i+1; End; End; d. Tìm phần tử xuất hiện nhiều nhất Function Tim(A, n) {Hàm tìm phần tử xuất hiện nhiều nhất trong dãy A} Begin dm :=0; for i:= 1 to n-1 do Begin d :=0; for j :=i+1 to n do if A[i]=A[j] then d := d+1; if d > dm then Begin dm := d; pt := A[i]; End; return pt; End; e. Tìm vị trí xuất hiện đầu tiên và vị trí xuất hiện cuối cùng của số lớn nhất Procedure Tim_vt(A, n) Begin start := 1; finish := 1; for i := 2 to n do if A[i]> A[start] then start := i else if A[i]=A[start] then finish := i; writeln('So lon nhat xuat hien o:'); writeln('Vi tri dau tien:', start); writeln('Vi tri cuoi cung:', finish); End; f. Tìm tất cả các phần tử lớn hơn tổng các phần tử đứng trước nó Procedure Tim_pt(A, n) Begin S := A[1]; k := 1; B[k] := 1; for i:=2 to n do Begin if S < A[i] then Begin k := k+1; B[k] := i; End; S := S+A[i]; End; writeln(' Cac phan tu lon hon tong cac phan tu dung truc no:'); for j := 1 to k do write(A[B[j]]:5); End; g. Tìm vị trí của phần tử đầu tiên bằng một phần tử bất kỳ đứng trước nó trong dãy. Function Tim_vt_pt(A, n) Begin vitri := 0; i := 2; while(i  n) and (vitri = 0) do Begin j := 1; while (j < i) and (vitri = 0) do if A[i] = A[j] then vitri := i else j := j+1; i := i+1; End; return vitri End; h. Tìm ước số chung lớn nhất của các phần tử trong dãy Function USCLN( A, n) { Tìm ước số chung lớn nhất của các phần tử trong dãy} Begin x := USC(A[1], A[2]); for i :=3 to n do Begin y := USC(x, A[i]); x := y; End; return x; End; i. Tìm số lớn thứ nhì Function Max_2( A, n) Begin i := 1; while(i<n) and (A[i]=A[i+1]) do i := i+1; if (i < n) then Begin if A[i] < A[i+1] then Begin M1 := A[i+1]; M2 := A[i]; End; else Begin M1 := A[i]; M2 := A[i+1]; End; for j := i+2 to n do if A[j] > M1 then Begin M2 := M1; M1 := A[j]; End; else if A[j] > M2 then M2 := A[j]; return M2; End; else write(' Khong co so lon thu nhi'); End; 14. Cho một danh sách nối đơn nút đầu trỏ bởi L, mỗi nút trong danh sách lưu trữ thông tin một điểm trong mặt phẳng. Viết các giải thuật thực hiện các công việc sau: a. Tạo danh sách b. Hiển thị danh sách c. Đếm số điểm trong danh sách d. Tìm khoảng cách xa nhất từ các điểm trong danh sách đến gốc toạ độ e. Sắp xếp danh sách theo chiều tăng dần của khoảng cách từ điểm đến gốc toạ độ f. Bổ sung điểm có toạ độ nhập từ bàn phím sao cho danh sách vẫn đảm bảo tính sắp xếp. g. Xoá khỏi danh sách điểm có toạ độ trùng với gốc toạ độ h. Tách ra khỏi danh sách L, danh sách những điểm nằm trên một trục toạ độ nào đó và cho P trỏ vào đầu danh sách đó. Giải: a. Tạo danh sách Procedure Taods(L) Begin L = null; repeat new(p); read(info(p).x); read(info(p).y); link(p) = null; if L = null then L = p else begin link(p) = L; L = p; end; until.. end; b. Hiển thị danh sách Procedure HT(L) Begin p = L; while p ≠ null do begin write(info(p).x,info(p).y); p = link(p) end; end; c. Đếm số điểm trong danh sách Function Dem_nut(L) Begin dem = 0; p = L; while p ≠ null do begin dem = dem +1; p = link(p) end; return dem; end; d. Tìm khoảng cách xa nhất từ các điểm đến gốc toạ độ Function KC_max(L) Begin If L = null then write(„Danh sach rong‟); Else Begin Max := sqrt(info(L).x*info(L).x+info(L).y*info(L).y); p = link(L); while (p ≠ null) do begin kc := sqrt(info(p).x*info(p).x+info(p).y*info(p).y); if max > kc then max := kc; p = link(p); end; return max; end; e. Sắp xếp danh sách điểm theo thứ tự tăng dần khoảng cách từ điểm đến gốc toạ độ Procedure Sapxep( L) Begin If (L = null) or (link(L)=null) then return Else begin p = L; while (link(p) ≠ null) do begin q = link(p); kc1 := sqrt(info(p).x*info(p).x+info(p).y*info(p).y); while q ≠ null do begin kc2 := sqrt(info(q).x*info(q).x+info(q).y*info(q).y); if kc1 > kc2 then begin tg := info(p); info(p) := info(q); info(q):=tg; end; q := link(q); end; p := link(p); end; end; end; f. Bổ sung một điểm mới vào danh sách sao cho vẫn đảm bảo tính sắp xếp Procedure Bo_sung_vao_sau( L, a, b) Begin new <= AVAIL; Info(new).x := a; Info(new).y :=b; Link(new) := null; p := L; kc := sqrt(a*a+b*b); while (p ≠ null) and ( kc > sqrt(info(p).x*info(p).x+info(p).y*info(p).y)) do begin q := p; p := link(p); end; if p = L then begin link(new) := L; L:= new; End else begin link(new) :=p; link(q) := new; end; end; g. Loại bỏ điểm có toạ độ trùng với gốc toạ độ Procedure Loai_bo( L) Begin if (L = null) then return else if (info(L).x=0) and (info(L).y=0) then begin q:= L; L := link(L); q=>Avail; End else begin q := L; p = link(L); while (p ≠ null) do begin if (info(p).x=0) and (info(p).y=0) then begin link(q):=link(p); p=>Avail; p := link(q); end else begin q := link(q); p = link(p); end; end; end; end; h. Tách danh sách Procedure Tach( L, P) Begin P := null; if (L = null) then return else begin while (L ≠ null) and ((info(L).x=0) or (info(L).y=0)) then begin q := L; L := link(L); link(q):= P; P := q; End; r:= L; q = link(L); while (q ≠ null) do begin if (info(q).x=0) or (info(q).y=0) then begin link(r) := link(q); link(q):= P; P := q; q := link(r); end else begin q := link(q); r := link(r); end; end; end; end; 15. Viết các giải thuật thực hiện các công việc sau trên danh sách nối kép có nút cực trái và nút cực phải lần lượt được trỏ bởi L và R: a. Tạo danh sách. b. Đếm số nút có trong danh sách. c. Tìm tới nút thứ k trong danh sách, nếu có nút thứ k thì cho ra địa chỉ nút đó, nếu không thì cho ra địa chỉ null. d. Bổ sung một nút có info = x vào sau nút thứ k. e. Loại bỏ nút đứng trước nút thứ k. Giải: a. Tạo danh sách Procedure Create(L, R) Begin L := R := null; repeat P <= Avail; Read(Info(P)); if L = null then begin L := R := P; LPTR(P) := RPTR(P) := null; end else begin RPTR(R) := P; LPTR(P) := R; R := P; RPTR(R) := null ; end; until End; b. Đếm số nút trong danh sách Function Dem_nut(L, R) Begin P:= L; Dem :=0; While P  null do Begin Dem := Dem +1; P := RPTR(P); End; Return Dem; End; c. Tìm tới nút thứ k Function Search(L, R, k) {Tìm nút thứ k trong danh sách nối kép có nút cực trái và cực phải lần lượt được trỏ bởi các con trỏ L và R} Begin if L = null then return null else Begin dem := 1; P := L; while (P  null) and (dem < k) do P := RPTR(P); return P; End; End; d. Bổ sung một nút có info = x vào sau nút thứ k. Procedure Add(L, R, k, x) { Bổ sung nút có Info = x vào sau nút thứ k trong danh sách nối kép có nút cực trái và cực phải lần lượt được trỏ bởi các con trỏ L và R} Begin P := Search(L, R, k); New <= Avail; Info(New) := x; LPTR(New) := RPTR(New) := null; if (P = null) then if L = null then L := R := New else Begin write('Khong bo sung'); return ; End else if P = R then {Bổ sung vào cuối- thành nút cực phải} Begin RPTR(R) := New; LPTR(New) := R; R := New; End; else {Bổ sung vào giữa} Begin RPTR(New) := RPTR(P); LPTR(New) := P; LPTR(RPTR(P)) := New; RPTR(P) := New; End; End; e. Loại bỏ nút đứng trước nút thứ k. Procedure Remove(L, R, k) { Loại bỏ nút đứng trước nút thứ k trong danh sách nối kép có nút cực trái và cực phải lần lượt được trỏ bởi các con trỏ L và R} Begin P := Search(L, R, k); if (P = null) or (P = L) then Begin write('Khong co nut loai bo'); return ; End else Begin Q := LPTR(P); if Q = L then {Loại bỏ nút cực trái} Begin L := RPTR(L); LPTR(L) := null; End else {Loại bỏ nút ở giữa} Begin RPTR(LPTR(Q)) := RPTR(Q);LPTR(RPTR(Q)) := LPTR(Q); End; Q => Avail; End; End; 16. Cho cây nhị phân cài đặt kiểu móc nối, có nút gốc được trỏ bởi T. Viết các giải thuật thực hiện các công việc sau: a. Xác định số nút có trên cây. b. Xác định số nút lá. c. Xác định chiều sâu(cao) của cây. Giải: a. Xác định số nút có trên cây Function Count_node( T) { Đếm số nút trên cây nhị phân có nút gốc trỏ bởi T} Begin Dem := 0; if T  null then Begin TOP := 0; PUSH (S, TOP, T ); While TOP > 0 do Begin P : = POP (S, TOP); While P  null do Begin Dem := Dem +1; if RPTR (P)  null then PUSH (S, TOP, RPTR (P)) ; P : = LPTR(P); End; End; End; return Dem; End; b Xác định số nút lá cây Function Count_leaf( T) { Đếm số nút trên cây nhị phân có nút gốc trỏ bởi T} Begin Dem := 0; if T  null then Begin TOP := 0; PUSH (S, TOP, T ); While TOP > 0 do Begin P : = POP (S, TOP); While P  null do Begin If (LPTR (P) = null) and (RPTR (P) =null) then Dem := Dem +1; if RPTR (P)  null then PUSH (S, TOP, RPTR (P)) ; P : = LPTR(P); End; End; End; return Dem; End; c. Xác định chiều sâu(cao) của cây. Function Height( T) { Tìm chiều cao của cây nhị phân có nút gốc trỏ bởi T} Begin if T = null then return 0 else if Height(LPTR(T)) > Height(RPTR(T)) then return 1+ Height(LPTR(T)) else return 1+ Height(RPTR(T)); End; 17. Cho cây nhị phân có các nút được duyệt theo thứ tự trước và thứ tự giữa là: Duyệt trước: ABDHKECFG Duyệt giữa : HDKBEAFCG Hãy vẽ cây nhị phân đó. Giải: Từ thứ tự duyệt trước, ta xác định được gốc của cây là A. Từ thứ tự duyệt giữa ta xác định được: - Các nút thuộc cây con trái của cây nút gốc A gồm: Duyệt trước: BDHKE Duyệt giữa : HDKBE - Các nút thuộc cây con phải của cây nút gốc A gồm: Duyệt trước: CFG Duyệt giữa : FCG Thực hiện đệ quy đối với các cây con trái, con phải cho tới khi không còn nút nào ta thu được cây sau: 18. Cho dãy khóa: 30, 10, 25, 8, 40, 6, 17, 50, 35, 45. Vẽ cây nhị phân tìm kiếm ứng với dãy khóa trên. Giải: Theo nguyên tắc tổ chức của cây nhị phân tìm kiếm, mỗi khi bổ sung một nút vào cây ta cần so sánh khoá của nút đó với khoá của các nút có trên cây theo thứ tự từ gốc xuống và bổ sung nút mới vào vị trí thích hợp. Với nguyên tắc trên ta thu được cây nhị phân tìm kiếm như sau: 30, 10, 25, 8, 40, 6, 17, 50, 35, 45. A B C D E F G H K 30 10 40 8 25 45 50 6 17 19. Cho cây nhị phân tìm kiếm có nút gốc được trỏ bởi T. Viết các giải thuật thực hiện các công việc sau a. Tìm giá trị nhỏ nhất của các khoá trên cây b. Hiển thị dãy khoá trên cây theo thứ tự giá trị tăng dần Giải: a. Tìm giá trị nhỏ nhất của các khoá trên cây Theo nguyên tắc tổ chức của cây nhị phân tìm kiếm, ta nhận thấy, nếu cây không rỗng thì nút cực trái trên cây chính là nút chứa khoá có giá trị nhỏ nhất trong tất cả các giá trị khoá trên các nút còn lại. Vậy giải thuật tìm giá trị nhỏ nhất của các khoá trên cây có nút gốc trỏ bởi T như sau: Function Min(T) Begin If T = null then Begin Write(„Cay rong‟); return; End Else Begin P := T; While(LPTR(p) null) do p:= LPTR(p); Return Key(p); End; End; b. Hiển thị dãy khoá trên cây theo thứ tự giá trị tăng dần Procedure Hienthi(T ) {Thủ tục hiển thị dãy khoá trên cây theo thứ tự giá trị tăng dần} Begin if T = null then Begin write ( ' cây rỗng ') ; return; End ; else Begin TOP := 0; P := T; Repeat While P  null do Begin Push(S, TOP, P); P := LPTR(P); End; if TOP > 0 then Begin P : = POP (S, TOP); write(INFO(P)); P := RPTR(P); continue := true; End else continue := false; Until not continue; End; End; 20. Cho dãy khoá: 42 87 3 96 4 0 53 12 66. Cho biết kết quả 5 bước thực hiện sắp xếp đầu tiên dãy khoá trên theo giải thuật sắp xếp: a. Sắp xếp kiểu lựa chọn b. Sắp xếp kiểu thêm dần c. Sắp xếp kiểu nổi bọt d. Sắp xếp kiểu phân đoạn (sắp xếp nhanh) e. Sắp xếp kiểu vun đống Giải: a. Sắp xếp kiểu lựa chọn Ban đầu: 42 87 3 96 4 0 53 12 66 Bước 1: 0 87 3 96 4 42 53 12 66 Bước 2: 0 3 87 96 4 42 53 12 66 Bước 3: 0 3 4 96 87 42 53 12 66 Bước 4: 0 3 4 12 87 42 53 96 66 Bước 5: 0 3 4 12 42 87 53 96 66 b. Sắp xếp kiểu thêm dần Ban đầu: 42 87 3 96 4 0 53 12 66 Bước 1: 42 87 3 96 4 0 53 12 66 Bước 2: 3 42 87 96 4 0 53 12 66 Bước 3: 3 42 87 96 4 0 53 12 66 Bước 4: 3 4 42 87 96 0 53 12 66 Bước 5: 0 3 4 42 87 96 53 12 66 c. Sắp xếp kiểu nổi bọt Ban đầu: 42 87 3 96 4 0 53 12 66 Bước 1: 0 42 87 3 96 4 12 53 66 Bước 2: 0 3 42 87 4 96 12 53 66 Bước 3: 0 3 4 42 87 12 96 53 66 Bước 4: 0 3 4 12 42 87 53 96 66 Bước 5: 0 3 4 12 42 53 87 66 96 d. Sắp xếp kiểu phân đoạn Ban đầu: 42 87 3 96 4 0 53 12 66 Bước 1: (4 12 3 0) 42 (96 53 87 66) Bước 2: (3 0) 4 (12) 42 (96 53 87 66) Bước 3: (0) 3 4 (12) 42 (96 53 87 66) Bước 4: 0 3 4 (12) 42 (96 53 87 66) Bước 5: 0 3 4 12 42 (96 53 87 66) e. Sắp xếp kiểu vun đống * Cây ban đầu: * Cây sau khi vun thành đống 42 87 3 96 4 0 53 12 22 66 96 87 53 66 4 0 3 12 22 42 * Kết quả thực hiện 4 bước sắp xếp đầu tiên Bước 1. Dãy đã sắp: 96, kích thước của đống n = 8, đống chưa sắp: Bước 2. Dãy đã sắp: 87 96 , kích thước của đống n = 7, đống chưa sắp: Bước 3. Dãy đã sắp: 66 87 96, kích thước của đống n = 6, đống chưa sắp: Bước 4. Dãy đã sắp:53 66 87 96, kích thước của đống n = 5, đống chưa sắp: 21. Viết thuật toán sắp xếp ba số hạng đầu tiên của một dãy các số nguyên có chiều dài tuỳ ý theo thứ tự tăng dần. 22. Viết giải thuật tìm cả số lớn nhất và số nhỏ nhất trong dãy hữu hạn các số nguyên. 87 66 53 42 2 4 0 3 12 22 66 42 53 12 2 4 0 3 53 42 3 12 2 4 0 42 12 3 0 4 23. Viết thuật toán tìm từ dài nhất trong một câu tiếng Anh (từ là một xâu các chữ cái, còn câu là một bảng liệt kê các từ cách nhau một khoảng trống) 24. Viết giải thuật tìm kiếm tam phân xác định vị trí một phần tử trong dãy hữu hạn các số nguyên đã được sắp xếp theo thứ tự tăng dần. 25. Viết giải thuật tìm trong dãy hữu hạn các số nguyên số hạng đầu tiên bằng một số hạng nào đó đứng trước nó trong dãy. 26. Viết giải thuật tìm trong dãy hữu hạn các số nguyên tất cả các số hạng lớn hơn tổng tất cả các số hạng đứng trước nó trong dãy. MỘT SỐ CHƢƠNG TRÌNH CÀI ĐẶT CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT BẰNG NGÔN NGỮ LẬP TRÌNH C 1. CHƢƠNG TRÌNH ĐỔI CƠ SỐ SỬ DỤNG STACK Chương trình đổi một số nguyên dương n từ hệ thập phân sang hệ đếm cơ số a, sử dụng Stack cài đặt kiểu kế tiếp (n và a nhập từ bàn phím). #include"conio.h" #include"stdio.h" #define max 100 char s[max]; int top; int full(char s[max],int top) { if(top>=max) return 1; else return 0; } int empty(char s[max],int top) { if(top<=0) return 1; else return 0; } void push(char s[max],int &top,char x) { if(full(s,top)==1) printf("\n stack day"); else { top++; s[top]=x; } } char pop(char s[max],int &top) { if(empty(s,top)==1) printf("\n stack rong"); else { top--; return(s[top+1]); } } void doics(int n,int a) { top=0; do { push(s,top,n%a); n=n/a; } while(n>0); while(empty(s,top)==0) printf("%X",pop(s,top)); } void main() { int a,n; clrscr(); printf("\n nhap he dem co so a="); scanf("%d",&a); printf("\n nhap vao so can doi:"); scanf("%d",&n); printf(“ %d o he dem co so %d la:”,n,a);doics(n,a); getch(); } 2. BIỂU DIỄN ĐA THỨC BẰNG DANH SÁCH NỐI ĐƠN Chương trình biểu diễn đa thức bậc n bằng danh sách nối đơn và thực hiện các phép toán sau: - Nhập đa thức từ bàn phím - Hiển thị đa thức ra màn hình - Tính giá trị đa thức - Nhân đa thức với một số - Rút gọn đa thức - Tính tổng hai đa thức - Tính hiệu hai đa thức - Tính tích hai đa thức - Tính đạo hàm bậc nhất, đạo hàm bậc hai của đa thức - Tìm nguyên hàm của đa thức - Tính tích phân xác định của đa thức #include"math.h" #include"stdio.h" #include"alloc.h" #include"conio.h" #include"stdlib.h" struct dt { int somu; float heso; dt*link; }; //Nhap da thuc dt *nhap() { dt *l,*p, *q; float hs; l=NULL; do { printf("\nHe so:"); scanf("%f",&hs); if (hs!=0) { p=(dt*)calloc(1,sizeof(dt)); p->heso = hs; printf("So mu:"); scanf("%d",&p->somu); p->link=NULL; if(l==NULL) l=p; else q->link=p; q = p; } }while(hs!=0); return(l); } //Hien thi da thuc void hienthi(dt *l) { dt *p; p = l; while(p!=NULL) { if((p->link!=NULL)&&((p->link)->heso>0)) printf("%5.2fx^%d+",p->heso,p->somu); else printf("%5.2fx^%d",p->heso,p->somu); p=p->link; } } //Tinh gia tri da thuc float Gia_tri(dt *l,float x) { dt *p; float value=0; p = l; while(p!=NULL) { value+=p->heso*pow( x,p->somu); p=p->link; } return value; } //Bo sung so hang dt *Bosung(dt *k, float hs, int sm) { dt *d; d=(dt*)calloc(1,sizeof(dt)); d->somu=sm; d->heso=hs; if(k==NULL) { k=d; k->link=NULL; } else { d->link=k; k=d; } return k; } //Cong hai da thuc dt *tong(dt*a,dt*b) { dt *p,*q,*c,*k; p=a; q=b; c=NULL; while((p!= NULL)&&(q!=NULL)) { if(p->somu==q->somu) { if((p->heso+q->heso)!=0) c=Bosung(c,p->heso+q->heso,p->somu); p=p->link; q=q->link; } else if(p->somu>q->somu) { c=Bosung(c,p->heso,p->somu); p=p->link; } else { c=Bosung(c,q->heso,q->somu); q=q->link; } } if(q==NULL) while(p!=NULL) { c=Bosung(c,p->heso,p->somu); p=p->link; } else while(q!=NULL) { c=Bosung(c,q->heso,q->somu); q=q->link; } return c; } //Tinh hieu hai da thuc dt *hieu(dt *a,dt *b) { dt *p,*q,*c,*k; p=a; q=b; c=NULL; while((p!= NULL)&&(q!=NULL)) { if(p->somu==q->somu) { if((p->heso-q->heso)!=0) c=Bosung(c,p->heso-q->heso,p->somu); p=p->link; q=q->link; } else if(p->somu>q->somu) { c=Bosung(c,p->heso,p->somu); p=p->link; } else { c=Bosung(c,-q->heso,q->somu); q=q->link; } } if(q==NULL) while(p!=NULL) { c=Bosung(c,p->heso,p->somu); p=p->link; } else while(q!=NULL) { c=Bosung(c,-q->heso,q->somu); q=q->link; } return c; } dt *tich(dt*a,dt*b) { dt *p,*q,*c,*k; p=a; c=NULL; while(p!= NULL) { q=b; while(q!=NULL) { k=c; while((k!=NULL)&&(k->somu!=p->somu+q->somu)) k=k->link; if(k!=NULL) k->heso=k->heso+p->heso*q->heso; else c=Bosung(c,p->heso*q->heso,p->somu+q->somu); q=q->link; } p=p->link; } return c; } //Dao ham bac nhat dt *Dao_ham(dt*a) { dt *p,*c; p=a; c=NULL; while(p!= NULL) { if(p->somu>0)c=Bosung(c,p->heso*p->somu,p->somu-1); p=p->link; } return c; } //Nguyen ham dt *Nguyen_ham(dt*a) { dt *p,*c; p=a; c=NULL; while(p!= NULL) { c=Bosung(c,p->heso/(p->somu+1),p->somu+1); p=p->link; } return c; } void main() { dt *a,*b,*c; int chon; float x; do { clrscr(); printf("\n1. Dao ham bac nhat"); printf("\n2. Nguyen ham"); printf("\n3. Tinh gia tri da thuc"); printf("\n4. Tong hai da thuc"); printf("\n5. Hieu hai da thuc"); printf("\n6. Tich hai da thuc"); printf("\n7. Ket thuc chuong trinh"); printf("\nChon chuc nang(1->7):"); scanf("%d",&chon); switch(chon) { case 1: printf("\nNhap da thuc can tinh:"); a=nhap(); b=Dao_ham(a); printf("\nDao ham cua da thuc la:");hienthi(b); getch(); break; case 2: printf("\nNhap da thuc can tinh:"); a=nhap(); b=Nguyen_ham(a); printf("\nNguyen ham cua da thuc la:");hienthi(b); getch(); break; case 3: printf("\nNhap da thuc can tinh:"); a=nhap(); printf("x=");scanf("%f",&x); printf("\nGia tri cua da thuc tai x=%5.2f la:%5.2f",x,Gia_tri(a,x)); getch(); break; case 4: printf("\nNhap da thuc thu nhat:"); a=nhap(); printf("\nNhap da thuc thu hai:"); b=nhap(); c=tong(a,b); printf("Tong hai da thuc la:");hienthi(c); getch(); break; case 5: printf("\nNhap da thuc thu nhat:"); a=nhap(); printf("\nNhap da thuc thu hai"); b=nhap(); c=hieu(a,b); printf("Hieu hai da thuc la:");hienthi(c); getch(); break; case 6: printf("\nNhap da thuc thu nhat:"); a=nhap(); printf("\nNhap da thuc thu hai"); b=nhap(); c=tich(a,b); printf("Tich hai da thuc la:");hienthi(c); getch(); break; case 7:exit(1); } }while (chon!=7); } 3. CÀI ĐẶT ĐA DANH SÁCH BIẺU DIỄN MA TRẬN THƢA Chương trình cài đặt cấu trúc đa danh sách biểu diễn ma trận thưa, nhập vào từ bàn phím 2 ma trận thưa, tính tích hai ma trận và in ma trận kết quả ra màn hình. Chƣơng trình minh hoạ #include #include #include struct node { node *left,*up; int v,r,c; }; node *arow[10],*acol[10],*brow[10],*bcol[10],*crow[10],*ccol[10]; struct mt { int m,n,k; }; void input(mt &A) { printf("So hang:");scanf("%d",&A.m); printf("So cot:");scanf("%d",&A.n); printf("So phan tu khac khong:");scanf("%d",&A.k); } void createA(mt A) { int i,value,row,col; node *p,*q; for(i=1;i<=A.m;i++) { arow[i]=(node*)calloc(1,sizeof(node)); arow[i]->c=0; arow[i]->left=arow[i]; } for(i=1;i<=A.n;i++) { acol[i]=(node*)calloc(1,sizeof(node)); acol[i]->r=0; acol[i]->up=acol[i]; } for(i=1;i<=A.k;i++) { printf("Gia tri phan tu:");scanf("%d",&value); printf("Chi so hang:");scanf("%d",&row); printf("Chi so cot:");scanf("%d",&col); p=(node*)calloc(1,sizeof(node)); p->v=value; p->r=row; p->c=col; q=arow[p->r]; while(p->cleft)->c) q=q->left; p->left=q->left; q->left=p; q=acol[p->c]; while(p->rup)->r) q=q->up; p->up=q->up; q->up=p; } } void createB(mt B) { int i,value,row,col; node *p,*q; for(i=1;i<=B.m;i++) { brow[i]=(node*)calloc(1,sizeof(node)); brow[i]->c=0; brow[i]->left=brow[i]; } for(i=1;i<=B.n;i++) { bcol[i]=(node*)calloc(1,sizeof(node)); bcol[i]->r=0; bcol[i]->up=bcol[i]; } for(i=1;i<=B.k;i++) { printf("Gia tri phan tu:");scanf("%d",&value); printf("Chi so hang:");scanf("%d",&row); printf("Chi so cot:");scanf("%d",&col); p=(node*)calloc(1,sizeof(node)); p->v=value; p->r=row; p->c=col; q=brow[p->r]; while(p->cleft)->c) q=q->left; p->left=q->left; q->left=p; q=bcol[p->c]; while(p->rup)->r) q=q->up; p->up=q->up; q->up=p; } } void display(node *q) { node *p; p=q->left; while(p!=q) { printf("%3d cot %d;",p->v,p->c); p=p->left; } } void ht(mt A) { int i; for(i=1;i<=A.m;i++) { printf("\nCac phan tu tren hang %d\n",i); display(arow[i]); } } void multi(mt A, mt B, mt &C) { node *p,*q,*t; int i,j,result; if(A.n==B.m) { C.m=A.m; C.n=B.n; for(i=1;i<=C.m;i++) { crow[i]=(node*)calloc(1,sizeof(node)); crow[i]->c=0; crow[i]->left=crow[i]; } for(i=1;i<=C.n;i++) { ccol[i]=(node*)calloc(1,sizeof(node)); ccol[i]->r=0; ccol[i]->up=ccol[i]; } for(i=1;i<=A.m;i++) for(j=1;j<=B.n;j++) { p=arow[i]->left; q=bcol[j]->up; result=0; while((p->c!=0)&&(q->r!=0)) if(p->c>q->r) p=p->left; else if(p->cr) q=q->left; else { result+=p->v*q->v; p=p->left; q=q->up; }

Các file đính kèm theo tài liệu này:

  • pdfgiao_trinh_mon_cau_truc_du_lieu_va_giai_thuat_phan_2.pdf