Giáo trình cấu trúc dữ liệu và giải thuật (nghề ứng dụng phần mềm trình độ cao đẳng)

57 5 0
Giáo trình cấu trúc dữ liệu và giải thuật (nghề ứng dụng phần mềm   trình độ cao đẳ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

UDPM-CĐ-MH11-CTDL> TUYÊN BỐ BẢN QUYỀN Tài liệu thuộc loại sách giáo trình nên nguồn thơng tin phép dùng nguyên trích dùng cho mục đích đào tạo tham khảo Mọi mục đích khác mang tính lệch lạc sử dụng với mục đích kinh doanh thiếu lành mạnh bị nghiêm cấm LỜI GIỚI THIỆU Kiến thức môn học Cấu trúc liệu giải thuật tản người muốn tìm hiểu sâu Công nghệ thông tin đặt biệt việc lập trình để giải tốn máy tính điện tử Các cấu trúc liệu giải thuật xem yếu tố quan trọng lập trình, câu nói tiếng Niklaus Wirth: Chương trình = Cấu trúc liệu + Giải thuật (Programs = Data Structures + Algorithms) Nắm vững cấu trúc liệu giải thuật sở để sinh viên tiếp cận với việc thiết kế xây dựng phần mềm sử dụng cơng cụ lập trình đại Cấu trúc liệu xem phương pháp lưu trữ liệu máy tính nhằm sử dụng cách có hiệu liệu Và để sử dụng liệu cách hiệu cần phải có thuật tốn áp dụng liệu Do vậy, cấu trúc liệu giải thuật yếu tố khơng thể tách rời có liên quan chặt chẽ với Việc lựa chọn cấu trúc liệu ảnh hưởng lớn tới việc lựa chọn áp dụng giải thuật Về nguyên tắc, cấu trúc liệu giải thuật biểu diễn cài đặt ngôn ngữ lập trình đại Tuy nhiên, để có phân tích sâu sắc mơ phạm, có kết thực tế hơn, chúng tơi sử dụng ngôn ngữ tựa Pascal để minh hoạ cho cấu trúc liệu thuật tốn Mặc dầu có nhiều cố gắng, không tránh khỏi khiếm khuyết, mong nhận đóng góp ý kiến độc giả để giáo trình hồn thiện Cần Thơ, ngày 17 tháng 06 năm 2018 Tham gia biên soạn Chủ biên Nguyễn Phát Minh MỤC LỤC TRANG LỜI GIỚI THIỆU MỤC LỤC GIÁO TRÌNH MƠN HỌC/MƠ ĐUN BÀI 1: THIẾT KẾ VÀ PHÂN TÍCH GIẢI THUẬT Mã bài: MH11 - 01 Mở đầu Thiết kế giải thuật Phân tích giải thuật Một số giải thuật BÀI 2: CÁC KIỂU DỮ LIỆU CƠ SỞ 11 Mã bài: MH11 - 02 11 Các kiểu liệu 11 Kiểu liệu có cấu trúc 13 Kiểu tập hợp 15 BÀI 3: MẢNG, DANH SÁCH VÀ CÁC KIỂU DỮ LIỆU TRỪU TƯỢNG 17 Mã bài: MH11 - 03 17 Mảng 17 Danh sách liên kết 18 Các kiểu liệu trừu tượng 22 BÀI 4: CÂY 32 Mã bài: MH11 - 04 32 Khái niệm 32 Cây nhị phân 33 BÀI 5: SẮP XẾP 43 Mã bài: MH11 - 05 43 Sắp xếp kiểu chọn, chèn, bọt 43 Sắp xếp kiểu phân đoạn 46 Sắp xếp kiểu hòa nhập 46 Kiểm tra 47 BÀI 6: TÌM KIẾM 48 Mã bài: MH11 - 06 48 Tìm kiếm 48 Tìm kiếm nhị phân 50 Cây tìm kiếm nhị phân 51 TÀI LIỆU THAM KHẢO 57 GIÁO TRÌNH MƠN HỌC/MƠ ĐUN Tên mơn học/mơ đun: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT Mã môn học/mô đun: MH 11 Vị trí, tính chất, ý nghĩa vai trị mơn học/mơ đun: _ _ _ Vị trí: sau học xong mơn học Tin học, Lập trình Tính chất: Cấu trúc liệu giải thuật môn sở nghề bắt buộc Ý nghĩa vai trị mơn học/mơ đun: Mục tiêu môn học/mô đun: _ Kiến thức: - Hiểu mối quan hệ cấu trúc liệu giải thuật việc xây dựng chương trình; Hiểu ý nghĩa, cấu trúc, cách khai báo, thao tác loại cấu trúc liệu: mảng, danh sách liên kết, giải thuật xử lý cấu trúc liệu đó; _ Kỹ năng: _ Xây dựng cấu trúc liệu mô tả tường minh giải thuật cho số toán ứng dụng cụ thể; - Cài đặt số giải thuật ngơn ngữ lập trình C; Về lực tự chủ trách nhiệm: - Coi việc học môn tảng cho môn học chuyên mơn tiếp theo, nghiêm túc tích cực việc học lý thuyết làm tập, chủ động tìm kiếm nguồn tài liệu liên quan đến môn học - Nội dung môn học/mô đun: Thời gian Tên chương, mục Số TT I II Tổng số Lý thuyết Chương 1: Thiết kế phân tích giải thuật 12 Mở đầu Thực hành, Kiểm tra* Bài tập (LT TH) 0.5 0.5 0 Thiết kế giải thuật 0.5 0.5 0 Phân tích giải thuật Một số giải thuật Chương 2: Các kiểu liệu sở 12 III IV V VI Các kiểu liệu 1 Kiểu liệu có cấu trúc Kiểu tập hợp Chương 3: Mảng, danh sách kiểu liệu trừu tượng 16 11 Mảng Danh sách liên kết Các kiểu liệu trừu tượng Kiểm tra 0 Chương 4: Cây 14 Khái niệm 1 0 Cây nhị phân Một số toán ứng dụng Kiểm tra 0 Chương 5: Sắp xếp 16 11 Sắp xếp kiểu chọn, chèn, bọt Sắp xếp kiểu phân đoạn Sắp xếp kiểu hòa nhập Kiểm tra 0 Chương 6: Tìm kiếm 16 Tìm kiếm 2 Tìm kiếm nhị phân Cây tìm kiếm nhị phân Kiểm tra 0 90 30 56 Tổng cộng BÀI 1: THIẾT KẾ VÀ PHÂN TÍCH GIẢI THUẬT Mã bài: MH11 - 01 Giới thiệu: Tổng quan giải thuật Đầu tiên cách phân tích vấn đề, từ thực tiễn chương trình, cách thiết kế giải pháp cho vấn đề theo cách giải máy tính Tiếp theo, phương pháp phân tích, đánh giá độ phức tạp thời gian thực giải thuật xem xét chương Mục tiêu:  Hiểu mối quan hệ cấu trúc liệu giải thuật;  Biết cách tư tiến trình phân tích thiết kế thuật toán;  Biết cách đánh giá độ phức tạp thuật toán;  Hiểu số giải thuật bản;  Viết tường minh số giải thuật;  Nghiêm túc, tỉ mỉ việc học vận dụng vào làm tập Nội dung chính: Mở đầu Có thể nói khơng có chương trình máy tính mà khơng có liệu để xử lý Dữ liệu liệu đưa vào (input data), liệu trung gian liệu đưa (output data) Do vậy, việc tổ chức để lưu trữ liệu phục vụ cho chương trình có ý nghĩa quan trọng tồn hệ thống chương trình Việc xây dựng cấu trúc liệu định lớn đến chất lượng công sức người lập trình việc thiết kế, cài đặt chương trình Thiết kế giải thuật Khái niệm giải thuật hay thuật giải mà nhiều cịn gọi thuật tốn dùng để phương pháp hay cách thức (method) để giải vần đề Giải thuật minh họa ngôn ngữ tự nhiên (natural language), sơ đồ (flow chart) mã giả (pseudo code) Trong thực tế, giải thuật thường minh họa hay thể mã giả tựa hay số ngơn ngữ lập trình (thường ngơn ngữ mà người lập trình chọn để cài đặt thuật tốn), chẳng hạn C, Pascal, ? Khi xác định cấu trúc liệu thích hợp, người lập trình bắt đầu tiến hành xây dựng thuật giải tương ứng theo yêu cầu toán đặt sở cấu trúc liệu chọn Để giải vấn đề có nhiều phương pháp, lựa chọn phương pháp phù hợp việc mà người lập trình phải cân nhắc tính tốn Sự lựa chọn góp phần đáng kể việc giảm bớt cơng việc người lập trình phần cài đặt thuật tốn ngơn ngữ cụ thể Phân tích giải thuật Mối quan hệ cấu trúc liệu Giải thuật minh họa đẳng thức: Cấu trúc liệu + Giải thuật = Chương trình Như vậy, có cấu trúc liệu tốt, nắm vững giải thuật thực việc thể chương trình ngơn ngữ cụ thể vấn đề thời gian Khi có cấu trúc liệu mà chưa tìm thuật giải khơng thể có chương trình ngược lại khơng thể có Thuật giải chưa có cấu trúc liệu Một chương trình máy tính hồn thiện có đầy đủ Cấu trúc liệu để lưu trữ liệu Giải thuật xử lý liệu theo yêu cầu toán đặt 3.1 Phân tích tính đắn Thiết kế xong thuật tốn câu hỏi ln ln phải có thuật tốn thiết kế chưa? Cách đơn giản mà sử dụng thơng dụng viết chương trình cho thuật tốn thiết kế chạy thử chương trình với nhiều liệu vào cụ thể (tests) để kiểm tra liệu có chuẩn xác hay chưa Tuy nhiên, cách khẳng định thuật toán với trường hợp cụ thể mà thơi Có cách khác chứng minh thuật tốn chứng minh tốn học Nhưng với cách chứng minh thuật toán toán học phức tạp nhiều địi hỏi nhiều kiến thức tổng hợp toán học tin học cộng với khả người thực việc chứng minh thuật tốn 3.2 Phân tích tính đơn giản Đối với chương trình dùng vài lần yêu cầu giải thuật đơn giản ưu tiên cần giải thuật dễ hiểu, dễ cài đặt, không đề cao vấn đề thời gian chạy chạy vài lần Tuy nhiên, chương trình sử dụng nhiều lần, yêu cầu tiết kiệm thời gian đặc biệt ưu tiên Tuy nhiên, thời gian thực chương trình lại phụ thuộc vào nhiều yếu tố như: cấu hình máy tính, ngơn ngữ sử dụng, trình biên dịch, liệu đầu vào, … Do ta so sánh giải thuật implement, chưa chương trình chạy nhanh có giải thuật tốt “Độ phức tạp thuật toán” sinh để giải vấn đề Một số giải thuật 4.1 Hoán vị hai phần tử 1.Bài toán INPUT: Nhập giá trị cho hai biến A B OUTPUT: Xuất biến A B với hai giá trị hốn đổi Ví dụ: Nhập A= 12, B = 50 in A = 50, B = 12 Trao đổi giá trị biến A B thông qua biến trung gian tam : B0 Bắt đầu B1 Nhập giá trị cho A B B2 Biến tam lấy giá trị A ( Gọi gán giá trị A cho tam , viết tam := A ) B3 A lấy giá trị B ( Gọi gán giá trị B cho A , viết A := B ) B4 B lấy giá trị tam ( Gọi gán giá trị tam cho B , viết B := tam ) B5 Thông báo kết B6 Kết thúc 4.2 Tìm số lớn nhất, nhỏ Tìm phần tử có giá trị LỚN Tìm phần tử có giá trị NHỎ dãy dãy số số * Ý tưởng: * Ý tưởng: + Khởi tạo giá trị MAX = a1 + Khởi tạo giá trị MIN = a1 + Lần lượt với i = đến N, so sánh số + Lần lượt với i = đến N, so sánh số với với MAX, > MAX MAX = MIN, > MIN MIN = Xác định toán: Xác định toán: Input: N, a1, a2, , aN Input: N, a1, a2, , aN Output: Phần tử có giá trị lớn Output: Phần tử có giá trị nhỏ Xây dựng thuật toán: Xây dựng thuật toán: Bước 1: Nhập N dãy a1, a2, , aN Bước 1: Nhập N dãy a1, a2, , aN Bước 2: Max Bước 2: Min a1, i 2; a1 , i 2; Bước 3: Nếu i > N đưa giá trị Max Bước 3: Nếu i > N đưa giá trị Min rồi kết thúc; kết thúc; Bước 4: Nếu > Max Max Bước 5: i ai; Bước 4: Nếu =0)&&(a[j]>a[j+1])) { a[j+1] = a[j]; j ; } if (j!=i-1) a[j+1] = temp; } 1.3 Thuật toán xếp bọt (Bubble Sort): - Tư tưởng: + Đi từ cuối mảng đầu mảng, trình phần tử (đứng phía sau) nhỏ phần tử đứng (trước) theo ngun tắc bọt khí phần tử nhẹ bị "trồi" lên phía phần tử nặng (hai phần tử đổi chỗ cho nhau) Kết phần tử nhỏ (nhẹ nhất) đưa lên (trồi lên) bề mặt (đầu mảng) nhanh + Sau lần đưa phần tử trồi lên chỗ Do vậy, sau N-1 lần tất phần tử mảng M có thứ tự tăng - Thuật toán: B1: First = B2: IF (First = N) Thực Bkt B3: ELSE B3.1: Under = N B3.2: If (Under = First) Thực B4 B3.3: Else B3.3.1: if (M[Under] < M[Under - 1]) Swap(M[Under], M[Under - 1]) B3.3.2: Under-B3.3.3: Lặp lại B3.2 B4: First++ B5: Lặp lại B2 Bkt: Kết thúc - Cài đặt thuật tốn: Hàm BubbleSort có prototype sau: void BubbleSort(T M[], int N); //Đổi chỗ phần tử cho 44 Hàm thực việc xếp N phần tử có kiểu liệu T mảng M theo thứ tự tăng dựa thuật toán xếp bọt Nội dung hàm sau: void BubbleSort(T M[], int N) { for (int I = 0; I < N-1; I++) for (int J = N-1; J > I; J ) if (M[J] < M[J-1]) Swap(M[J], M[J-1]); return; } Hàm Swap có prototype sau: void Swap(T????X, T????Y); Hàm thực việc hoán vị giá trị hai phần tử X Y cho Nội dung hàm sau: void Swap(T????X, T????Y) { T Temp = X; X = Y; Y = Temp; return; } - Ví dụ minh họa thuật toán: Giả sử ta cần xếp mảng M có 10 phần tử sau (N = 10): M: 15 10 20 10 25 35 22 Ta thực lần (N - = 10 - = 9) để xếp mảng M: - Phân tích thuật tốn: + Trong trường hợp: Số phép gán: G = Số phép so sánh: S = (N-1) + (N-2) + ? + = ½N(N-1) + Trong trường hợp tốt nhất: mảng ban đầu có thứ tự tăng Số phép hốn vị: Hmin = + Trong trường hợp xấu nhất: mảng ban đầu có thứ tự giảm Số phép hoán vị: Hmin = (N-1) + (N-2) + ? + = ½N(N-1) + Số phép hốn vị trung bình: Havg = ¼N(N-1) - Nhận xét thuật tốn bọt: + Thuật toán xếp bọt đơn giản, dễ hiểu dễ cài đặt 45 30 + Trong thuật toán xếp bọt, lần từ cuối mảng đầu mảng phần tử nhẹ trồi lên nhanh phần tử nặng lại "chìm" xuống chậm chạp khơng tận dụng chiều xuống (chiều từ đầu mảng cuối mảng) + Thuật tốn bọt khơng phát đoạn phần tử nằm hai đầu mảng nằm vị trí để giảm bớt quãng đường lần Sắp xếp kiểu phân đoạn Phương pháp: Dùng giải pháp đệ quy (chia để trị) _ Bước 1: Phân hoạch mảng A ban đầu thành mảng B C cho bi  cj bi B, cj C _ Bước 2: Sắp xếp mảng B đệ quy _ Bước 3: Sắp xếp mảng C đệ quy Điều kiện dừng: mảng cần có phần tử _ Vì B, C bi xem cj nên mảng A Sắp xếp kiểu hòa nhập Phương pháp: Cũng sử dụng giải pháp chia để trị _ _ _ Bước 1: Chia mảng A ban đầu thành mảng B C Bước 2, 3: Sắp xếp mảng B C đệ quy (Điều kiện dừng: mảng cần có phần tử) Bước 4: Trộn (merge) mảng B, C thành mảng A Thuật toán: int Partition(int a[], int p, int r) { int t; // phân hoạch return t; } void QuickSort(int a[], int p, int r) { int t = Partition(a, p, r); if (p< t-1) QuickSort(a, p, t-1); if (t+1< r) QuickSort(a, t+1, r); 46 } Kiểm tra 47 BÀI 6: TÌM KIẾM Mã bài: MH11 - 06 Giới thiệu: Trong hầu hết hệ lưu trữ, quản lý liệu, thao tác tìm kiếm thường thực nhiều để khai thác thơng tin Các thuật tốn xếp tìm kiếm với kỹ thuật sử dụng coi kỹ thuật sở cho lập trình máy tính Mục tiêu: _ Hiểu ý tưởng, thuật toán chi tiết số phương pháp tìm kiếm; _ Áp dụng số thuật tốn tìm kiếm vào dãy khóa cụ thể; _ Cài đặt thuật tốn tìm kiếm ngơn ngữ lập trình bậc cao; _ Nghiêm túc, tỉ mỉ, sáng tạo việc học vận dụng vào làm tập Nội dung chính: Tìm kiếm Thuật tốn tìm tuyến tính cịn gọi Thuật tốn tìm kiếm (Sequential Search) a Tư tưởng: Lần lượt so sánh phần tử mảng M với giá trị X phần tử tìm đến phần tử có giá trị X duyệt qua hết tất phần tử mảng M kết thúc b Thuật toán: B1: k = B2: IF M[k]?? X AND k?? N B2.1: k++ B2.2: Lặp lại B2 B3: IF k?? N Tìm thấy vị trí k B4: ELSE //Duyệt từ đầu mảng //Nếu chưa tìm thấy chưa duyệt hết mảng Khơng tìm thấy phần tử có giá trị X B5: Kết thúc c Cài đặt thuật tốn: Hàm LinearSearch có prototype: int LinearSearch (T M[], int N, T X); Hàm thực việc tìm kiếm phần tử có giá trị X mảng M có N phần tử Nếu tìm thấy, hàm trả số nguyên có giá trị từ đến N-1 vị trí tương ứng phần tử tìm thấy Trong trường hợp ngược lại, hàm trả giá trị -1 (không tìm thấy) Nội dung hàm sau: int LinearSearch (T M[], int N, T X) 48 { int k = 0; while (M[k] != X??? k < N) k++; if (k < N) return (k); return (-1); } d Phân tích thuật tốn: - Trường hợp tốt phần tử mảng có giá trị X: Số phép gán: Gmin = Số phép so sánh: Smin = + = - Trường hợp xấu khơng tìm thấy phần tử có giá trị X: Số phép gán: Gmax = Số phép so sánh: Smax = 2N+1 - Trung bình: Số phép gán: Gavg = Số phép so sánh: Savg = (3 + 2N + 1) : = N + e Cải tiến thuật toán: Trong thuật toán trên, bước lặp cần phải thực phép so sánh để kiểm tra tìm thấy kiểm sốt hết mảng q trình duyệt mảng Chúng ta giảm bớt phép so sánh thêm vào cuối mảng phần tử cầm canh (sentinel/stand by) có giá trị X để nhận diện hết mảng duyệt mảng, thuật tốn cải tiến lại sau: B1: k = B2: M[N+1] = X B3: IF M[k]?? X B3.1: k++ B3.2: Lặp lại B3 B4: IF k < N Tìm thấy vị trí k B5: ELSE //Phần tử cầm canh //k = N song phần tử cầm canh Khơng tìm thấy phần tử có giá trị X B6: Kết thúc Hàm LinearSearch viết lại thành hàm LinearSearch1 sau: int LinearSearch1 (T M[], int N, T X) { int k = 0; M[N] = X; while (M[k] != X) k++; 49 if (k < N) return (k); return (-1); } f Phân tích thuật tốn cải tiến: - Trường hợp tốt phần tử mảng có giá trị X: Số phép gán: Gmin = Số phép so sánh: Smin = + = - Trường hợp xấu khơng tìm thấy phần tử có giá trị X: Số phép gán: Gmax = Số phép so sánh: Smax = (N+1) + = N + - Trung bình: Số phép gán: Gavg = Số phép so sánh: Savg = (2 + N + 2) : = N/2 + Như vậy, thời gian thực phép gán khơng đáng kể thuật toán cải tiến chạy nhanh thuật toán nguyên thủy - Tìm kiếm nhị phân Thuật tốn tìm tuyến tính tỏ đơn giản thuận tiện trường hợp số phần tử dãy không lớn Tuy nhiên, số phần tử dãy lớn, chẳng hạn tìm kiếm tên khách hàng danh bạ điện thoại thành phố lớn theo thuật tốn tìm thực nhiều thời gian Trong thực tế, thông thường phần tử dãy có thứ tự, thuật tốn tìm nhị phân sau rút ngắn đáng kể thời gian tìm kiếm dãy có thứ tự Trong thuật tốn giả sử phần tử dãy có thứ tự tăng (không giảm dần), tức phần tử đứng trước ln có giá trị nhỏ (khơng lớn hơn) phần tử đứng sau Khi đó, X nhỏ giá trị phần tử đứng dãy (M[Mid]) X tìm thấy nửa đầu dãy ngược lại, X lớn phần tử M[Mid] X tìm thấy nửa sau dãy a Tư tưởng: Phạm vi tìm kiếm ban đầu từ phần tử dãy (First = 1) phần tử cuối dãy (Last = N) So sánh giá trị X với giá trị phần tử đứng dãy M M[Mid] Nếu X = M[Mid]: Tìm thấy Nếu X < M[Mid]: Rút ngắn phạm vi tìm kiếm nửa đầu dãy M (Last = Mid1) Nếu X > M[Mid]: Rút ngắn phạm vi tìm kiếm nửa sau dãy M (First = Mid+1) Lặp lại trình tìm thấy phần tử có giá trị X phạm vi tìm kiếm khơng cịn (First > Last) b Thuật toán đệ quy (Recursion Algorithm): 50 B1: First = B2: Last = N B3: IF (First > Last) B3.1: Khơng tìm thấy B3.2: Thực Bkt B4: Mid = (First + Last)/ B5: IF (X = M[Mid]) //Hết phạm vi tìm kiếm B5.1: Tìm thấy vị trí Mid B5.2: Thực Bkt B6: IF (X < M[Mid]) Tìm đệ quy từ First đến Last = Mid - B7: IF (X > M[Mid]) Tìm đệ quy từ First = Mid + đến Last Bkt: Kết thúc c Cài đặt thuật toán đệ quy: Hàm BinarySearch có prototype: int BinarySearch (T M[], int N, T X); Hàm thực việc tìm kiếm phần tử có giá trị X mảng M có N phần tử có thứ tự tăng Nếu tìm thấy, hàm trả số nguyên có giá trị từ đến N-1 vị trí tương ứng phần tử tìm thấy Trong trường hợp ngược lại, hàm trả giá trị -1 (khơng tìm thấy) Hàm BinarySearch sử dụng hàm đệ quy RecBinarySearch có prototype: int RecBinarySearch(T M[], int First, int Last, T X); Hàm RecBinarySearch thực việc tìm kiếm phần tử có giá trị X mảng M phạm vi từ phần tử thứ First đến phần tử thứ Last Nếu tìm thấy, hàm trả số nguyên có giá trị từ First đến Last vị trí tương ứng phần tử tìm thấy Trong trường hợp ngược lại, hàm trả giá trị -1 (khơng tìm thấy) Cây tìm kiếm nhị phân 3.1 Định nghĩa Cây tìm kiếm ứng với n khóa {\displaystyle k_{1},k_{2}, k_{n}} {\displaystyle k_{1},k_{2}, k_{n}} nhị phân mà nút gán khóa cho với mỗi nút k: Mọi khóa trái nhỏ khóa nút k Mọi khóa phải lớn khóa nút k Cây tìm kiếm nhị phân cấu trúc liệu sử dụng để xây dựng cấu trúc liệu trừu tượng tập hợp, đa tập hợp, dãy kết hợp Nếu BST có chứa giá trị giống biểu diễn đa tập hợp Cây loại sử dụng bất đẳng thức không nghiêm ngặt Mọi nút trái có khóa nhỏ khóa nút cha, nút phải có nút lớn khóa nút cha Nếu BST không chứa giá trị giống biểu diễn tập hợp đơn trị lý thuyết tập hợp Cây loại sử dụng bất đẳng thức nghiêm ngặt 51 Mọi nút trái có khóa nhỏ khóa nút cha, nút phải có nút lớn khóa nút cha Việc chọn đưa giá trị vào phải (hay trái) tùy theo người Một số người đưa giá trị vào hai phía, việc tìm kiếm trở nên phức tạp 3.2 Cài đặt tìm kiếm nhị phân Khởi tạo (init)  Khởi tạo node: cấp phát nhớ cho node, truyền data cần lưu trữ, gán pLeft = pRight = NULL  Khởi tạo : khởi tạo gán root = NULL struct NODE { int data; NODE* pLeft; NODE* pRight; }; NODE* CreateNode(int x) { NODE* p = new NODE(); 10 p->data = x; 11 p->pLeft = p->pRight = NULL; 12 return p; 13 } Chèn (insertion) Chèn node chứa liệu vào có gốc root trả địa node chèn, việc chèn liệu phải dựa đặc điểm nhị phân tìm kiếm VD: Input: { 40, 5, 35, 45, 15, 56, 48, 13, 16, 49, 47 }; 52  Tìm vị trí node cần chèn : NODE* FindInsert(NODE* root, int x) { if (root == NULL) { return NULL; } NODE* p = root; NODE* f = p; while (p != NULL) 10 { 11 f = p; 12 if (p->data > x) 13 { 14 p = p->pLeft; 15 } 16 else 17 { 18 19 p = p->pRight; } 53 20 } 21 return f; 22 }  Chèn node : void InsertNode(NODE* &root, int x) { NODE* n = CreateNode(x); if (root == NULL) { root = n; return; } else 10 { 11 NODE* f = FindInsert(root, x); 12 if (f != NULL) 13 { 14 if (f->data > x) 15 { 16 f->pLeft = n; 17 } 18 else 19 { 20 f->pRight = n; 21 } 22 23 } } 24 } Tạo nhị phân tìm kiếm void CreateTree(NODE* &root, int a[], int n) { 54 for (int i = 0; i < n; i++) { InsertNode(root, a[i]); } } Tìm kiếm (searching) Tìm node "x" root, trả địa tìm thấy node x  Sử dụng đệ quy : NODE* SearchNode_Re(NODE* root, int x) { if (root == NULL) return NULL; if (root->data == x) { return root; } 10 if (root->data > x) 11 { 12 SearchNode_Re(root->pLeft, x); 13 } 14 else 15 { 16 SearchNode_Re(root->pRight, x); 17 } 18 }  Sử dụng vòng lặp : NODE* SearchNode(NODE* root, int x) { if (root == NULL) return NULL; 55 NODE* p = root; while (p != NULL) { if (p->data == x) 10 { 11 return p; 12 } 13 else if (p->data > x) 14 { 15 p = p->pLeft; 16 } 17 else 18 { 19 20 p = p->pRight; } 21 } 22 } Kiểm tra 56 TÀI LIỆU THAM KHẢO  Đỗ Xuân Lôi, Cấu trúc liệu giải thuật, NXB Thống kê, 1999;  Hoàng Nghĩa Tý, Cấu trúc liệu thuật toán, NXB Xây dựng, 2000 57

Ngày đăng: 23/12/2023, 10:14

Từ khóa liên quan

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

Tài liệu liên quan