1. Trang chủ
  2. » Thể loại khác

GT Cau truc du lieu va giai thuat

60 189 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 60
Dung lượng 1,79 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

MỤC TIÊU CỦA MÔN HỌC: - Hiểu được mối quan hệ giữa cấu trúc dữ liệu và giải thuật trong việc xây dựng chương trình; - Hiểu được ý nghĩa, cấu trúc, cách khai báo, các thao tác của các l

Trang 1

GIÁO TRÌNH CẤU TRÚC DỮ LIỆU VÀ

Trang 2

Lời nói đầu

Hiện nay, tại Trường chưa có giáo trình Cấu trúc dữ liệu & giải thuật Đặc biệt trên thị trường không có tài liệu học tập, tham khảo phù hợp với chương trình khung Cao đẳng nghề, trung cấp nghề thuộc nghề Công nghệ thông tin (CNTT) trong quá trình đào tạo nghề hiện nay

Nhóm tác giả biên soạn giáo trình lập trình cơ bản nhằm mục đích giúp học sinh, sinh viên (HSSV) sử dụng giáo trình làm tài liệu nghiên cứu và học tập một cách thuận tiện Chương trình môn học được sử dụng để giảng dạy cho sinh viên cao đẳng nghề Công nghệ thông tin (ứng dụng phần mềm) và làm tài liệu tham khảo cho các nghề thuộc các ngành nghề kỹ thuật

Vậy, rất mong được sự góp ý của bạn đọc để tài liệu này ngày càng được hoàn thiện hơn, chúng tôi xin chân thành cảm ơn

Đắk Lắk, ngày 02 tháng 09 năm 2014

Tham gia biên soạn

Chủ biên: Nguyễn Thị Thu Hà

ThS Lê Văn Tùng

Trang 3

CHƯƠNG TRÌNH MÔN HỌC CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

II MỤC TIÊU CỦA MÔN HỌC:

- Hiểu được mối quan hệ giữa cấu trúc dữ liệu và giải thuật trong việc xây dựng chương trình;

- Hiểu được ý nghĩa, cấu trúc, cách khai báo, các thao tác của các loại cấu trúc dữ liệu: mảng, danh sách liên kết, cây và các giải thuật cơ bản xử lý các cấu trúc dữ liệu đó;

- Xây dựng được cấu trúc dữ liệu và mô tả tường minh các giải thuật cho một số bài toán ứng dụng cụ thể;

- Cài đặt được một số giải thuật trên ngôn ngữ lập trình C;

 Coi việc học môn này là một nền tảng cho các môn học chuyên môn tiếp theo, nghiêm túc và tích cực trong việc học lý thuyết và làm bài tập, chủ động tìm kiếm các nguồn tài liệu liên quan đến môn học

III NỘI DUNG MÔN HỌC:

1 Nội dung tổng quát và phân bổ thời gian:

Thực hành, Bài tập

Kiểm tra *

(LT hoặc TH)

I Thiết kế và phân tích giải thuật 15 4 11 0

III Mảng, danh sách và các kiểu dữ liệu

Trang 4

Chương 1: Thiết kế và phân tích giải thuật

1 Mở đầu:

Có thể nói rằng không có một chương trình máy tính nào mà không có dữ liệu để xử lý

Dữ liệu có thể là dữ liệu đưa vào (input data), dữ liệu trung gian hoặc dữ liệu đưa ra (output data) Do vậy, việc tổ chức để lưu trữ dữ liệu phục vụ cho chương trình có ý nghĩa rất quan trọng trong toàn bộ hệ thống chương trình Việc xây dựng cấu trúc dữ liệu quyết định rất lớn đến chất lượng cũng như công sức của người lập trình trong việc thiết kế, cài đặt chương trình

2 Thiết kế giải thuật:

Khái niệm giải thuật hay thuật giải mà nhiều khi còn được gọi là thuật toán dùng để chỉ phương pháp hay cách thức (method) để giải quyết vần đề Giải thuật có thể được minh họa bằng ngôn ngữ tự nhiên (natural language), bằng sơ đồ (flow chart) hoặc bằng mã giả (pseudo code) Trong thực tế, giải thuật thường được minh họa hay thể hiện bằng mã giả tựa trên một hay một số ngôn ngữ lập trình nào đó (thường là ngôn ngữ mà người lập trình chọn để cài đặt thuật toán), chẳng hạn như C, Pascal, ?

Khi đã xác định được cấu trúc dữ liệu thích hợp, người lập trình sẽ bắt đầu tiến hành xây dựng thuật giải tương ứng theo yêu cầu của bài toán đặt ra trên cơ sở của cấu trúc dữ liệu đã được chọn Để giải quyết một vấn đề có thể có nhiều phương pháp, do vậy sự lựa chọn phương pháp phù hợp là một việc mà người lập trình phải cân nhắc và tính toán Sự lựa chọn này cũng có thể góp phần đáng kể trong việc giảm bớt công việc của người lập trình trong phần cài đặt thuật toán trên một ngôn ngữ cụ thể

3 Phân tích giải thuật:

Mối quan hệ giữa cấu trúc dữ liệu và Giải thuật có thể minh họa bằng đẳng thức:

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

Như vậy, khi đã có cấu trúc dữ liệu tốt, nắm vững giải thuật thực hiện thì việc thể hiện chương trình bằng một ngôn ngữ cụ thể chỉ là vấn đề thời gian Khi có cấu trúc dữ liệu

mà chưa tìm ra thuật giải thì không thể có chương trình và ngược lại không thể

có Thuật giải khi chưa có cấu trúc dữ liệu Một chương trình máy tính chỉ có thể được hoàn thiện khi có đầy đủ cả Cấu trúc dữ liệu để lưu trữ dữ liệu và Giải thuật

xử lý dữ liệu theo yêu cầu của bài toán đặt ra

3.1 Đánh giá cấu trúc dữ liệu và giải thuật

3.1.1 Các tiêu chuẩn đánh giá cấu trúc dữ liệu

Để đánh giá một cấu trúc dữ liệu chúng ta thường dựa vào một số tiêu chí sau:

- Cấu trúc dữ liệu phải tiết kiệm tài nguyên (bộ nhớ trong),

- Cấu trúc dữ liệu phải phản ảnh đúng thực tế của bài toán,

- Cấu trúc dữ liệu phải dễ dàng trong việc thao tác dữ liệu

3.2 Đánh giá độ phức tạp của thuật toán

Việc đánh giá độ phức tạp của một thuật toán quả không dễ dàng chút nào Ở dây, chúng ta chỉ muốn ước lượng thời gian thực hiện thuận toán T(n) để có thể

có sự so sánh tương đối giữa các thuật toán với nhau Trong thực tế, thời gian thực hiện một thuật toán còn phụ thuộc rất nhiều vào các điều kiện khác như cấu

Trang 5

tạo của máy tính, dữ liệu đưa vào, ở đây chúng ta chỉ xem xét trên mức độ của lượng

dữ liệu đưa vào ban đầu cho thuật toán thực hiện

Để ước lượng thời gian thực hiện thuật toán chúng ta có thể xem xét thời gian thực hiện thuật toán trong hai trường hợp:

- Trong trường hợp tốt nhất: Tmin

- Trong trường hợp xấu nhất: Tmax

Từ đó chúng ta có thể ước lượng thời gian thực hiện trung bình của thuật toán: Tavg

4 Một số giải thuật cơ bản:

4.1: Thuật toán đơn giản

Có thể nói rằng không có một chương trình máy tính nào mà không có dữ liệu để xử lý

Dữ liệu có thể là dữ liệu đưa vào (input data), dữ liệu trung gian và dữ liệu ra (output data)

Fibonacci(n) = Fibonacci(n – 1) + Fibonacci(n – 2)

4.3: Giải thuật đệ quy:

Bất cứ một hàm nào đó có thể triệu gọi hàm khác, nhưng ở đây một hàm nào đó có thể tự

triệu gọi chính mình Kiểu hàm như thế được gọi là hàm đệ quy

Trang 6

Phương pháp đệ quy thường dùng phổ biến trong những ứng dụng mà cách giải quyết có thể được thể hiện bằng việc áp dụng liên tiếp cùng giải pháp cho những tập hợp con của bài toán

ta viết lại như sau: (1*2*3*…*(n-2)*(n-1))*n = n*(n-1)! … = n*(n-1)*(n-2)!…

� Ta viết lại hàm giaithua bằng đệ quy như sau:

/* Ham tinh giai thua */

long giaithua(int in)

Trang 7

return (in * giaithua(in – 1));

}

� Chạy lại chương trình, quan sát, nhận xét và đánh giá kết quả

� Giải thích hoạt động của hàm đệ quy giaithua

Ví dụ giá trị truyền vào hàm giaithua qua biến in = 5

• Thứ tự gọi thực hiện hàm giaithua

giaithua(in) return(in * giaithua(in – 1))

bắt đầu định trị theo thứ tự ngược lại

• Định trị theo thứ tự ngược lại

giaithua(in) return(in * giaithua(in – 1))

Trang 8

Chương 2: Các kiểu dữ liệu cơ sở

1 Khái niệm về kiểu dữ liệu

Kiểu dữ liệu T có thể xem như là sự kết hợp của 2 thành phần:

- Miền giá trị mà kiểu dữ liệu T có thể lưu trữ: V,

- Tập hợp các phép toán để thao tác dữ liệu: O

T = <V, O>

Mỗi kiểu dữ liệu thường được đại diện bởi một tên (định danh) Mỗi phần tử dữ liệu

có kiểu T sẽ có giá trị trong miền V và có thể được thực hiện các phép toán thuộc tập hợp các phép toán trong O

Để lưu trữ các phần tử dữ liệu này thường phải tốn một số byte(s) trong bộ nhớ, số byte(s) này gọi là kích thước của kiểu dữ liệu

2 Các kiểu dữ liệu cơ bản

Kiểu số nguyên là kiểu dữ liệu dùng để lưu các giá trị nguyên hay còn gọi là

kiểu đếm được Kiểu số nguyên trong C được chia thành các kiểu dữ liệu con, mỗi

kiểu có một miền giá trị khác nhau

2.1 Kiểu số nguyên 1 byte (8 bits)

Kiểu số nguyên một byte gồm có 2 kiểu sau:

1 unsigned char Từ 0 đến 255 (tương đương 256 ký tự trong

bảng mã ASCII)

2 char Từ -128 đến 127

Kiểu unsigned char: lưu các số nguyên dương từ 0 đến 255

=> Để khai báo một biến là kiểu ký tự thì ta khai báo biến kiểu unsigned char

Mỗi số trong miền giá trị của kiểu unsigned char tương ứng với một ký tự trong bảng mã ASCII

Kiểu char: lưu các số nguyên từ -128 đến 127 Kiểu char sử dụng bit trái nhất

để làm bit dấu

=> Nếu gán giá trị > 127 cho biến kiểu char thì giá trị của biến này có thể là số

âm (?)

2.2 Kiểu số nguyên 2 bytes (16 bits)

Kiểu số nguyên 2 bytes gồm có 4 kiểu sau:

Trang 9

bit bên trái nhất để làm bit dấu

=> Nếu gán giá trị >32767 cho biến có 1 trong 3 kiểu trên thì giá trị của biến

này có thể là số âm

Kiểu unsigned int: Kiểu unsigned int lưu các số nguyên dương từ 0 đến 65535

2.3 Kiểu số nguyên 4 byte (32 bits)

Kiểu số nguyên 4 bytes hay còn gọi là số nguyên dài (long) gồm có 2 kiểu sau:

1 unsigned long Từ 0 đến 4,294,967,295

2 long Từ -2,147,483,648 đến 2,147,483,647

Kiểu long : Lưu các số nguyên từ -2147483658 đến 2147483647 Sử dụng bit

bên trái nhất để làm bit dấu

=> Nếu gán giá trị >2147483647 cho biến có kiểu long thì giá trị của biến này

3 long double 10 bytes Từ 3.4 *10-4932 đến 1.1 *104932

Mỗi kiểu số thực ở trên đều có miền giá trị và độ chính xác (số số lẻ) khác

nhau Tùy vào nhu cầu sử dụng mà ta có thể khai báo biến thuộc 1 trong 3 kiểu trên Ngoài ra ta còn có kiểu dữ liệu void, kiểu này mang ý nghĩa là kiểu rỗng không chứa giá trị gì cả

Kiểu số nguyên thường được thực hiện với các phép toán: O =?{+, -, *, /, DIV, MOD,

- Kiểu chuỗi ký tự: Có kích thước tùy thuộc vào từng ngôn ngữ lập trình

Kiểu chuỗi ký tự thường được thực hiện với các phép toán: O =??{+,???,

<, >, <=, >=, =, Length, Trunc, ?}?

- Kiểu luận lý: Thường có kích thước 1 byte

Kiểu luận lý thường được thực hiện với các phép toán: O =?{NOT, AND, OR, XOR, <, >, <=, >=, =, ?}?

Trang 10

3 Các kiểu dữ liệu có cấu trúc

3.2 Định nghĩa kiểu cấu trúc

struct <Tên cấu trúc>

- <Tên cấu trúc>: là một tên được đặt theo quy tắc đặt tên của danh biểu; tên

này mang ý nghĩa sẽ là tên kiểu cấu trúc

- <Kiểu> <Trường i> (i=1 n): mỗi trường trong cấu trúc có dữ liệu thuộc kiểu

gì (tên của trường phải là một tên được đặt theo quy tắc đặt tên của danh biểu)

Ví dụ 1: Để quản lý ngày, tháng, năm của một ngày trong năm ta có thể khai

báo kiểu cấu trúc gồm 3 thông tin: ngày, tháng, năm

struct NgayThang

{

unsigned char Ngay;

unsigned char Thang;

unsigned int Nam;

};

typedef struct

{

Trang 11

unsigned char Ngay;

unsigned char Thang;

unsigned int Nam;

} NgayThang;

Ví dụ 2: Mỗi sinh viên cần được quản lý bởi các thông tin: mã số sinh viên, họ tên, ngày tháng năm sinh, giới tính, địa chỉ thường trú Lúc này ta có thể khai báo một struct gồm các thông tin trên

3.3 Khai báo biến cấu trúc

Việc khai báo biến cấu trúc cũng tương tự như khai báo biến thuộc kiểu dữ liệu

chuẩn

Cú pháp:

- Đối với cấu trúc được định nghĩa theo cách 1:

struct <Tên cấu trúc> <Biến 1> [, <Biến 2>…];

- Đối với các cấu trúc được định nghĩa theo cách 2:

<Tên cấu trúc> <Biến 1> [, <Biến 2>…];

Ví dụ: Khai báo biến NgaySinh có kiểu cấu trúc NgayThang; biến SV có kiểu

Đối với các kiểu dữ liệu ta đã biết như kiểu số, kiểu mảng, kiểu cấu trúc thì dữ

liệu kiểu tập hợp (typedef) là kiểu dữ liệu bao gồm nhiều thành phần có kiểu dữ liệu giống hoặ khác nhau, mỗi thành phần được gọi là một trường (field)

Trang 12

4.2.Khai báo biến tập hợp:

Sử dụng từ khóa typedef (Type definitions) để định nghĩa kiểu:

- typedef (Type definitions): là kiểu do người dùng định nghĩa

- <Tên cấu trúc>: là một tên được đặt theo quy tắc đặt tên của danh biểu; tên này mang ý nghĩa sẽ là tên kiểu cấu trúc

<Kiểu> <Trường i> (i=1 n): mỗi trường trong cấu trúc có dữ liệu thuộc kiểu

dữ liệu cơ bản

Ví dụ 1: Để quản lý ngày, tháng, năm của một ngày trong năm ta có thể khai

báo kiểu cấu trúc gồm 3 thông tin: ngày, tháng, năm

Typedef struct

{

unsigned char Ngay;

unsigned char Thang;

unsigned int Nam;

} NgayThang;

Ví dụ 2: Mỗi sinh viên cần được quản lý bởi các thông tin: mã số sinh viên, họ

tên, ngày tháng năm sinh, giới tính, địa chỉ thường trú Lúc này ta có thể khai báo một struct gồm các thông tin trên

4.3 Khai báo biến kiểu tập hợp:

Việc khai báo biến tập hợp cũng tương tự như khai báo biến thuộc kiểu dữ liệu

chuẩn

Cú pháp:

- Đối với cấu trúc được định nghĩa theo cách 1:

struct <Tên cấu trúc> <Biến 1> [, <Biến 2>…];

- Đối với các cấu trúc được định nghĩa theo cách 2:

<Tên cấu trúc> <Biến 1> [, <Biến 2>…];

Ví dụ: Khai báo biến NgaySinh có kiểu cấu trúc NgayThang; biến SV có kiểu

Trang 13

5.Câu hỏi và Bài tập

1 Trình bày tầm quan trọng của Cấu trúc dữ liệu và Giải thuật đối với người lập trình?

2 Các tiêu chuẩn để đánh giá cấu trúc dữ liệu và giải thuật?

3 Khi xây dựng giải thuật có cần thiết phải quan tâm tới cấu trúc dữ liệu hay không? Tại sao?

4 Liệt kê các kiểu dữ liệu cơ sở, các kiểu dữ liệu có cấu trúc trong C, Pascal?

Trang 14

Chương 3: Mảng, danh sách và các kiểu dữ liệu trìu tượng

1 Mảng:

Mỗi biến chỉ có thể biểu diễn một giá trị Để biểu diễn một dãy số hay một bảng

số ta có thể dung nhiều biến nhưng cách này không thuận lợi trong trường hợp này ta có khái niệm về mảng khái niệm về mảng trong ngôn ngữ C cũng giống như khái niệm về ma trận trong đại số tuyến tính

Mảng có thể hiểu là một tập hợp nhiều phần tử có cùng kiểu giá trị và cùng cùng chung một tên Mỗi phần tử mảng biểu diễn được một giá trị Có bao nhiêu kiểu biến thì có bấy nhiêu kiểu mảng mảng cần được khai báo để định rõ: loại mảng: int, float, double,…

Tên mảng

Số chiều dài và kích thước mỗi chiều

Khái niệm về kiểu mảng và tên mảng cũng giống như khái niệm về kiểu biến và tên biến ta sẽ giải thích về số chiều và kích thước mỗi chiều thong qua các ví dụ

Giả sử z,b,x,y được khai báo như trên, và giả sử i,j là các biến nguyên trong đó i=2, J=1, khi đó:

a[j+i-1] là a[2]

b[j+i][2-i] là b[3][0]

y[i][j] là y[2][1]

Chú ý:

Mảng có bao nhiêu chiều thì ta phải viết bấy nhiêu chỉ số vì thế nếu ta viết như sau sẽ

là sai: y[i]( vì y là mảng hai chiều),vv…

Biểu thức dung làm chỉ số có thể thực hiện khi đó phần nguyên của biểu thức thực sẽ

là chỉ số mảng

Ví dụ:

A[2.5] là a[2]

Trang 15

B[1.9] là a[1]

*Khi chỉ số vượt ra ngoài kích thước mảng, máy sẽ vẫn không báo lỗi, nhưng nó sẽ truy cập đến một vùng nhớ bên ngoài mảng và có thể làm loạn chương trình

2 Khái niệm về danh sách:

Danh sách là tập hợp các phần tử có kiểu dữ liệu xác định và giữa chúng có một mối liên hệ nào đó

Số phần tử của danh sách gọi là chiều dài của danh sách Một danh sách có chiều dài bằng 0 là một danh sách rỗng

2.1 Danh sách liên kết (Linked List)

2.1.1 Định nghĩa

Danh sách liên kết là tập hợp các phần tử mà giữa chúng có một sự nối kết với nhau thông qua vùng liên kết của chúng

Sự nối kết giữa các phần tử trong danh sách liên kết đó là sự quản lý,

ràng buộc lẫnnhau về nội dung của phần tử này và địa chỉ định vị phần tử kia Tùy thu

ộc vào mức độvà cách thức nối kết mà danh sách liên kết có

thể chia ra nhiều loại khác nhau:

- Danh sách liên kết đơn;

- Danh sách liên kết đôi/kép;

- Danh sách đa liên kết;

- Danh sách liên kết vòng (vòng đơn, vòng đôi)

Mỗi loại danh sách sẽ có cách biểu diễn các phần tử (cấu trúc dữ liệu)riêng và cá cthao tác trên đó Trong tài liệu này chúng ta chỉ trình bày 02 loại danh sách liên kết cơbản là danh sách liên kết đơn và danh sách liên kết đôi

2.1 Danh sách liên kết (Linked List)

2.1.1 Định nghĩa

Danh sách liên kết là tập hợp các phần tử mà giữa chúng có một sự nối kết với nhau thông qua vùng liên kết của chúng

Sự nối kết giữa các phần tử trong danh sách liên kết đó là sự quản lý,

ràng buộc lẫnnhau về nội dung của phần tử này và địa chỉ định vị phần tử kia Tùy thu

ộc vào mức độvà cách thức nối kết mà danh sách liên kết có

thể chia ra nhiều loại khác nhau:

- Danh sách liên kết đơn;

- Danh sách liên kết đôi/kép;

- Danh sách đa liên kết;

- Danh sách liên kết vòng (vòng đơn, vòng đôi)

Mỗi loại danh sách sẽ có cách biểu diễn các phần tử (cấu trúc dữ liệu)riêng và cá cthao táctrên đó Trong tài liệu này chúng ta chỉ trình bày 02 loại danh sách liên kết cơbản là danh sách liên kết đơn

2.1 Danh sch lin kết (Linked List)

2.1.1 Định nghĩa

Trang 16

Danh sch lin kết l tập hợp cc phần tử m giữa chng cĩ một sự nối kết với nhau thơng qua vng lin kết của chng

Sự nối kết giữa cc phần tử trong danh sch lin kết đĩ l sự quản lý,

rng buộc lẫnnhau về nội dung của phần tử ny v địa chỉ định vị phần tử kia Ty thuộc v

o mức độv cch thức nối kết m danh sch lin kết cĩ

thể chia ra nhiều loại khc nhau:

- Danh sch lin kết đơn;

- Danh sch lin kết đơi/kp;

- Danh sch đa lin kết;

- Danh sch lin kết vịng (vịng đơn, vịng đơi)

Mỗi loại danh sch sẽ cĩ cch biểu diễn cc phần tử (cấu trc dữ liệu)ring v ccthao tc trn đĩ Trong ti liệu ny chng ta chỉ trình by 02 loại danh sch lin kết cơbản l danh sc

h lin kết đơn v danh sch lin kết đơi

typedef SLL_OneNode * SLL_Type;

Để quản lý một danh sách liên kết chúng ta có thể sử dụng nhiều

phương pháp khácnhau và tương ứng với các phương pháp này

chúng ta sẽ có các cấu trúc dữ liệukhác nhau, cụ thể:

- Quản lý địa chỉ phần tử đầu danh sách:

SLL_Type SLList1;

Hình ảnh minh họa:

SLList1

N ULL

- Quản lý địa chỉ phần tử đầu và cuối danh sách:

typedef struct SLL_PairNode

Trang 17

SLLFirst SLLLast

NULL

NumNode = 7

B Các thao tác trên danh sách liên kết đơn:

Với mỗi cách quản lý khác nhau của danh sách liên kết đơn , các

thao tác cũng sẽcó sự khác nhau về mặt chi tiết song nội dung cơ

bản ít có sự khác nhau Do vậy, ơ đây chúng ta chỉ trình bày các

thao tác theo cách quản lý thứ nhất (quản lý địa chỉcủa phần tử

đầu danh sách liên kết đơn), các cách quản lý khác sinh viên tự

vận dụng để điều chỉnh cho thích hợp

a Khởi tạo danh sách (Initialize):

Trong thao tác này chỉ đơn giản là chúng ta cho giá trị con trỏ quản lý địa ch

ỉ phầntử đầu danh sách về con trỏ NULL Hàm khởi tạo danh

sách liên kết đơn như sau:

void SLL_Initialize(SLL_Type First)

Trang 18

struct List {

Node * pHead;

};

c Thêm một phần tử vào trong danh sách:

Giả sử chúng ta cần thêm một phần tử có giá trị thành phần dữ liệu là NewDa

ta vàotrong danh sách Việc thêm có thể diễn ra ở đầu, cuối hay ở

giữa danh sách liên kết

Do vậy, ở đây chúng ta trình bày 3 thao tác thêm riêng biệt nhau:

a) Thêm phần tử mới vào đầu danh sách

void ChenDau(List &lt, Data x)

Trang 19

void ChenCuoi(List &lt, Data x)

e Tìm kiếm một phần tử trong danh sách:

Thực hiện tìm tuần tự (LinearSearch)

if (p->info.MaSV == x) return p;

p = p->pNext;

} return NULL;

g Hủy danh sách:

* Xĩa phần tử đầu tiên trong danh sách:

Thực hiện tìm tuần tự (LinearSearch)

Trang 20

p = p->pNext;

} return NULL;

}

 Xĩa tồn bộ danh sách

Lần lượt xĩa các phần tử đầu danh sách cho đến khi danh sách trống

B5: CurNode = CurNode->NextNode

B6: Lặp lại B3

Bkt: Kết thúc

k Sắp xếp thứ tự các phần tử trong danh sách:

Trang 21

Thao tác này chúng ta có thể vận dụng các thuật toán sắp xếp đã

trình bày trongChương 3 để sắp xếp dữ liệu trong danh sách liên kết

đơn Ở đây chúng ta chỉ trìnhbày sự vận dụng thuật toán trộn tự nhiên

để sắp xếp.Cũng cần lưu ý rằng đối với thao tác hoán vị hai phần tử

thì chúng ta có thể hoán vịhoàn toàn hai nút hoặc chỉ hoán vị

phần dữ liệu Tuy nhiên việc hoán vị hoàn toànhai nút sẽ phức tạp

hơn

- Thuật toán sắp xếp trộn tự nhiên:

B1: IF (SLL_Split(SLList, TempList) = NULL)

Nếu như vùng liên kết của danh sách liên kết đơn có 01 mối liên kết

với 01 phần tửkhác trong danh sách thì vùng liên kết trong danh sá

ch liên

đôi có 02 mối liên kếtvới 02 phần tử khác trong danh sách, cấu trú

c dữ liệu của mỗi nút trong danh sáchliên kết đôi như sau:

typedef struct DLL_Node

{ T Key;

InfoType Info;

DLL_Node * NextNode; // Vùng liên kết quản lý địa chỉ phần tử kế

tiếp nóDLL_Node * PreNode; // Vùng liên kết quản lý địa chỉ phần tử

Trang 22

Ở đây chúng ta cũng giả thiết rằng vùng dữ liệu của mỗi phần tử

trong danh sáchliên kết đôi chỉ bao gồm một thành phần khóa nhậ

typedef DLL_OneNode * DLL_Type;

Có nhiều phương pháp khác nhau để quản lý các danh sách liên kết đôi và tươngứng với các phương pháp này sẽ có các cấu trúc dữ

liệu khác nhau, cụ thể:

- Quản lý địa chỉ phần tử đầu danh sách:

Cách này hoàn toàn tương tự như đối với danh sách liên kết đơn DLL_Type DLL_List1;

- Quản lý địa chỉ phần tử đầu và cuối danh sách:

typedef struct DLL_PairNode

NULL

Trang 23

15 10 20 18 40 30 Quản lý địa chỉ phần tử đầu, địa chỉ phần tử cuối v

à số phần tử trong danh

NULL

NULL

3 Các kiểu dữ liệu trìu tượng:

3.1 Ngăn xếp (Stack)

A Khái niệm - Cấu trúc dữ liệu:

Ngăn xếp là một danh sách mà trong đĩ thao tác thêm một phần tử vào trong danhvà thao tác lấy ra một phần tử từ trong danh sách được thực hiện ở cùng một đầu

Như vậy, các phần tử được đưa vào trong ngăn xếp sau cùng sẽ được lấy ra trướctiên, phần tử đưa vào trong hàng đợi trước tiên s

được lấy ra sau cùng Do đĩ màngăn xếp cịn được gọi là danh sác

h vào sau ra trước (LIFO List) và cấu trúc dữ liệunày cịn được gọi là cấu trúc LIFO (Last In – First Out)

Tương tự như hàng đợi, cĩ nhiều cách để biểu diễn và tổ chức các ngăn xếp - Sử dụng danh sách đặc,

Trang 24

hoặc ngược chiều (cuối) với thứ tự các phần tử trong mảng và tron

g

danh sách liênkết Điều này có nghĩa là bề mặt ngăn xếp có thể là đầu mảng, đầu danh sách liênkết mà cũng có thể là cuối mảng, cuối danh sách liên kết Để thuận tiện, ở đâychúng ta giả sử bề mặt của ngăn xếp là đầu mảng, đầu danh sách liên kết Trường

hợp ngược lại, sinh viên tự áp dụng tương tự

Ở đây chúng ta cũng sẽ biểu diễn và tổ chức hàng đợi bằng danh sách đặc và bằngdanh sách liên kết đơn được quản lý bởi con trỏ đầu danh sách Do vậy cấu trúc dữliệu của ngăn xếp và các thao tác trên đó sẽ được trình bày thành hai trường hợpkhác nhau

- Biểu diễn và tổ chức bằng danh sách đặc:

typedef struct S_C { int Size; // Kích thước ngăn xếp

int SP;

T * List;// Nội dung ngăn xếp } C_STACK;

C_STACK CS_List;

- Biểu diễn và tổ chức bằng danh sách liên kết đơn;

typedef struct S_Element

Trang 25

Thứ tự ưu tiên các phép toán?

Trang 26

Hàng đợi là một danh sách mà trong đó thao tác thêm một phần t

vào trong danhsách được thực hiện ở một đầu này và thao tác lấ

y ra một phần tử từ trong danhsách lại được thực hiện ở đầu kia

Như vậy, các phần tử được đưa vào trong hàng đợi trước sẽ được lấy ra trước, phầntử đưa vào trong hàng đợi sau sẽ được lấy ra sau Do đó mà hàng đợi còn được gọilà danh sách vào trước ra trước (FIFO List) và cấu trúc dữ liệu này còn được gọi làcấu trúc FIFO (First

In – First Out) Có nhiều cách để biểu diễn và tổ chức các hàng đợi:

Trang 27

và bằng danhsách liên kết đơn được quản lý bởi hai con trỏ đầu v

{ int Len; // Chiều dài hàng đợi

int Front, Rear;

T * List;// Nội dung hàng đợi } C_QUEUE;

C_QUEUE CQ_List;

- Biểu diễn và tổ chức bằng danh sách liên kết đơn;

typedef struct Q_Element

{ T Key;

Q_Element * Next; // Vùng liên kết quản lý địa chỉ phần tử kế tiếp

} Q_OneElement;

typedef Q_OneElement * Q_Type;

typedef struct QP_Element

B Các thao tác trên hàng đợi tổ chức bằng danh sách đặc:

Do hạn chế của danh sách đặc cho nên mỗi hàng đợi đều có một chiều dài cố định

Do vậy, trong quá trình thao tác trên hàng đợi có thể xảy ra hiện tượng hàng đợi bịđầy hoặc hàng đợi bị tràn

Trang 28

Khi hàng đợi bị đầy: số phần tử của hàng đợi bằng chiều dài cho phép của hàngđợi Lúc này chúng ta không thể thêm bất kỳ một phần tử nào vào hàng đợi.Khi hàng đợi bị tràn: số phần tử của hàng đợi nhỏ hơn chiều dài cho phép củahàng đợi nhưng Rear = Len Lúc này chúng

ta phải khắc phục tình trạng trànhàng đợi bằng cách dịch tất cả các phần tử của hàng đợi

ra phía trước Front-1

vị trí hoặc xoay vòng để Rear chuyển lên vị trí đầu danh sách đặc Trong phầnnày chúng ta sử dụng phương pháp xoay vòng Như vậ

y theo

phương pháp này,hàng đợi bị đầy trong các trường hợp sau:

+ Front = 1 và Rear = Len, khi: Front < Rear + Rear + 1 = Front, khi: Rear < Front

Ghi chú:

Nếu chúng ta khắc phục hàng đợi bị tràn bằng phương pháp dịch tất

cả

các phần tửcủa hàng đợi ra phía trước Front=1 vị trí thì hàng đợi b

ị đầy khi thỏa mãn điều kiện:

Front = 1 và Rear = Len (Ở đây ta luôn luôn có: Front ≤ Rear)

4.Câu hỏi và Bài tập

1.Trình bày khái niệm của các loại danh sách? Ưu, nhược điểm và ứng dụng của mỗi loại danh sách?

2 Hãy đưa ra các cấu trúc dữ liệu để quản lý các loại danh sách vừa kể trên? Mỗi loạibạn hãy chọn ra một cấu trúc dữ liệu mà theo bạn là hay nhất? Giải thích sự lựachọn đó?

3 Trình bày thuật toán và cài đặt tất cả các thao tác trên danh sách li

5 Trình bày thuật toán và cài đặt tất cả các thao tác trên hàng đợi, ngă

Trang 29

xếp trên danhsách liên kết đơn, liên kết đôi theo hai cách quản lý:

- Quản lý địa chỉ nút đầu danh sách;

- Quản lý địa chỉ nút đầu và cuối danh sách

Theo bạn thuật toán sắp xếp nào dễ vận dụng hơn trên danh sách liên kết đơn, liênkết đôi trong hai trường hợp này?

7 Sử dụng Stack, viết chương trình chuyển đổi một số nguyên N tro

ng hệ thập phân(hệ 10) sang biểu diễn ở:

a Hệ nhị phân (hệ 2)

b Hệ thập lục phân (hệ 16)

8 Viết chương trình mô phỏng cho bài toán “Tháp Hà nội” và “Tháp Saigon” với cấu trúc dữ liệu như sau:

a Sử dụng danh sách liên kết để lưu trữ các cột tháp;

b Sử dụng Stack để lưu trữ các cột của tháp

Có nhận xét gì cho từng trường hợp?

9 Vận dụng Stack để gỡ đệ quy cho thuật toán QuickSort?

10 Vận dụng danh sách liên kết vòng để giải bài toán Josephus

Chương 4: Cây (TREE)

1 Khái niệm-biểu biễn cây:

1.1 Định nghĩa cây:

Ví dụ: có mối quan hệ họ hàng sau:

 Ông Nam có 3 người con là Hùng, Huân , Hải

 Ông Hùng có 2 người con là Sơn, Hậu

 Ông Huân có 2 người con là Trang, Minh

Trang 30

Cây là một tập hợp các phần tử (các nút) được tổ chức và có các đặc đi

ểm

sau:

- Hoặc là một tập hợp rỗng (cây rỗng)

Hoặc là một tập hợp khác rỗng trong đó có một nút duy nhất đ

ược làm nút gốc(Root’s Node), các nút còn lại được phân thành các

nhóm

trong đó mỗi nhóm lại là một cây gọi là cây con (Sub-Tree)

Như vậy, một cây con có thể là một tập rỗng các nút và cũng có th

ể là một tập hợpkhác rỗng trong đó có một nút làm nút gốc cây con

Định nghĩa cây:

Cây là một tập hợp các phần tử liên kết với nhau qua một quan hệ phân

cấp gọi là quan hệ cha con Tồn tại một phần tử (nút) không là con của

bất cứ nút nào, gọi là nút gốc

Định nghĩa đệ quy:

• Một nút được gọi là một cây và là nút gốc của cây đó

• Nếu T1, T2, …, Tk là các cây và n1, n2, …, nk lần lượt

là các nút gốc n là một nút và n là cha của các nút con n1, n2, …, nk Hình thành nên một cây T và n là nút gốc của cây T này

Ngày đăng: 02/11/2017, 21:54

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm