1. Trang chủ
  2. » Công Nghệ Thông Tin

Giáo trình CTDL và giải thuật

137 533 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 137
Dung lượng 1,41 MB

Nội dung

Giáo trình CTDL và giải thuật do trường CNTT và TT Thái NGuyên bạn hành năm 2014

Trang 2

LỜI NÓI ĐẦU

Để đáp ứng nhu cầu học tập của các bạn sinh viên, nhất là sinh viênchuyên ngành công nghệ thông tin, chuyên ngành tin học kinh tế, chuyênngành Điện tử Viễn thông các tác giả Bộ môn Công nghệ phần mềm - KhoaCông Nghệ Thông Tin - Trường Đạ i h ọc Th á i n g uyê n chúng tôi đãtiến hành biên soạn tập các bài giảng chính trong chương trình học đào tạo

theo tín chỉ Bài giảng môn Cấu Trúc Dữ Liệu và Thuật toán này được biên soạn cơ bản dựa trên quyển: “Cấu trúc dữ liệu & thuật toán” của tác giả Đinh Mạnh Tường, Nhà xuất bản Khoa học và Kỹ thuật “Cấu trúc dữ liệu và giải thuật”, của tác giả Đỗ Xuân Lôi, “ Cấu trúc dữ liệu + giải thuật= Chương trình” của N Wirth Giáo trình này cũng được biên soạn dựa trên

kinh nghiệm giảng dạy nhiều năm môn Cấu Trúc Dữ Liệu và Giải Thuật củachúng tôi

Tài liệu này được soạn theo đề cương chi tiết môn Cấu Trúc DữLiệu v à t h u ậ t t o á n của sinh viên chuyên ngành Công nghệ thông tincủa Khoa Công Nghệ Thông Tin - Trường Đại Học Thái nguyên Mục tiêucủa nó nhằm giúp các bạn sinh viên chuyên ngành có một tài liệu cô đọngdùng làm tài liệu học tập, nhưng chúng tôi cũng không loại trừ toàn bộ cácđối tượng khác tham khảo Chúng tôi nghĩ rằng các bạn sinh viên khôngchuyên tin và những người quan tâm tới cấu trúc dữ liệu và giải thuật sẽtìm được trong này những điều hữu ích

Mặc dù đã rất cố gắng nhiều trong quá trình biên soạn giáo trình nhưngchắc chắn giáo trình sẽ còn nhiều thiếu sót và hạn chế Rất mong nhậnđược sự đóng góp ý kiến của sinh viên và các bạn đọc để tập bài giảngngày một hoàn thiện hơn và có thể trở thành một giáo trình thực sự hữuích

Thái Nguyên, 08/2013

Các tác giả

Trang 3

MỤC LỤC

1.3.1 Sự cần thiết phải phân tích giải thuật 211.3.2 Thời gian thực hiện của giải thuật 22

Trang 4

PHẦN TỔNG QUAN

Môn học cấu trúc dữ liệu cung cấp cho sinh viên một khối lượng lớn các kiếnthức cơ bản về các cấu trúc dữ liệu và các phép toán trên từng cấu trúc đó.Sau khi học xong môn này, sinh viên cần phải:

- Nắm vững các khái niệm cơ bản như: kiểu dữ liệu, kiểu dữ liệu trừu tượng, mô hình dữ liệu, giải thuật và cấu trúc dữ liệu,

- Nắm vững và cài đặt được các mô hình dữ liệu, kiểu dữ liệu trừutượng như danh sách, ngăn xếp, hàng đợi, cây, tập hợp, bảng băm,

đồ thị t r ê n m á y t í n h bằng một ngôn ngữ lập trình cụ thể, ví dụ:Pascal, C,

- Vận dụng được các kiểu dữ liệu trừu tượng, các mô hình dữ liệu để

mô hình hóa các bài toán thực tế, lựa chọn cấu trúc dữ liệu thích hợp đểlập trình cho giải bài toán đặt ra

Môn học cấu trúc dữ liệu được dùng để giảng dạy cho các sinh viên sau:

- Sinh viên chuyên ngành công nghệ thông tin (môn bắt buộc )

- Sinh viên chuyên ngành tin học kinh tế (môn bắt buộc)

- Sinh viên chuyên ngành Điện tử - Viễn thông và tự động hóa (môn bắt buộc)

3. Nội dung cốt lõi

Nội dung giáo trình gồm 5 chương và đuợc trình bày trong 45 tiết chosinh viên, trong đó có khoảng 30 tiết lý thuyết và 15 tiết bài tập thực hành Nộidung bài giảng chú trọng về các cấu trúc dữ liệu và các giải thuật trên cáccấu trúc dữ liệu đó, bên cạnh đó, kết thúc mỗi chương bài giảng còn cung cấpcác câu hỏi thảo luận và bài tập thực hành để sinh viên cùng thảo luận, thựchành, tham khảo thêm từ nhiều nguồn tài liệu khác nhằm giúp học viên hiểuthấu lý thuyết đã cung cấp trong chương, tích cực hóa nhận thức của ngườihọc thông qua các hoạt động thảo luận giữa người học và giảng viên

Với mỗi mô hình dữ liệu và kiểu dữ liệu trừu tượng, chúng tôi luôn cốgắng trình bày từ mức khái niệm, đến các phép toán cơ bản trên mô hình, đếncác dạng biểu diễn trên máy tính/ các cấu trúc dữ liệu tương ứng với mô hình

dữ liệu/kiểu dữ liệu trừu tượng trong ngôn ngữ pascal và cài đặt các phép toán

cơ bản trên một dạng biểu diễn nào đó Sự cố gắng này của chúng tôi nhằmmục đích giúp người học hiểu được bản chất của từng mô hình dữ liệu/ kiểu

dữ liệu, người đọc có thể bám vào định nghĩa của từng mô hình/kiểu dữ liệutrừu tượng để cài đặt nó trên máy tính với các dạng biểu diễn khác nhau sao

Trang 5

cho thể hiện được định nghĩa này trên máy tính Người đọc nếu không thànhthạo ngôn ngữ lập trình pascal có thể dùng ngôn ngữ lập trình khác để biểudiễn mô hình/ kiểu dữ liệu trừu tượng và cài đặt các phép toán cơ bản trên môhình sử dụng ngôn ngữ lập trình đó Bài giảng này chúng tôi sử dụng pascal vìđây là một ngôn ngữ được trang bị hầu hết cho các sinh viên trước khi họcmôn học này, là một ngôn ngữ trong sáng người đọc dễ dàng hiểu các câu lệnhcủa nó ứng với thao tác thực tế nào.

Chương 2:

Trình bày mô hình dữ liệu danh sách, các cấu trúc dữ liệu để biểudiễn danh sách trên máy tính, chúng tôi tập trung trình bày cấu trúc danh sáchliên kết đơn, cấu trúc danh sách liên kết vòng và cấu trúc danh sách liên kếtkép Ngăn xếp và hàng đợi cũng được trình bày trong chương này và đượcxem là hai kiểu dữ liệu trừu tượng từ mô hình danh sách Chương này cónhiều cài đặt tương đối chi tiết để các bạn học viên mới tiếp cận với lậptrình có cơ hội nâng cao khả năng lập trình trong ngôn ngữ pascal, từ đó họcviên có thể mở rộng cài đặt sang các ngôn ngữ lập trình khác

Chương 3:

Chương này giới thiệu cá c mô hình dữ liệu cây bao gồm cây tổng quát,cây nhị phân, cây nhị phân tìm kiếm Với mỗi mô hình cây chúng tôi trình bàycác nội dung cần thiết như: khái niệm cây, các phép toán cơ bản trên cây, cácphép duyệt cây, các dạng biểu diễn cây trên máy tính hay còn gọi là các cấu trúc

dữ liệu tương ứng với mô hình dữ liệu cây, sau đó chúng tôi lựa chọn một dạngbiểu diễn cây cụ thế để cài đặt các phép toán cơ bản trên dạng biểu diễn đó, bạnđọc có thể vận dụng để cài đặt các phép toán trên cây với các dạng biểu diễn câykhác và phải phân tích để thấy rõ ưu/nhược điểm của từng dạng biểu diễn cây,phân tích rõ vai trò của từng mô hình dữ liệu cây như: cây tổng quát, cây nhịphân, cây nhị phân tìm kiếm

Chương 4:

Chương này chúng tôi trình bày mô hình dữ liệu đồ thị bao gồm nhữngnội dung chính như: Định nghĩa đồ thị để bạn đọc hiểu được đồ thị là gì, phânloại được đồ thị như đồ thị định hướng, vô hướng, có trọng số , cáckhái niệm cơ bản trên đồ thị, các cách biểu diễn đồ thị trên máy tính, cácphép duyệt đồ thị như duyệt theo chiều rộng, duyệt theo chiều sâu, vàcác bài toán ứng dụng đồ thị như: bài toán tìm cây khung cực tiểu, bàitoán tìm đường đi ngắn nhất, để bạn đọc thấy rõ vai trò của đồ thịtrong việc giải quyết các bài toán ứng dụng đồ thị Do hạn chế về thời

Trang 6

bỏ ngỏ để sinh viên tham khảo thêm các tài liệu khác, tự tìm hiểu, thảoluận, và sẽ hoàn thiện những phần kiến thức còn bỏ ngỏ này trongmôn học tiếp đó là môn toán rời rạc theo trong khung kiến thứcchương trình đào tạo của nhà trường

Chương 5:

Chương này, chúng tôi nói về mô hình dữ liệu tập hợp, nội dung trìnhbày gồm: Định nghĩa tập hợp để người dùng có một quan niệmchung về tập hợp, tập hợp là một khái niệm cơ bản để phát sinh

ra các mô hình dữ liệu khác như cây, danh sách, .ví dụ: Danh

sách biểu diễn một tập hợp các phần tử thỏa mãn điều kiện là

đồng kiểu, biến động, có quan hệ 1 – 1, Bạn đọc có thể liên

hệ khái niệm tập này với khái niệm tập hợp trong toán học, cácphép toán cơ bản trên tập hợp, các cách đơn giản để biểu diễn tập hợptrên máy tính như biểu diễn tập hợp bằng vectơ bít hay bằng danh sách,bằng cây Chúng tôi lựa chọn dạng biểu diễn tập hợp bằng véc tơ bít để càiđặt một số phép toán cơ bản trên tập hợp, bạn đọc sẽ phải tự cài đặt các phéptoán cơ bản này trên các dạng biểu diễn tập hợp khác Phần tiếp theo củachương trình bày kiểu dữ liệu trừu tượng tự điển, từ điển là tập hợp với baphép toán thêm, xoá và tìm kiếm phần tử Phần cuối chương chúng tôi trìnhbày cấu trúc dữ liệu thích hợp để biểu diễn từ điển đó là bảng băm

4 Kiến thức tiên quyết

Để học tốt môn học cấu trúc dữ liệu này, sinh viên cần phải có các kiến thức cơ bản sau:

- Kiến thức và kỹ năng lập trình căn bản

- Kiến thức toán rời rạc

- Nắm vững và sử dụng thành thạo một ngôn ngữ lập trình, cụ thể là ngônngữ Pascal hoặc một ngôn ngữ lập trình nào đó, ví dụ C, C++, Visual Basic, java,

Lưu ý: Các dạng biểu diễn và cài đặt các phép toán trong bài giảng này chúng tôi chỉ dùng ngôn ngữ Pascal, sẽ có một chút khó khăn cho bạn đọc nào chưa tìm hiểu ngôn ngữ Pascal.

[1] Aho, A V , J E Hopcroft, J D Ullman "Data Structure and

Algorihtms", Addison– Wesley; 1983

[2] Đỗ Xuân Lôi "Cấu trúc dữ liệu và giải thuật" Nhà xuất bản khoa học và

kỹ thuật Hà nội, 1995

[3] Đinh Mạnh Tường, Cấu trúc dữ liệu & thuật toán, Nhà xuất bản Khoa học và Kỹ thuật, 2003

Trang 7

[4] Michel T Goodrich, Roberto Tamassia, David Mount, “Data

Structures and Algorithms in C++” Weley International Edition; 2004.

[5] N Wirth " Cấu trúc dữ liệu + giải thuật= Chương trình", 1983.

[6] Nguyễn Trung Trực, "Cấu trúc dữ liệu" BK tp HCM, 1990.

[7] Lê Minh Trung; “Lập trình nâng cao bằng Pascal với các cấu trúc dữ

liệu”; 1997

Trang 8

Chương 1 MỞ ĐẦU TỔNG QUAN

1 Mục tiêu

Sau khi học xong chương này, sinh viên phải:

- Nắm được các bước trong lập trình để giải quyết cho một bài toán

- Nắm vững khái niệm cơ bản liên quan đến cấu trúc dữ liệu và giải thuật như:

Mô hình dữ liệu, kiểu dữ liệu trừu tượng, kiểu dữ liệu, giải thuật,

- Nắm vững các tiêu chuẩn để lựa chọn cấu trúc dữ liệu tốt cho bài toán

- Biết cách phân tích, đánh giá giải thuật

- Nắm vững kỹ thuật đệ quy trong cách giải bài toán

2 Kiến thức cơ bản cần thiết

Các kiến thức cơ bản cần thiết để học chương này bao gồm:

- Khả năng nhận biết và giải quyết bài toán theo hướng tin học hóa

- Các kiến thức cơ bản trong ngôn ngữ lập trình: biến, hằng, kiểu dữ liệu, dữ liệu, biểu diễn dữ liệu trên máy tính, giải thuẩt,

3 Nội dung chính

Chương này chúng ta sẽ nghiên cứu các vấn đề sau:

- Cách tiếp cận từ bài toán đến chương trình

- Các khái niệm cơ bản liên quan đến cấu trúc dữ liệu và thuật toán

- Các tiêu chuẩn để lựa chọn cấu trúc dữ liệu tốt cho bài toán

- Sự cần thiết phải phân tích đánh giá giải thuật

- Kỹ thuật đệ quy trong cách giải bài toán

- Ngôn ngữ diễn đạt giải thuật

1 1 Từ bài toán đên chương trình

Để giải một bài toán trong thực tế bằng máy tính ta thường trải qua 2 giai đoạn:

Giai đoạn 1:

Xác định bài toán cần giải quyết và xây dựng mô hình toán học cho bài toán.Mục đích của giai đoạn này là nhằm trả lời hai câu hỏi: Bài toán cho cái gì vàyêu cầu làm những gì? sau đó trả lời câu hỏi “để thực hiện các yêu cầu của bàitoán thì làm như thế nào”

Trang 9

Khi giải quyết 1 bài toán thực tế, ta phải bắt đầu từ việc xác định bài toán Nhiềuthời gian và công sức bỏ ra để xác định bài toán cần giải quyết, tức là phải trả lời

rõ ràng các câu hỏi bài toán yêu cầu ta "phải làm những công việc gì?" sau đó là

để thực hiện các công việc này thì ta "làm như thế nào?" Thông thường, khikhởi đầu, hầu hết các bài toán là không đơn giản, không rõ ràng Để giảm bớt sựphức tạp của bài toán thực tế, ta phải hình thức hóa nó, nghĩa là phát biểu lại bàitoán thực tế thành một bài toán hình thức (hay còn gọi là mô hình toán) Có thể córất nhiều bài toán thực tế có cùng một mô hình toán

Ví dụ 1: Xét bài toán tô màu bản đồ thế giới.

Ta cần phải tô màu cho các nước trên bản đồ thế giới Trong đó mỗi nước đều được tô một màu và hai nước láng giềng (cùng biên giới) thì phải được tô bằng hai màu khác nhau Hãy tìm một phương án tô màu sao cho số màu sử dụng là ít nhất.

Việc lựa chọn và xây dựng mô hình toán học cho bài toán diễn ra theo phân tích

sau:

Ta có thể xem mỗi nước trên bản đồ thế giới là một đỉnh của đồ thị, hai nước láng giềng của nhau thì hai đỉnh ứng với nó được nối với nhau bằng một cạnh Bài toán lúc này trở thành bài toán tô màu cho đồ thị như sau:

- Mỗi đỉnh đều phải được tô màu,

- Hai đỉnh có cạnh nối thì phải tô bằng hai màu khác nhau và ta cần tìm một phương án tô màu sao cho số màu được sử dụng là ít nhất

=> Mô hình toán học được sử dụng trong bài toán này là mô hình đồ thị.

Ví dụ 2: Xét bài toán điều khiển đèn giao thông

Cho một ngã năm như hình 1.1, trong đó C và E là các đường một chiều theo

chiều mũi tên, các đường khác là hai chiều Hãy thiết kế một bảng đèn hiệu điều khiển giao thông tại ngã năm này một cách hợp lý, nghĩa là: phân chia các lối

đi tại ngã năm này thành các nhóm, mỗi nhóm gồm các lối đi có thể cùng đi đồng thời nhưng không xảy ra tai nạn giao thông (các lối đi này có các hướng đi không cắt nhau), và số lượng nhóm chia là ít nhất có thể được.

Việc lựa chọn, xây dựng mô hình toán học cho bài toán được diễn ra theo phân tích sau:

A

B

C

DE

Hình 1.1

Trang 10

Ta có thể xem đầu vào của bài toán là tất cả các lối đi tại ngã năm này, đầu ra của bài toán là các nhóm lối đi có thể đi đồng thời mà không xảy ra tai nạn giao thông, mỗi nhóm sẽ tương ứng với một pha điều khiển của đèn hiệu, vì vậy ta phải tìm kiếm lời giải với số nhóm là ít nhất để giao thông không bị tắc nghẽn vì phải chờ đợi quá lâu.

Trước hết ta nhận thấy rằng tại ngã năm này có 13 lối đi: AB, AC, AD, BA,

BC, BD, DA, DB, DC, EA, EB, EC, ED Tất nhiên, để có thể giải được bài toán ta phải tìm một cách nào đó để thể hiện mối liên quan giữa các lối đi này Lối nào với lối nào không thể đi đồng thời, lối nào và lối nào có thể đi đồng thời Ví dụ cặp AB

và EC có thể đi đồng thời, nhưng AD và EB thì không, vì các hướng giao thông cắt nhau Ở đây ta sẽ dùng một sơ đồ trực quan như sau: tên của 13 lối đi được viết lên mặt phẳng, hai lối đi nào nếu đi đồng thời sẽ xảy ra đụng nhau (tức là hai hướng đi cắt qua nhau) ta nối lại bằng một đoạn thẳng, hoặc cong, hoặc ngoằn ngoèo tuỳ

thích Ta sẽ có một sơ đồ như hình 1.2 Như vậy, trên sơ đồ này, hai lối đi có cạnh nối

lại với nhau là hai lối đi không thể cho đi đồng thời.

Với cách biểu diễn như vậy ta đã có một mô hình toán học đồ thị (Graph), trong

đó mỗi lối đi trở thành một đỉnh của đồ thị, hai lối đi không thể cùng đi đồng thời được nối nhau bằng một đoạn ta gọi là cạnh của đồ thị Bây giờ ta phải xác định các nhóm, với số nhóm ít nhất, mỗi nhóm gồm các lối đi có thể đi đồng thời, nó ứng với một pha của đèn hiệu điều khiển giao thông Giả sử rằng, ta dùng màu để

tô lên các đỉnh của đồ thị này sao cho:

- Các lối đi cho phép cùng đi đồng thời sẽ có cùng một màu: Dễ dàng nhận thấy rằng hai đỉnh có cạnh nối nhau sẽ không được tô cùng màu.

- Số nhóm là ít nhất: ta phải tính toán sao cho số màu được dùng là

ít nhất Tóm lại, ta phải giải quyết bài toán sau:

"Tô màu cho đồ thị ở hình 1.2 sao cho:

Trang 11

- Hai đỉnh có cạnh nối với nhau (hai còn gọi là hai đỉnh kề nhau) không cùng màu.

Chú ý: Có rất nhiều các cấu trúc toán học có thể làm mô hình dữ liệu trong tin học, ví dụ như: Danh sách, tập hợp, ánh xạ, cây, đồ thị,

- Một bài toán thực tế bất kỳ thường bao gồm các đối tượng dữ liệu và các yêucầu xử lý trên những đối tượng đó, cho nên trong giai đoạn phân tích và thiết

kế, khi xây dựng mô hình toán học cho bài toán cần chú trọng đến hai vấn đề :

+ Tổ chức biểu diễn các đối tượng dữ liệu của bài toán trong mô hìnhtoán học như thế nào? mô hình này ta còn gọi là mô hình dữ liệu trongtin học ?

+ Xây dựng các thao tác xử lý trên các đối tượng của mô hình ra sao ?

1.1.2 Cài đặt chương trình cho bài toán cần giải quyết

Khi cài đặt chương trình giải quyết bài toán tương ứng ta quan tâm đến hai vấn đề:

1) Biểu diễn mô hình dữ liệu/mô hình toán học của bài toán trên máy tính

Ta phải chọn dạng biểu diễn nào để máy tính có thể hiểu và thực hiêncác thao tác trên chúng Giai đoạn này còn được gọi là xây dựng cấu trúc

dữ liệu cho bài toán Ta có thể cài đặt một mô hình dữ liệu bởi nhiều cấutrúc dữ liệu khác nhau Trong mỗi cách cài đặt, một số phép toán trên môhình có thể được thực hiện thuận lơi, nhưng các phép toán khác có thểlại không thuận lợi

2) Mã hóa các giải thuật

Với mỗi cấu trúc dữ liệu ta cần mã hóa các thao xử lý trên nó để giảiquyết các yêu cầu đặt ra của bài toán

Ta có thể sử dụng một ngôn ngữ lập trình cụ thể nào đó (Pascal,C, ) để cài đặt kết

quả ở giai đoạn Xác định & mô hình hóa bài toán cần giải quyết, ở bước này ta dùng

các cấu trúc dữ liệu được cung cấp trong ngôn ngữ, ví dụ Array, Record, để biểudiễn m ô h ì n h d ữ l i ệ u c ủ a b à i t o á n t r ê n m á y t í n h , và mã hóa giải thuậtbởi các câu lệnh trong ngôn ngữ lập trình lựa chọn

Như vậy, ta có thể tóm tắt các bước từ bài toán đến chương trình như sau:

1) Về mặt dữ liệu:

Theo quy trình từ: Mô hình dữ liệu -> Kiểu dữ liệu trừu tượng -> Cấu trúc dữliệu Thật vậy: Trong quá trình phát triển chương trình, nhất là khi phát triển

Trang 12

các hệ thống phần mềm lớn, ta cần đến hai dạng biểu diễn dữ liệu: Biếu diễntrừu tượng và biểu diễn cụ thể

biểu diễn trừu tượng: được xác định bởi mô hình dữ liệu – đó là mô hìnhtoán học của các đối tượng dữ liệu cùng với các phép toán thực hiện trêncác đối tượng đó, ví dụ như: Mô hình cây, danh sách, tập hợp, đồ thị, môhình ERA, …Khi ta dùng mô hình dữ liệu với một số xác định các phéptoán nào đó, ta sẽ có một kiểu dữ liệu trừu tượng , ví dụ: Ngăn xếp, hàngđợi, bảng băm, …

=> Dạng biểu diễn dữ liệu này không phụ thuộc vào ngôn ngữ lập trình cụ thể

diễn cụ thể của dữ liệu: Là biểu diễn xác định cách lưu trữ vật lý của dữliệu trong bộ nhớ máy tính Biểu diễn cụ thể của dữ liệu được xác định bởicác cấu trúc dữ liệu Các cấu trúc dữ liệu được mô tả trong ngôn ngữ lậptrình cụ thể mà ta sử dụng

=> Dạng biểu diễn này phụ thuộc vào ngôn ngữ lập trình cụ thể

Từ biểu diễn trừu tượng, ta có thể chuyển dịch thành các biểu diễn cụ thể khácnhau, hay nói cách khác, từ các mô hình dữ liệu hoặc từ các kiểu dữ liệu trừutượng, ta có thể chuyển dịch thành các cấu trúc dữ liệu khác nhau Ví dụ, ta cóthể cài đặt danh sách bởi cấu trúc dữ liệu mảng hoặc cấu trúc dữ liệu danh sáchliên kết Khi cài đặt mô hình dữ liệu bởi cấu trúc dữ liệu nào đó, thì các phéptóan trên mô hình được thực hiện bởi các thao tác là cần thiết phải được cài đặttrên cấu trúc dữ liệu đó

2) Về mặt xử lý dữ liệu:

Theo quy trình từ: Giải thuật không hình thức -> giải thuật bằng ngôn ngữ giả -> Giải thuật được mã hóa hoàn toàn bởi ngôn ngữ lập trình cụ thể, ví dụ:Pascal, C, Thật vây: Từ những yêu cầu xử lý thực tế, ta tìm cá c giải thuậttrên mô hình dữ l i ệu đ ã xâ y dự n g Giải thuật có thể mô tả một cáchkhông hình thức (tức là nó chỉ nêu phương hướng giải hoặc các bước giải mộtcách tổng quát) Tiếp theo ta hình thức hoá giải thuật bằng ngôn ngữ giả, rồichi tiết hoá dần ("mịn hoá") các bước giải tổng quát ở trên (làm mịn dần), ởbước này ta cần dùng các kiểu dữ liệu trừu tượng (không phải là các khai báocài đặt trong ngôn ngữ lập trình cụ thể) và các cấu trúc lệnh điều khiển trongngôn ngữ lập trình (không chú trọng đến cú pháp ngôn ngữ) , kết hợp ngônngữ tự nhiên để mô tả giải thuật Cuối cùng trong pha cài đặt, ta tiến hành mãhóa hoàn toàn giải thuật được mô tả bởi ngôn ngữ giả, sử dụng ngôn ngữ lậptrình cụ thể, thao tác trên cấu trúc dữ liệu cụ thể

1.2 Các khái niệm cơ bản

1.2.1 Mô hình dữ liệu ( Data model )

Mô hình dữ liệu là gì?

Trang 13

Là mô hình dữ liệu được sử dụng để mô tả cấu trúc logic của dữ liệu được xử lýbởi hệ thống Là mô hình toán học cùng với các phép toán có thể thực hiện trêncác đối tượng của mô hình.

Lựa chọn mô hình dữ liệu cho bài toán cần giải quyết như thế nào?

- Các thành phần dữ liệu thực tế đa dạng, phong phú và thường chứa đựngnhững quan hệ nào đó với nhau, do đó cần phải tổ chức, lựa chọn và xây dựngcác mô hình dữ liệu thích hợp nhất sao cho vừa có thể phản ánh chính xác các

dữ liệu thực tế này, vừa có thể dễ dàng dùng máy tính để xử lý

- Để tìm ra cấu trúc toán học thích hợp với một bài toán đã cho, trước hết chúng

ta cần phải phân tích kỹ bài toán để tìm ra câu trả lời cho các câu hỏi sau:

+ Các thông tin quan trọng của bài toán có thể biểu diễn bởi các đốitượng toán học nào ?

+ Có các mối quan hệ nào giữa các đối tượng ?+ Các kết quả phải tìm của bài toán có thể biểu diễn bởi các khái niệmtoán học nào ?

Sau khi đã có mô hình toán học mô tả bài toán, một câu hỏi đặt ra là, ta phảilàm việc với mô hình như thế nào để tìm ra lời giải của bài toán? Chúng ta sẽthiết kế các thuật toán thông qua các hành động, các phép toán thực hiện trêncác đối tượng của mô hình

Các loại mô hình dữ liệu ?

Ta có thể phân loại các mô hình dữ liệu dựa trên mối quan hệ giữa các phần tử củachúng như sau:

quan hệ 1:1 Các phần tử trong mô hình có quan hệ tuyến tính theo thứ tựxuất hiện của chúng, tức là, nếu mô hình dữ liệu tuyến tính chứa các phần tửthì nó phải có phần tử đầu tiên và phần tử cuối cùng, mỗi phần tử có đúng

một phần đứng ngay trước và một phần tử đứng ngay sau Hình 1.3 biểu

diễn một ví dụ về mô hình dữ liệu tuyến tính

Hình 1.3 Mô hình dữ liệu danh sách

Phần tử cuối cùng

A

Phần tử đứng trước A

Trang 14

chỉ có một tiền bối Hình 1.4 biểu diễn một ví dụ cụ thể về mô hình này Nếu ta di chuyển từ trên xuống dưới trong Hình 1.4 thì mỗi nút có thể trỏ

đến nhiều nút khác, nhưng nếu ta di chuyển từ dưới lên thì mỗi nút (trừ nút ởgốc) chỉ có quan hệ với 1 nút Mô hình dữ liệu phân cấp như vậy thườngđược gọi là cây, và đây là một loại mô hình dữ liệu quan trọng trong khoahọc máy tính:

Hình 1.4 – Mô hình dữ liệu cây

nhất Trong đồ thị, các phần tử có mối quan hệ n:m Tức là, mỗi phần tử

có thể có quan hệ với một hoặc nhiều phần tử khác Hình 1.5 biểu diễn

một ví dụ cụ thể về mô hình này

Hình 1.5 – Mô hình dữ liệu đồ thị

quan hệ trực tiếp với nhau, giữa chúng chỉ có một mối quan hệ là thànhviên của tập hợp, ta không cần quan tâm tới vị trí chính xác của một

phần tử nào đó trong tập hợp Hình 1.6 biểu diễn một ví dụ cụ thể về mô

hình này

A

A

Trang 15

Hình 1.6 – Mô hình tập hợp

Trên đây là bốn loại mô hình dữ liệu mà chúng ta sẽ nghiên cứu trong cuốn bàigiảng này Ta cũng sẽ nghiên cứu các dạng biểu diễn của các mô hình này bởi các cấutrúc dữ liệu khác nhau trong pha cài đặt chương trình Nói chung, hầu hết các cấu trúc

dữ liệu đều rơi vào một trong bốn dạng cơ bản này

1.2.2 Khái niệm trừu tượng hóa

Trong tin học, trừu tượng hóa nghĩa là đơn giản hóa, làm cho nó sáng sủa hơn và

dễ hiểu hơn Cụ thể trừu tượng hóa là che đi những chi tiết, làm nổi bật cái tổng

thể

1.2.3 Kiểu dữ liệu trừu tượng

Trong Mô hình dữ liệu, chúng ta có thể thực hiện một tập hợp các phép toán rất đadạng, phong phú Song trong nhiều áp dụng, chúng ta chỉ sử dụng mô hình với một

số xác định các phép toán nào đó Khi đó chúng ta sẽ có một kiểu dữ liệu trừutượng

Kiểu dữ liệu trừu tượng (abstract data type): là một mô hình dữ liệu được xét cùng với một số xác định các phép toán nào đó

Ví dụ: Mô hình dữ liệu danh sách, chỉ xét đến các phép toán thêm vào và lấy ra, tagọi là kiểu dữ liệu hàng đợi hoặc ngăn xếp, Mô hình tập hợp, chỉ xét đến các phéptoán: Thêm vào, loại bỏ, tìm kiếm ta gọi là kiểu dữ liệu trừu tượng từ điển, Khi nói đến một kiểu dữ liệu cần phải đề cập đến hai đặc trưng cơ bản sau :

1) Tập các giá trị thuộc kiểu.

2) Tập hợp các phép toán có thể thực hiện được trên các dữ liệu của kiểu.

1.2.4 Dữ liệu

Thực tế dữ liệu tồn tại ở rất nhiều dạng: hình ảnh, âm thanh, …….có rất nhiềudạng khác nhau Trong một bài toán, dữ liệu được phân làm ba loại:

Dữ liệu Dữ liệu vào: Các đối tượng cần xử lý của bài toán Kết quả trung gian

Dữ liệu đầu ra: Kết quả xử lý

Trang 16

Ví dụ: Xét bài toán cho một dãy số gồm n số nguyên, tìm số lớn nhất trong dãy sốCác dữ liệu của bài toán là:

- Dữ liệu đầu vào: số nguyên n, dãy số a1, a2, , an

- Dữ liệu đầu ra: Số lớn nhất (giả sử max)

- Dữ liệu trung gian: Giả sử dùng biến điều khiển i trong quá trình duyệt từ đầu đến cuối dãy để tìm số lớn nhất

1.2.5 Biểu diễn dữ liệu trên máy tính

+ Trong MTĐT, các dữ liệu dù tồn tại ở những hình thức khác nhau (số, văn bản,hình ảnh, đúng / sai ) đều được biểu diễn dưới dạng nhị phân khi đưa vào MT xử

lý Tức là mỗi dữ liệu được biểu diễn dưới dạng một dãy các số nhị phân 0 hoặc 1

Ví dụ: Số 10 = 0000 1010 ở dạng nhị phân

=> Cách biểu diễn này rất không thuận tiện (dài, khó, không gợi nhớ, …) đối với con người Việc xuất hiện các ngôn ngữ lập trình bậc cao ( Pascal, C, … gần với ngôn ngữ tự nhiên) đã giải phóng con người khỏi những khó khăn khi làm việc với cách biểu diễn dữ liệu nhị phân trong MT

+ Trong các ngôn ngữ lập trình bậc cao: Các kiểu dữ liệu là sự trừu tượng hoá cáctính chất của các đối tượng dữ liệu có cùng bản chất trong thế giới thực (chỉ ranhững tính chất đặc trưng cho các đối tượng thuộc phạm vi bài toán đang xét)

Ví dụ: Ứng với các dữ liệu dạng số, tương ứng ta có các kiểu dữ liệu số nguyên, số thực, số phức, … trong ngôn ngữ lập trình,

+ Như vậy tất cả các dữ liệu mô tả trong ngôn ngữ lập trình bậc cao được máy tính

xử lý đều phải được khai báo thuộc một kiểu dữ liệu xác định Khi đó chương trìnhdịch của ngôn ngữ lập trình bậc cao sẽ dịch chuyển các kiểu dữ liệu này sang dạngbiểu diễn nhị phân trước khi được máy tính xử lý

V : tập các giá trị hợp lệ mà một đối tượng kiểu T có thể lưu trữ

O : tập các thao tác xử lý có thể thi hành trên đối tượng kiểu T.

Ví du: Giả sử có kiểu dữ liệu ký tự (Chacracter) = <Vc ,Oc> với

Vc = { a-z,A-Z}

Oc = { lấy mã ASCII của ký tự, biến đổi ký tự thường thành ký tự hoa…}

Trang 17

Giả sử có kiểu dữ liệu số nguyên = <Vi ,Oi> với

Vi = { -32768 32767}

Oi= { +, -, *, /, %}

Như vậy:

Muốn sử dụng một kiểu dữ liệu trong cài đặt cần nắm vững các thuộc tính của kiểu

dữ liệu đó Các thuộc tính của 1 kiểu dữ liệu bao gồm:

Tên kiểu dữ liệu: Từ khóa thể hiện cho kiểu đó

Miền giá trị: Một biến có kiểu dữ liệu đó có thể nhận các giá trị trong phạm vi nào

Kích thước lưu trữ: Để tối ưu hóa việc sử dụng kiểu dữ liệu phù hợp, tránh hiện tượng dư thừa bộ nhớ.

Tập các toán tử tác động lên kiểu dữ liệu: Các phép toán cơ bản mà kiểu dữ liệu đó cung cấp

Ta thấy rằng, các dữ liệu cơ bản thường là các loại dữ liệu đơn giản, không có cấutrúc Chúng thường là các giá trị vô hướng như các số nguyên, số thực, các ký tự, cácgiá trị logic Các loại dữ liệu này, do tính thông dụng và đơn giản của mình, thườngđược các ngôn ngữ lập trình (NNLT) cấp cao xây dựng sẵn như một thành phần củangôn ngữ để giảm nhẹ công việc cho người lập trình Chính vì vậy đôi khi người tacòn gọi chúng là các kiểu dữ liệu định sẵn/tiền định Thông thường, các kiểu dữ liệu

cơ bản bao gồm :

Kiểu có thứ tự rời rạc: số nguyên, ký tự, logic , liệt kê, miền con …

Kiểu không rời rạc: số thực

Tùy ngôn ngữ lập trình, các kiểu dữ liệu định nghĩa sẵn có thể khác nhau đôi chút vềcác thuộc tính Ví dụ: Với ngôn ngữ C, các kiểu dữ liệu này chỉ gồm số nguyên, sốthực, ký tự Và theo quan điểm của C, kiểu ký tự thực chất cũng là kiểu số nguyên vềmặt lưu trữ, chỉ khác về cách sử dụng Trong khi đó PASCAL định nghĩa tất cả cáckiểu dữ liệu cơ sở đã liệt kê ở trên và phân biệt chúng một cách chặt chẽ

Các kiểu cơ sở rất đơn giản và không thể hiện rõ sự tổ chức dữ liệu trong mộtcấu trúc, thường chỉ được sử dụng làm nền để xây dựng các kiểu dữ liệu phức tạp khác

Trong nhiều trường hợp, chỉ với các kiểu dữ liệu cơ sở không đủ để phản ánh tựnhiên và đầy đủ bản chất của sự vật thực tế, dẫn đến nhu cầu phải xây dựng các kiểu

dữ liệu mới dựa trên việc tổ chức, liên kết các thành phần dữ liệu có kiểu dữ liệu đãđược định nghĩa Những kiểu dữ liệu được xây dựng như thế gọi là kiểu dữ liệu có cấutrúc Đa số các ngôn ngữ lập trình đều cài đặt sẵn một số kiểu có cấu trúc cơ bản nhưmảng, chuỗi, tập tin, bản ghi và cung cấp cơ chế cho lập trình viên tự định nghĩa kiểu

dữ liệu mới

Ví dụ : Để mô tả một đối tượng sinh viên, cần quan tâm đến các thông tin sau:

- Mã sinh viên: chuỗi ký tự

- Tên sinh viên: chuỗi ký tự

- Ngày sinh: kiểu ngày tháng

- Nơi sinh: chuỗi ký tự

Trang 18

- Điểm thi: số nguyênCác kiểu dữ liệu cơ sở cho phép mô tả một số thông tin như :

Giả sử đã có cấu trúc phù hợp để lưu trữ một sinh viên, nhưng thực tế lại cầnquản lý nhiều sinh viên, lúc đó nảy sinh nhu cầu xây dựng kiểu dữ liệu có cấu trúcmới, ví dụ danh sách hoặc mảng

Mục tiêu của việc nghiên cứu cấu trúc dữ liệu chính là tìm những phương cáchthích hợp để tổ chức, liên kết dữ liệu, hình thành các kiểu dữ liệu có cấu trúc từ nhữngkiểu dữ liệu đã được định nghĩa

1.2.7 Cấu trúc dữ liệu (Data Structures)

Cấu trúc dữ liệu được định mô tả như sau: CTDL = { Các dữ liệu thành phần} (1)

Trong đó:

Các dữ liệu thành phần có thể là dữ liệu đơn (sẵn có) hoặc là CTDL đã đượcxây dựng, chúng được liên kết với nhau theo một phương pháp liên kết nào đó, từnhững CTDL này người ta xây dựng các giải thuật tương ứng tác động trên CTDL

đó một cách hiệu quả nhất

Ví dụ: Trong ngôn ngữ lập trình Pascal, các câu trúc dữ liệu đã được định nghĩasẵn như :

Trang 19

o Cấu trúc dữ liệu là mô hình dữ liệu/kiểu dữ liệu trừu tượng được biểudiễn trên máy tính

o Cấu trúc dữ liệu là kiểu dữ liệu có cấu trúc

Để đánh giá một Cấu trúc dữ liệu liệu người ta thường căn cứ vào các tiêu chuẩn sau:

Phản ánh đúng thực tế :

Đây là tiêu chuẩn quan trọng nhất, quyết định tính đúng đắn của toàn bộ bàitoán Cần xem xét kỹ lưỡng cũng như dự trù các trạng thái biến đổi của dữ liệutrong chu trình sống để có thể chọn cấu trúc dữ liệu lưu trữ thể hiện chính xácđối tượng thực tế

Ví dụ : Một số tình huống chọn cấu trúc lưu trữ sai :

- Chọn một biến số nguyên integer để lưu trữ tiền thưởng bán hàng (được tính

theo công thức tiền thưởng bán hàng = trị giá hàng * 5%), do vậy sẽ làm trònmọi giá trị tiền thưởng gây thiệt hại cho nhân viên bán hàng Trường hợp nàyphải sử dụng biến số thực để phản ánh đúng kết quả của công thức tính thực tế

- Trong trường trung học, mỗi lớp có thể nhận tối đa 28 học sinh Lớp hiện có

20 học sinh, mỗi tháng mỗi học sinh đóng học phí 100.000 đ Chọn một biến số

nguyên byte ( khả năng lưu trữ 0 - 255) để lưu trữ tổng học phí của lớp học

trong tháng là không phù hợp vì giá trị tổng học phí thu được > 255, vượt khỏikhả năng lưu trữ của biến đã chọn, gây ra tình trạng tràn, dẫn đến sai lệch

2 - Phù hợp với các thao tác trên đó:

Tiêu chuẩn này giúp tăng tính hiệu quả của giải thuật, cụ thể là giúp cho việcphát triển các thuật toán đơn giản, tự nhiên hơn trên cấu trúc Do đó chươngtrình đạt hiệu quả cao hơn về tốc độ xử lý

Ví dụ : Một tình huống chọn cấu trúc lưu trữ không phù hợp:

Cần xây dựng một chương trình soạn thảo văn bản, các thao tác xử lýthường xảy ra là chèn, xoá sửa các ký tự trên văn bản Trong thời gian xử lý vănbản, nếu chọn cấu trúc lưu trữ văn bản trực tiếp lên tập tin thì sẽ gây khó khănkhi xây dựng các giải thuật cập nhật văn bản và làm chậm tốc độ xử lý củachương trình vì phải làm việc trên bộ nhớ ngoài Trường hợp này nên tìm mộtcấu trúc dữ liệu có thể tổ chức ở bộ nhớ trong để lưu trữ văn bản suốt thời giansoạn thảo

Trang 20

LƯU Ý :

Đối với mỗi ứng dụng, cần chú ý đến thao tác nào được sử dụng nhiều nhất đểlựa chọn cấu trúc dữ liệu cho thích hợp

3 - Tiết kiệm tài nguyên hệ thống:

Cấu trúc dữ liệu chỉ nên sử dụng tài nguyên hệ thống vừa đủ để đảm nhiệmđược chức năng của nó Thông thường có 2 loại tài nguyên cần lưu tâm nhất:CPU và bộ nhớ Tiêu chuẩn này nên cân nhắc tùy vào tình huống cụ thể khi viếtchương trình Nếu cần một chương trình có tốc độ xử lý nhanh thì khi chọn cấutrúc dữ liệu yếu tố tiết kiệm thời gian xử lý phải đặt nặng hơn tiêu chuẩn sửdụng tối ưu bộ nhớ, và ngược lại

Ví dụ : Một số tình huống chọn cấu trúc lưu trữ lãng phí:

- Sử dụng biến integer (2 bytes) để lưu trữ một giá trị cho biết tháng hiện hành

Biết rằng tháng chỉ có thể nhận các giá trị từ 1-12, nên chỉ cần sử dụng kiểu

byte là đủ.

- Để lưu trữ danh sách học viên trong một lớp, sử dụng mảng 50 phần tử (giới hạn

số học viên trong lớp tối đa là 50) Nếu số lượng học viên thật sự ít hơn 30, thìgây lãng phí Trường hợp này cần có một cấu trúc dữ liệu linh động hơn mảng,

ví dụ danh sách liên kết – ta sẽ đề cập đến trong các tiếp theo

Knuth (1973) định nghĩa giải thuật là một chuỗi hữu hạn các thao tác để giải một bài toán nào đó Các tính chất quan trọng của giải thuật là:

Hiệu quả (effectiveness):

các thao tác trong giải thuật phải được thực hiện trong một lượng thời gian hữu hạn

Trang 21

Ngoài ra một giải thuật còn phải có đầu vào (input) và đầu ra (output).

Nói

tóm l ại:

M ột giải thuật phải giải quyết xong công việc khi ta cho dữ liệu vào Cónhiều cách để thể hiện giải thuật: dùng ngôn ngữ tự nhiên, dùng lưu đồ, dùngngôn ngữ giả, dùng các câu lệnh của ngôn ngữ lập trình, Và một cáchdùng phổ biến là dùng ngôn ngữ giả, đó là sự kết hợp của ngôn ngữ tự nhiên vàcác câu lệnh của ngôn ngữ lập trình

1.2.9 Mối quan hệ giữa cấu trúc dữ liệu và giải thuật

Trong một chương trình: Giải thuật phản ánh các phép xử lý, còn đối tượng xử

lý của giải thuật lại là dữ liệu, chính dữ liệu chứa đựng các thông tin cần thiết đểthực hiện giải thuật Để xác định được giải thuật phù hợp cần phải biết nó tác độngđến loại dữ liệu nào (ví dụ để làm nhuyễn các hạt đậu, người ta dùng cách xay chứkhông băm bằng dao, vì đậu sẽ văng ra ngoài) và khi chọn lựa cấu trúc dữ liệucũng cần phải hiểu rõ những thao tác nào sẽ tác động đến nó (ví dụ để biểu diễncác điểm số của sinh viên người ta dùng số thực thay vì chuỗi ký tự vì còn phảithực hiện thao tác tính trung bình từ những điểm số đó)

Như vậy trong một chương trình máy tính, giải thuật và cấu trúc dữ liệu có mốiquan hệ chặt chẽ với nhau, được thể hiện qua công thức :

Cấu trúc dữ liệu + Giải thuật = Chương trình

Với một cấu trúc dữ liệu đã chọn, sẽ có những giải thuật tương ứng, phù hợp.Khi cấu trúc dữ liệu thay đổi thường giải thuật cũng phải thay đổi theo để tránhviệc xử lý gượng ép, thiếu tự nhiên trên một cấu trúc không phù hợp Hơn nữa, mộtcấu trúc dữ liệu tốt sẽ giúp giải thuật xử lý trên đó có thể phát huy tác dụng tốt hơn,vừa đáp ứng nhanh vừa tiết kiệm bộ nhớ, giải thuật cũng dễ hiễu và đơn giản hơn

* Cấu trúc lưu trữ ( Storange structures)

+ CTDL được biểu diễn trong bộ nhớ máy tính còn được gọi là Cấu trúc lưu trữ

1.3 Phân tích giải thuật

1.3.1 Sự cần thiết phải phân tích giải thuật

Trong khi giải một bài toán chúng ta có thể có một số giải thuật khác nhau, vấn

đề là cần phải đánh giá các giải thuật đó để lựa chọn một giải thuật tốt nhất.Thông thường thì ta sẽ căn cứ vào các tiêu chuẩn sau:

Trang 22

(1) - Giải thuật đúng đắn.

(2) - Giải thuật đơn giản

(3) - Giải thuật hiệu quả

Với yêu cầu (1), để kiểm tra tính đúng đắn của giải thuật chúng ta có thể càiđặt giải thuật đó và cho thực hiện trên máy với một số bộ dữ liệu mẫu rồi lấykết quả thu được so sánh với kết quả đã biết Thực ra thì cách làm này khôngchắc chắn bởi vì có thể giải thuật đúng với tất cả các bộ dữ liệu chúng ta đã thửnhưng lại sai với một bộ dữ liệu nào đó Vả lại cách làm này chỉ phát hiện ragiải thuật sai chứ chưa chứng minh được là nó đúng Tính đúng đắn của giảithuật cần phải được chứng minh bằng toán học Tất nhiên điều này khôngđơn giản và do vậy chúng ta sẽ không đề cập đến ở đây

Khi chúng ta viết một chương trình để sử dụng một vài lần thì yêu cầu (2)

là quan trọng nhất Chúng ta cần một giải thuật dễ viết chương trình để nhanhchóng có được kết quả, thời gian thực hiện chương trình không được đề cao vì

dù sao thì chương trình đó cũng chỉ sử dụng một vài lần mà thôi

Khi một chương trình được sử dụng nhiều lần thì thì yêu cầu tiết kiệm thờigian thực hiện chương trình, tiết kiệm không gian lưu trữ lại rất quan trọng, đặcbiệt đối với những chương trình mà khi thực hiện cần dữ liệu nhập lớn do đó yêucầu (3) sẽ được xem xét một cách kĩ càng Ta gọi nó là hiệu quả của giải thuật.Tính hiệu quả thể hiện qua hai mặt:

• Thời gian (Giúp chương trình chạy nhanh)

• Không gian (Làm cho chương trình bé chiếm ít bộ nhớ, tiết kiệm không gian)

1.3.2 Thời gian thực hiện của giải thuật

Thời gian thực hiện của giải thuật phụ thuộc vào nhiều yếu tố

• Trước hết phụ thuộc vào độ lớn của dữ liệu đầu vào

• Ngoài ra T còn phụ thuộc vào

a) Thời gian thực hiện giải thuật là gì? đơn vị của T(n) tính bằng gì ? cách tính?

Thời gian thực hiện một chương trình là một hàm của kích thước dữ liệu vào, ký hiệu T(n) trong đó n là kích thước (độ lớn) của dữ liệu vào.

Ví dụ 1: Chương trình tính tổng của n số có thời gian thực hiện là T(n) = c*n trong đó

c là một hằng số

- T(n) không thể tính bằng đơn vị cụ thể mà tính bằng số lần thực hiện cáclệnh của giải thuật

Trang 23

 Một câu hỏi đặt ra là: Cách tính này có thể hiện được tính nhanh hay chậmcủa giải thuật hay không ?

Câu trả lời: rõ ràng là có, thí dụ xét 2 giải thuật 1 (GT1) và giải thuật 2 (GT2) :

o GT1 có thời gian thực hiện là tỉ lệ với n

o GT2 có thời gian thực hiện là tỉ lệ với n 2

=> Với n khá lớn thì giải thuật 1 nhanh hơn giải thuật 2

Thời gian mà ta đánh giá như trên gọi là độ phức tạp tính toán của giải thuật:

Ở giải thuật 1 ta nói GT có độ phức tạp tính toán cấp n và kí hiệu T(n) = O(n)

Ở giải thuật 2 thì thời gian T() = O(n2) hay O(g(n)), g(n) còn được gọi là cấp độ phức tạp tính toán

Hàm g(n) thường chọn là: logn; n; n2; n3: ta gọi chung là hàm đa thức; g(n) = 2n

ta gọi là hàm mũ; các giải thuật có độ phức tạp tính toán là cấp các hàm đa thức thì chấp nhận được Ví dụ : T(n) = 60n2 + 9n + 9 = O(n)

* Một số ví dụ đánh giá độ phức tạp tính toán của GT

Ví dụ 1 : Tính trung bình cộng của một dãy gồm n số nhập vào từ bàn phím

Trang 24

* Một số qui tắc cơ bản xác định độ phức tạp tính toán

a Qui tắc loại bỏ hằng số

Nếu ta có T(n) = O(C1.g(n)) thì ta cũng có T(n) = O(g(n))

b Qui tắc lấy max

Nếu ta có T(n) = O(f(n) + g(n)) thì ta cũng có T(n) = O(max(f(n),g(n)))

c Qui tắc cộng

T1(n) và T2(n) là thời gian thực hiện của 2 đoạn chương trình P1 và P2 và T1(n) = O(f(n)); T2(n)= O(g(n)) thì thời gian thực hiện 2 đoạn chương trình nối tiếp nhau là T(n) = T1(n) + T2(n) hay T(n) = O(max(f(n),g(n)))

Tóm lại: Qui tắc tổng quát để phân tích một chương trình:

- Thời gian thực hiện của mỗi lệnh gán, READ, WRITE là O(1)

- Thời gian thực hiện của một chuỗi tuần tự các lệnh được xác định bằng qui tắccộng Như vậy thời gian này là thời gian thi hành một lệnh nào đó lâu nhấttrong chuỗi lệnh

- Thời gian thực hiện cấu trúc IF là thời gian lớn nhất thực hiện lệnh sau THENhoặc sau ELSE và thời gian kiểm tra điều kiện Thường thời gian kiểm tra điềukiện là O(1)

- Thời gian thực hiện vòng lặp là tổng thời gian thực hiện thân vòng lặp (trên tất

cả các lần lặp) Nếu thời gian thực hiện thân vòng lặp không thay đổi thìthời gian thực hiện vòng lặp là tích của số lần lặp với thời gian thực hiện 1 lầnthân vòng lặp

Ví dụ 1: Tính thời gian thực hiện của thủ tục sắp xếp “nổi bọt”

PROCEDURE Noi_bot(VAR a: ARRAY[1 n] OF integer);

VAR i, j, temp: Integer;

Trang 25

END;

* Xác định độ phức tạp của giải thuật trên

Ta thấy toàn bộ chương trình chỉ gồm một lệnh lặp {1}, lồng trong lệnh {1} là lệnh{2}, lồng trong lệnh {2} là lệnh {3} và lồng trong lệnh {3} là 3 lệnh nối tiếp nhau{4}, {5} và {6} Chúng ta sẽ tiến hành tính độ phức tạp theo thứ tự từ trong ra:

- Trước hết, cả ba lệnh gán {4}, {5} và {6} đều tốn O(1) thời gian, việc so sánh 1] > a[j] cũng tốn O(1) thời gian, do đó lệnh {3} tốn O(1) thời gian

a[j Vòng lặp {2} thực hiện (na[j i) lần, mỗi lần O(1) do đó vòng lặp {2} tốn O((na[j i).1)

= O(n-i)

- Vòng lặp {1} lặp có i chạy từ 1 đến n-1nên thời gian thực hiện của vòng lặp {1}

và cũng là độ phức tạp của giải thuật là:

Ví dụ 2: Xét giải thuật tìm kiếm tuần tự

Hàm tìm kiếm Search nhận vào một mảng a có n số nguyên và một sốnguyên x, hàm sẽ trả về giá trị logic TRUE nếu tồn tại một phần tử a[i] = x, ngượclại hàm trả về FALSE

Giải thuật tìm kiếm tuần tự là lần lượt so sánh x với các phần tử của mảng a,bắt đầu từ a[1], nếu tồn tại a[i] = x thì dừng và trả về TRUE, ngược lại nếu tất cảcác phần tử của a đều khác X thì trả về FALSE

FUNCTION Search(a:ARRAY[1 n] OF Integer; x:Integer):Boolean;

VAR i:Integer; Found:Boolean;

BEGIN

{1} i:=1;

{2} Found:=FALSE;

{3} WHILE(i<=n)AND (not Found) DO

{4}IF A[i]=X THEN Found:=TRUE ELSE i:=i+1;

{5} Search:=Found;

END;

* Phân tích xác định độ phức tạp của giải thuật trên

Ta thấy các lệnh {1}, {2}, {3} và {5} nối tiếp nhau, do đó độ phức tạp củahàm Search chính là độ phức tạp lớn nhất trong 4 lệnh này Dễ dàng thấy rằng

ba lệnh {1}, {2} và {5} đều có độ phức tạp O(1) do đó độ phức tạp của hàm

Trang 26

Search chính là độ phức tạp của lệnh {3} Lồng trong lệnh {3} là lệnh {4} Lệnh{4} có độ phức tạp O(1) Trong trường hợp xấu nhất (tất cả các phần tử củamảng a đều khác x) thì vòng lặp {3} thực hiện n lần, vậy ta có T(n) = O(n).

1.3.3 Không gian của giải thuật

Không gian của giải thuật, ký hiệu L(gt) được tính bằng số ô nhớ nguyên thuỷ được dùng trong giải thuật đó (= số biến đơn)

Ví dụ: Xét giải thuật (gt1) tính trung bình cộng của một dãy gồm n số nhập vào từ bànphím

7 Tính TBC = T/n;

8 Đưa ra TBC

=> L(gt1) = 4 (gồm biến n, biến d, biến T, biến TBC)

1.4 Ngôn ngữ diễn đạt giải thuật

- Là công cụ trung gian giúp giao tiếp giữa người và MTĐT

- Mỗi ngôn ngữ lập trình có một hệ kiểu, trong đó có một số là kiểu dữ liệu đơnhay nguyên tử, một số là các cấu trúc dữ liệu bao gồm các kiểu đơn

- Ngôn ngữ diễn đạt giải thuật bao gồm một tập hợp các câu lệnh tuân theo một

cú pháp nhất định Thông qua các câu lệnh mà MT có thể hiểu và thực hiệnnhững công việc mà người dùng muốn MT làm

- Trong môn học CTDL ta sử dụng ngôn ngữ lập trình Pascal để minh hoạ

1.5 Đệ quy và giải thuật đệ

1.5.1 Khái niệm đệ quy

Một đối tượng được gọi là đệ quy nếu nó bao gồm chính nó như một bộ phậnhoặc đối tượng được định nghĩa dưới dạng của chính nó

Ví dụ : Cho n là số nguyên dương, giai thừa của n được định nghĩa là :

n! = 1 nếu n = 0 hoặc n = 1;

n*(n-1) ! nếu n >1

=> Giai thừa của n được định nghĩa qua giai thừa của n-1, giai thừa của n-1 lại định nghĩa theo giai thừa của n-2, cứ tiếp tục như vậy tạo nên công thức đệ quy

1.5.2 Giải thuật đệ quy và thủ tục đệ quy

a) Giải thuật đệ quy

{

Trang 27

Nếu lời giải của bài toán T được thực hiện bởi lời giải của một bài toán T’, có dạngnhư T thì đó là một lời giải đệ quy Giải thuật chứa lời giải đệ quy được gọi là giảithuật đệ quy (T’<T)

Ví dụ: Xét bài toán tìm một từ trong từ điển

Phác thảo giải thuật

Procedure SEARCH( dict, word)

{dict được gọi là đầu mối để truy nhập được vào từ điển đang xét, word chỉ từ cần tìm }

1) If (từ điển chỉ còn là một trang )

Then (tìm word trong trang này)

Else

Begin

- Mở từ điển vào trang giữa;

- Xác định xem nửa nào chứa word ;

- If (word nằm ở nửa trước của từ điển )Then SEARCH(dict1, word) Else SEARCH(dict2, word)

End;

{dict1, dict2 là 2 đầu mối có thể truy cập được vào đầu trước và đầu sau của từ

điển }

b) Đặc điểm của thủ tục đệ quy

+ Trong thủ tục đệ quy có lời gọi đến chính nó

+ Mỗi lần có lời gọi thì kích thước của bài toán đã thu nhỏ hơn trước

+ Có một trường hợp đặc biệt, trường hợp suy biến: Bài toán sẽ được giảiquyết theo một cách khác hẳn và gọi đệ quy cũng kết thúc

Đệ quy gồm : Đệ quy trực tiếp (thủ tục chứa lời gọi đến chính nó) và đệ quy giántiếp (thủ tục chứa lời gọi đến thủ tục khác mà thủ tục này lại chứa lời gọi đến chính

nó )

CÂU HỎI ÔN TẬPCâu 1: Viết các giải thuật:

Tìm số nguyên lớn nhất/nhỏ nhất trong một dãy số nguyên

Sắp xếp dãy số theo chiều tăng/giảm dần

Tìm tất cả các số nguyên tố trong một dãy số

Sau đó Anh (Chị) hãy phân tích tính độ phức tạp tính toán và không gian củatừng giải thuật sau:

Câu 2: Viết các giải thuật đệ quy tương ứng với các bài toán sau

Trang 29

Chương 2 MÔ HÌNH DỮ LIỆU DANH SÁCH

TỔNG QUAN

1 Mục tiêu

Sau khi học xong chương này, sinh viên phải nắm vững các khái niệm danh sách, ngăn xếp, hàng đợi Biết cài đặt các dạng biểu diễn của danh sách, ngăn xếp, hàng đợi trên máy tính và cài đặt được các phép toán cơ bản trên từng dạng biểu diễn bằng ngôn ngữ lập trình cụ thể Ngoài ra học viên cần liệt kê và cài đặt được các phép toán thông dụng trên từng cấu trúc dữ liệu Sau kihi học song chương, học viên cần biết ứng dụng lý thuyết đã tìm hiểu để giải các bài toán thực tế.

2 Nội dung chính

Trong chương này chúng ta sẽ nghiên cứu

- Mô hình danh sách (LIST): Khái niệm, các dạng biểu diễn, các phép toán cơ bản

và cài đặt, các phép toán thường gặp và cài đặt

- Kiểu dữ liệu trừu tượng ngăn xếp (STACK): Khái niệm ngăn xếp, các dạng biểu diễn ngăn xếp, các phép toán thường gặp trên ngăn xếp, ứng dụng của ngăn xếp

- Kiểu dữ liệu trừu tượng hàng đợi (QUEUE): Khái niệm hàng đợi, các dạng biểu diễn hàng đợi, các phép toán thường gặp trên hàng đợi, ứng dụng của hàng đợi

2.1 Danh sách (List)

2.1.1 Khái niệm danh sách

Mô hình toán học của danh sách là một tập hợp hữu hạn biến động các phần

tử thuộc cùng một lớp đối tượng nào đó (có cùng một kiểu dữ liệu)

Ta cũng lưu ý rằng một đối tượng cũng có thể xuất hiện nhiều lần trong mộtdanh sách Ta biểu diễn danh sách L như là một chuỗi các phần tử của nó: a1, a2, ,

an với n ≥ 0 thì:

+ Nếu n = 0 ta nói danh sách rỗng (empty list)

+ Nếu n > 0 ta gọi a1 là phần tử đầu tiên và an là phần tử cuối cùng của danhsách

+ Số phần tử của danh sách ta gọi là độ dài của danh sách

Trang 30

danh sách có thứ tự tuyến tính theo vị trí (position) xuất hiện của các phần tử.

Ta nói ai đứng trước ai+1, với i từ 1 đến n-1; Tương tự ta nói ai là phần tửđứng sau ai-1, với i từ 2 đến n Ta cũng nói ai là phần tử tại vị trí thứ i, hayphần tử thứ i của danh sách

Ví dụ: Tập hợp họ tên các sinh viên của lớp TINHOC được liệt kê trên giấy như sau:

1 Nguyễn Trung Cang

là danh sách con của một danh sách bất kỳ

2.1 2 Các phép toán cơ bản trên danh sách

Gọi L là một danh sách đã cho, p là một vị trí (position) trong danh sách, x là mộtgiá trị nào đó cùng kiểu với kiểu dữ liệu của các phần tử trong danh sách Các phéptoán cơ bản thường gặp trên danh sách là:

1) Chèn một phần tử vào danh sách

INSERT_LIST(x,p,L): Chèn phần tử x vào vị trí p trong danh sách L Tức là

nếu danh sách là a1, a2, , ap-1, ap , , an thì sau khi xen ta có kết quả a1, a2, , ap-1,

x, ap, , an Nếu vị trí p không tồn tại trong danh sách thì phép toán không đượcxác định

2) Tìm vị trí của một phần tử trong danh sách

LOCATE(x,L) thực hiện việc xác định vị trí phần tử có nội dung x đầu tiên trong

Trang 31

danh sách L Locate trả kết quả là vị trí của phần tử x trong danh sách Nếu xkhông có trong danh sách thì vị trí sau phần tử cuối cùng của danh sáchđược trả về, tức là ENDLIST(L).

3) Lấy giá trị của phần tử ở vị trí nào đó

RETRIEVE(p,L) lấy giá trị của phần tử ở vị trí p của danh sách L; nếu vị trí p

không có trong danh sách thì kết quả không xác định (có thể thông báo lỗi)

4) Xoá một phần tử ở vị trí nào đó trong danh sách

DELETE_LIST(p,L): xoá phần tử ở vị trí p trong danh sách L Nếu vị trí p

không có trong danh sách thì phép toán không được định nghĩa và danh sách L sẽkhông thay đổi

5) Tìm vị trí của phần tử đứng sau phần tử có vị trí xác đinh

LINK(p,L) cho kết quả là vị trí của phần tử đi sau phần tử p; nếu p là phần tử

cuối cùng trong danh sách L thì LINK(p,L) cho kết quả là ENDLIST(L) Linkkhông xác định nếu p không phải là vị trí của một phần tử trong danh sách

6) Tìm vị trí của phần tử đứng trước phần tử có vị trí xác đinh

PREVIOUS(p,L) cho kết quả là vị trí của phần tử đứng trước phần tử có vị trí

p trong danh sách Nếu p là phần tử đầu tiên trong danh sách thì Previous(p,L)không xác định Previous cũng không xác định trong trường hợp p không phải

là vị trí của phần tử nào trong danh sách

7) Tìm vị trí của phần tử đứng đầu danh sách

FIRST(L) cho kết quả là vị trí của phần tử đầu tiên trong danh sách Nếu danh

sách rỗng thì ENDLIST(L) được trả về

8)Kiểm tra tính rỗng của danh sách

EMPTY_LIST(L) cho kết quả TRUE nếu danh sách rỗng, ngược lại nó cho giá

trị FALSE

9) Tạo một dách sách rỗng

MAKENULL_LIST(L) khởi tạo một danh sách L rỗng, chưa có dữ liệu.

Ghi chú:

- Trong thiết kế các giải thuật sau này chúng ta dùng các phép toán trừu tượng

đã được định nghĩa ở trên đây như là các phép toán nguyên thủy (cơ bản) Thật vậy,

Trang 32

từ các phép toán nguyên thuỷ này ta có thể tự hình thành lên các phép toán phứctạp khác thường gặp trên danh sách như: Tạo danh sách chứa dữ liêu, sắp xếp danhsách, duyệt danh sách, tách, gộp, tính toán, tổng hợp, hiện thị danh sách ….phụthuộc vào yêu cầu cụ thể của bài toán.

- Trên đây là các phép toán trừu tượng do chúng ta định nghĩa, nó chưa được càiđặt trong các ngôn ngữ lập trình Do đó để thực hiện được các phép toán đó taphải cài đặt chúng thành các chương trình con trong ngôn ngữ lập trình cụ thể.Trong bài giảng này, với mỗi cấu trúc dữ liệu cài đặt mô hình danh sách ta vẫngiữ đúng những tham số của các hàm/thủ tục đã liệt kê ở trên để thống nhất trongviệc cài đặt các phép toán tương ứng với nó

2.1.3 Biểu diễn danh sách trên máy tính

2.1.3.1 Danh sách cài đặt bằng mảng

Cài đặt danh sách bởi mảng hay còn gọi là cấu trúc dữ liệu danh sách đặc, hoặc cấutrúc dữ liệu danh sách kế tiếp, gọi tắt là: Danh sách đặc, hoặc danh sách kế tiếp, nóthuộc loại cấu trúc dữ liệu tĩnh

a) Mô tả cài đặt

- Giá sử N là số phân tử tối đa trong danh sách, với cách cài đặt này, dĩ nhiên,

ta phải ước lượng số phần tử tối đa của danh sách để khai báo số phần tử của

mảng cho thích hợp Giả sử Item là kiểu dữ liệu của các phần tử trong danh

sách Khi đó ta sẽ biểu diễn danh sách như sau:

+ Dùng một mảng để lưu giữ các phần tử của danh (giả sử mảng Elements).

? Muốn thêm 1 phần tử vào đầu hay cuối danh sách ta cần gọi các phép toán nào và gọi các phép toán đó như thế nào?

? Để nhập dữ liệu cho danh sách chứa n phần tử ta cần gọi trình tự các phép toán nào? Nói rõ cách làm

? Duyệt danh sách để hiển thị/tìm tất cả các phần tử ở vị trí chẵn ta cần gọi trình tự cácphéo toán cơ bản nào ở trên Nói rõ cách làm

Trang 33

+ Count là một biến đếm đếm số lượng phần tử hiện có trong danh sách

=> Như vậy ta có thể định nghĩa danh sách như một cấu trúc bản ghi gồm 2 trường:

Elements: Chứa các phần tử trong danh sách

Count: Đếm số phần tử hiện có trong danh sách (chiều dài danh sách)

Mảng chứa các phần tư trong danh sách có dạng như sau:

Nội dung phần

tử

Phần tử 1

Type List1 = Record

Elements : Array[1 N] of Item;

Count : 0 N;

End;

Var L : List1;

c) Cài đặt các phép toán cơ bản

1- Khởi tạo danh sách rỗng

Danh sách rỗng là một danh sách không chứa bất kỳ một phần tử nào (hay độ dàidanh sách bằng 0) Theo cách khai báo trên, trường count chỉ vị trí của phần tửcuối cùng trong danh sách và đó cũng độ dài hiện tại của danh sách, vì vậy để khởitạo danh sách rỗng ta chỉ việc gán giá trị trường count này bằng 0

Procedure MakeNullList(Var L: List)

Trang 34

Danh sách rỗng là một danh sách mà độ dài của nó bằng 0.

Function Empty_list(L : List) : boolean;

Phân tích cách thêm

Khi xen phần tử có nội dung x vào tại vị trí p của danh sách L thì sẽ xuất hiện cáckhả năng sau:

- Mảng đầy: mọi phần tử của mảng đều chứa phần tử của danh sách, tức là phần

tử cuối cùng của danh sách nằm ở vị trí cuối cùng trong mảng Nói cách khác, độdài của danh sách bằng chỉ số tối đa của mảng; khi đó không còn chỗ cho phần tửmới, vì vậy việc xen là không thể thực hiện được, chương trình báo lỗi

- Ngược lại, nếu mảng chưa đầy ta tiếp tục xét:

+ Nếu p không hợp lệ (p>count+1 hoặc p<1 ) thì chương trình con báo lỗi; (vì: Vị trí xen p<1 thì khi đó p không phải là một vị trí phần tử trong danhsách đặc Nếu vị trí p>L.count+1 thì khi xen sẽ làm cho danh sách Lkhông còn là một danh sách đặc nữa

+ Nếu vị trí p hợp lệ thì ta tiến hành xen theo các bước sau:

* Dời các phần tử từ vị trí p đến cuối danh sách ra sau 1 vị trí

* Độ dài danh sách tăng 1

* Đưa phần tử mới vào vị trí p

Giải thuật chèn:

Procedure InsertList(X: Item, P: integer , Var L: List)

Var i: integer;

Begin

Trang 35

if (L.count =n) then Writeln(‘Loi: Danh sach day khong them duoc 1’)

4 - Xóa phần tử ra khỏi danh sách

Bài toán:

Cho danh sách L, hãy xoá phần tử ở vị trí p ra khỏi danh sách

Phân tích bài toán

Để xoá phần tử ở vị trí p ra khỏi danh sách L ta làm công việc ngược lại với chènmột phần tử: Trước tiên ta kiểm tra vị trí phần tử cần xóa xem có hợp lệ haychưa?

+ Nếu p>L.count hoặc p<1 thì đây không phải là vị trí của phần tử trong danhsách

+ Ngược lại, vị trí đã hợp lệ thì ta phải dời các phần tử từ vị trí p+1 đếncuối danh sách lên trước một vị trí để đè lên phần tử cần xóa và độ dài danhsách giảm đi 1 phần tử (do đã xóa bớt 1 phần tử)

Giải thuật xoá

Procedure DeleteList(P: byte, var L: list)

Trang 36

o Nếu tìm thấy x thì vị trí của phần tử tìm thấy được trả về,

o Nếu không tìm thấy thì hàm trả về vị trí sau vị trí của phần tử cuốicùng trong danh sách, tức là ENDLIST(L) Giả sử ta cho ENDLIST(L) :=L.count+1

Trong trường hợp có nhiều phần tử cùng giá trị x trong danh sách thì vị trí củaphần tử được tìm thấy đầu tiên được trả về

Giải thuật

Procedure Locate(X:Item, L:list) :integer;

Var p: integer; found: boolean;

Trang 37

Found = false;

P = First(L); //vị trí phần tử đầu tiên

/*trong khi chưa tìm thấy và chưa kết thúc danh sách thì xét phần tử kế tiếp*/

while ((P < L.count+1) and (not Found) do

if (Retrieve(P,L) == X) then Found := true else P =

Trang 38

2.1.3.2 Danh sách cài đặt bởi con trỏ

Danh sách được cài đặt bởi con trỏ ta còn gọi là cấu trúc dữ liệu danh sách liênkết hay còn gọi là danh sách móc nối, còn gọi tắt là danh sách liên kết, đây thuộc loạicấu trúc dữ liệu động

Bài tập:

Vận dụng các phép toán trên danh sách đặc để viết chương trình nhập vào một danh sách các số nguyên và hiển thị danh sách vừa nhập ra màn hình Thêm phần tử có nội dung x vào danh sách tại ví trí p (trong đó x và p được nhập từ bàn phím) Xóa phần tử đầu tiên

có nội dung x (nhập từ bàn phím) ra khỏi danh sách.

Gợi ý:

Giả sử ta đã cài đặt đầy đủ các phép toán cơ bản trên danh sách Để thực hiện yêu cầunhư trên, ta cần thiết kế thêm một số chương trình con sau :

- Nhập danh sách từ bàn phím (giả sử: READ_LIST(L))

- Hiển thị danh sách ra màn hình ( giả sử gọi là PRINT_LIST(L))

Thực ra thì chúng ta chỉ cần sử dụng các phép toán MakeNull_List, Insert_List,Delete_List, Locate và các chương trình con Read_List, Print_List vừa nói trên là có thểgiải quyết được bài toán Để đáp ứng yêu cầu đặt ra, ta viết chương trình chính để nối kếtnhững chương trình con lại với nhau gồm các câu lệnh như sau:

BEGIN

MakeNullList(L); //Khởi tạo danh sách rỗng

ReadList(L);

Writeln(‘Danh sach vua nhap: ‘);

Print_List(L); // In danh sach len man hinh

Trang 39

Trong cách cài đặt này, ta dùng con trỏ để liên kết các ô nhớ chứa các phần tử củadanh sách Các hình thức tổ chức liên kết các phần tử trong danh sách có thể là:

+ Liên kết đơn, tương ứng ta có cấu trúc dữ liệu danh sách liên kết đơn – gọi tắt

là danh sách liên kết đơn

+ Liên kết vòng: Tương ứng ta có cấu trúc dữ liệu danh sách liên kết vòng – gọi

tắt là danh sách liên kết vòng

+ Liên kết đôi: Tương ứng ta có cấu trúc dữ liệu danh sách liên kết đôi – gọi tắt

là danh sách liên kết kép

+ Đa liên kết: Tương ứng ta có danh sách đa móc nối

Trong bài giảng này ta trung nguyên cứu cấu trúc danh sách liên kết đơn, kép Các cấu trúc danh sách liên kết khác dành cho học viên.

a) Danh sách liên kết đơn (Single Link List)

Mỗi phần tử trong danh sách là một ô nhớ, mỗi ô nhớ là một cấu trúc ít nhất làhai ngăn, một ngăn chứa dữ liệu của phần tử đó, một ngăn là con trỏ chứa địachỉ của ô nhớ đứng kế sau trong danh sách, ta có thể hình dung cơ chế này qua ví dụsau:

Giả sử 1 nhóm có 4 bạn: Đông, Tây, Nam, Bắc có địa chỉ nhà ở lần lượt làd,t,n,b Giả sử: Đông có địa chỉ của Nam, Tây không có địa chỉ của bạn nào, Bắc

giữ địa chỉ của Đông, Nam có địa chỉ của Tây, điều này được mô tả qua Hình 2.1

như sau

Ta có 1 kiểu lưu trữ khác: Lưu trữ móc nối, các ô nhớ chứa các phần tử trong danh sách không nhất thiết phải nằm ở những vị trí kế tiếp nhau, và chúng gắn kết với nhau thông qua cơ chế móc nối - lưu địa chỉ của nhau => danh sách được lưu trữ theo kiểu này gọi

là danh sách móc nối hay danh sách liên kết Vậy lưu trữ móc nối là như thế nào, ta đi tìm hiểu nguyên tắc lưu trữ của nó?

Các ô nhớ chứa các phần tử của danh sách

là một vùng liên tục, các vùng nhớ này được cấp phát ngay khi dịch chương trình

vì nó là các ô nhớ tĩnh.

Nhược điểm chính: Số lượng các phần tử trong danh sách bị hạn chế vì phụ thuộc vào vùng nhớ trống liên tục trong bộ nhớ

Ta đã biết, với cấu trúc

danh sách kế tiêp thì:

Trang 40

Hình 2.1 – Danh sách liên kết đơn chứa 4 phần tử

Như vậy, nếu ta xét thứ tự các phần tử bằng cơ chế lưu địa chỉ này thì ta có mộtdanh sách: Bắc, Đông, Nam, Tây Hơn nữa để có thể truy cập đến các phần tửtrong danh sách này thì chỉ cần giữ địa chỉ của Bắc (địa chỉ của ô nhớ chứa phần

tử đầu tiên trong danh sách)

*Mô tả cài đặt

Trong cài đặt, mỗi phần tử trong danh sách được cài đặt như một nút có hai trường:

+ Trường info chứa giá trị của các phần tử trong danh sách;

+ Trường link là một con trỏ giữ địa chỉ của ô kế tiếp trong danh sách:

- Mỗi nút có dạng như sau:

- Hình ảnh danh sách có dạng như sau:

Nút cuối cùng trong danh sách không có nút đứng sau, nên Trường link của

phần tử cuối trong danh sách, trỏ đến một giá trị đặc biệt là Nil (trỏ tới đất – không

trỏ tới đâu) Cấu trúc danh sách như vậy gọi là danh sách cài đặt bằng con trỏ hay

danh sách liên kết đơn hoặc danh sách móc nối đơn hay ngắn gọn gọi là danh sách

INFO LINK

Là con trỏ, trỏ đến nút đứng kế sau trong danh sách (nghĩa là nó chứa địa chỉ của ô nhớ nút đứng sau nó)chứa giá trị phần tử của nút, giả sử có kiểu dữ liệu là Item

Ngày đăng: 11/06/2014, 01:24

HÌNH ẢNH LIÊN QUAN

Hình 1.3 Mô hình dữ liệu danh sách 2- Mô hình dữ liệu phân cấp (mô hình cây): Dùng để biểu diễn các phần tử - Giáo trình CTDL và giải thuật
Hình 1.3 Mô hình dữ liệu danh sách 2- Mô hình dữ liệu phân cấp (mô hình cây): Dùng để biểu diễn các phần tử (Trang 13)
Hình 2.1 – Danh sách liên kết đơn chứa 4 phần tử - Giáo trình CTDL và giải thuật
Hình 2.1 – Danh sách liên kết đơn chứa 4 phần tử (Trang 40)
Hình 2.3: Xoá phần tử tại vị trí p Giải thuật: - Giáo trình CTDL và giải thuật
Hình 2.3 Xoá phần tử tại vị trí p Giải thuật: (Trang 44)
Hình 2.4 – hình ảnh danh sách liên kết đơn vòng - Giáo trình CTDL và giải thuật
Hình 2.4 – hình ảnh danh sách liên kết đơn vòng (Trang 45)
Hình 2.5 – hình ảnh danh sách liên kết đôi - Giáo trình CTDL và giải thuật
Hình 2.5 – hình ảnh danh sách liên kết đôi (Trang 46)
Hình 2.6 – Thêm một phần tử ở vị trí trước vị trí được trở bởi con trỏ M - Giáo trình CTDL và giải thuật
Hình 2.6 – Thêm một phần tử ở vị trí trước vị trí được trở bởi con trỏ M (Trang 47)
Hình 2.7 – Loại bỏ một phần tử ở vị trí M - Giáo trình CTDL và giải thuật
Hình 2.7 – Loại bỏ một phần tử ở vị trí M (Trang 48)
Hình 2.8 – cấu trúc ngăn xếp - Giáo trình CTDL và giải thuật
Hình 2.8 – cấu trúc ngăn xếp (Trang 50)
Hình 2.10 – Tịnh tiến hàng - Giáo trình CTDL và giải thuật
Hình 2.10 – Tịnh tiến hàng (Trang 58)
Hình 2.10: Cài đặt hàng bằng mảng xoay vòng - Giáo trình CTDL và giải thuật
Hình 2.10 Cài đặt hàng bằng mảng xoay vòng (Trang 59)
Hình 3.1 – Cây - Giáo trình CTDL và giải thuật
Hình 3.1 – Cây (Trang 70)
Hình 3.2 – Hình ảnh một cây - Giáo trình CTDL và giải thuật
Hình 3.2 – Hình ảnh một cây (Trang 72)
Hình ảnh cây  sau khi cài đặt - Giáo trình CTDL và giải thuật
nh ảnh cây sau khi cài đặt (Trang 75)
Hình 3.4 – Cây và hình ảnh cây sau khi biểu diễn trên MT sử dụng dạng Tree2 - Giáo trình CTDL và giải thuật
Hình 3.4 – Cây và hình ảnh cây sau khi biểu diễn trên MT sử dụng dạng Tree2 (Trang 78)
Hình 3.4 – Cây và hình ảnh cây sau khi biểu diễn dưới dạng Tree3 - Giáo trình CTDL và giải thuật
Hình 3.4 – Cây và hình ảnh cây sau khi biểu diễn dưới dạng Tree3 (Trang 79)
Hình 3.5 – Cây và hình ảnh cây được biểu diễn bởi con trưởng và em - Giáo trình CTDL và giải thuật
Hình 3.5 – Cây và hình ảnh cây được biểu diễn bởi con trưởng và em (Trang 82)
Hình ảnh cây  sau khi cài đặt - Giáo trình CTDL và giải thuật
nh ảnh cây sau khi cài đặt (Trang 83)
Hình 3.8 – Hình ảnh 1 cây TKNP - Giáo trình CTDL và giải thuật
Hình 3.8 – Hình ảnh 1 cây TKNP (Trang 94)
Hình 3.9 – hình ảnh một cây TKNP - Giáo trình CTDL và giải thuật
Hình 3.9 – hình ảnh một cây TKNP (Trang 96)
Hình 4.4 - Đồ thị và hình ảnh đồ thị sau khi biểu diễn bởi danh sách kề - Giáo trình CTDL và giải thuật
Hình 4.4 Đồ thị và hình ảnh đồ thị sau khi biểu diễn bởi danh sách kề (Trang 111)
Hình 4.5 - Đồ thị và minh họa phép duyệt đồ thị theo chiều sâu - Giáo trình CTDL và giải thuật
Hình 4.5 Đồ thị và minh họa phép duyệt đồ thị theo chiều sâu (Trang 112)
Hình 4.6 - Hình ảnh đồ thị và phép duyệt đồ thị theo chiều rộng - Giáo trình CTDL và giải thuật
Hình 4.6 Hình ảnh đồ thị và phép duyệt đồ thị theo chiều rộng (Trang 113)
Hình 4.7 - Đồ thị G và các cây khung của đồ thị G - Giáo trình CTDL và giải thuật
Hình 4.7 Đồ thị G và các cây khung của đồ thị G (Trang 114)
Hình 1:  Cấu trúc bảng băm mở - Giáo trình CTDL và giải thuật
Hình 1 Cấu trúc bảng băm mở (Trang 126)
Bảng băm là mảng gồm 5 phần tử và hàm băm h(x) = x % 5; Ta có bảng băm lưu trữ - Giáo trình CTDL và giải thuật
Bảng b ăm là mảng gồm 5 phần tử và hàm băm h(x) = x % 5; Ta có bảng băm lưu trữ (Trang 127)
Bảng 5.1 -  Giải quyết đụng độ trong bảng băm đóng bằng chiến lược băm lại tuyến tính - Giáo trình CTDL và giải thuật
Bảng 5.1 Giải quyết đụng độ trong bảng băm đóng bằng chiến lược băm lại tuyến tính (Trang 132)

TỪ KHÓA LIÊN QUAN

w