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

Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp

80 9 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

Tiêu đề Giáo Trình Nhập Môn Cấu Trúc Dữ Liệu Và Giải Thuật
Trường học Trường Cao đẳng nghề Đồng Tháp
Chuyên ngành Thiết kế đồ họa
Thể loại giáo trình
Năm xuất bản 2017
Thành phố Đồng Tháp
Định dạng
Số trang 80
Dung lượng 3,57 MB

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

Nội dung

Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật cung cấp cho người học những kiến thức như: Tổng quan về cấu trúc dữ liệu và giải thuật; đệ qui và giải thuật đệ qui; danh sách; các phương pháp sắp xếp cơ bản;... Mời các bạn cùng tham khảo!

Trang 1

GIÁO TRÌNH NHẬP MÔN CẤU TRÚC DỮ LIỆU

VÀ GIẢI THUẬT

MÔN HỌC/ MÔ ĐUN: MĐ 11

NGÀNH, NGHỀ: THIẾT KẾ ĐỒ HỌA

TRÌNH ĐỘ: CAO ĐẲNG/TRUNG CẤP

(Ban hành kèm theo Quyết định số /QĐ-CĐCĐ ngày tháng năm 2017

của Hiệu trưởng trường Cao đẳng Nghề Đồng Tháp)

Đồng Tháp, năm 2017

Trang 2

Tài liệu này thuộc loại sách giáo trình nên các nguồn thông tin có thể được phép dùng nguyênbản hoặc trích dùng cho các mục đích về đào tạo và tham khảo.

Mọi mục đích khác mang tính lệch lạc hoặc sử dụng với mục đích kinh doanh thiếu lành mạnh sẽ

bị nghiêm cấm

Trang 3

TỔNG QUAN VỀ CẤU TRÚC DỮ LIỆU VÀ GIẢI

Khi đã xác định được cấu trúc dữ liệu thích hợp, người lập trình sẽ bác đầu tiến hànhxây dựng giải thuật 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ựachọ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ậptrình trong việc cài đặt thuật toán trên một ngôn ngữ cụ thể

2 Đánh giá độ phức tạp của giải thuật

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 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 thao tác dữ liệu

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

Việc đánh giá độ phức tạp của bài toán quả không dễ chút nào Ở đây chúng ta chỉmới ước lượng thời gian thực hiện bài toán T(n) để có sự so sánh tương đối giữa các thuậttoá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ềuvào các điều kiện khác như cấu 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ựchiện thuật toán trong hai trường hợp:

• Trong trường hợp tốt nhất: T(min)

• Trong trường hợp xấu nhất: T(max)

Từ đó chúng ta có thể ước lượng thời gian thực hiện trung bình T(avg)

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

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

Trang 4

Kiểu dữ liệu T là sự hết hợp giữ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 biểu diễn bằng một tên (biệt 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ậphợ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ơ sở

Hầu hết các ngôn ngữ lập trình đều có cung cấp các kiểu dữ liệu cơ sở Tùy vào mỗiloại ngôn ngữ mà các kiểu dữ liệu cơ sở có các tên gọi khác nhau song chung quy lại cónhững loại kiểu dữ liệu cơ sở như sau:

TT Kiểu dữ liệu(T) Kích thước(V) Các phép toán thực hiện(O)

5 Luận lý 1 byte NOT, AND, OR, XOR, <, >,

Trang 5

0 đến 65,535– 32,768 đến 32,767– 32,768 đến 32,767

0 đến 4,294,967,295– 2,147,483,648 đến 2,147,483,6473.4 * 10–38đến 3.4 * 1038

1.7 * 10–308đến 1.7 * 10308

3.4 * 10–4932đến 1.1 * 104932

III Các kiểu dữ liệu trừu tượng

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

Kiểu dữ liệu có cấu trúc là kiểu dữ liệu được xây dựng trên cơ sở các dữ liệu đã có(có thể là một kiểu dữ liệu có cấu trúc khác) Tùy vào từng ngôn ngữ lập trình, songthường có các loại sau:

• Kiểu mảng hay còn gọi là dãy: kích thước bằng tổng kích thước của các phần tử

• Kiểu bảng ghi hay cấu trúc: kích thước bằng tổng kích thước thành phần (File)

2 Kiểu dữ liệu con trỏ

Các ngôn ngữ lập trình thường cung cấp cho chúng ta một kiểu dữ liệu đặt biệt đểlưu trữ các địa chỉ của bộ nhớ, đó là con trỏ (Pointer)

3 Kiểu dữ liệu tập tin

Tập tin (File) có thể xem là một kiểu dữ liệu đặc biệt, kích thước tối đa của tập tintùy thuộc vào không gian đĩa nơi lưu trữ tập tin

IV Các cấu trúc dữ liệu cơ bản

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

Dữ liệu có thể à 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ấtquan 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

V Mối quan hệ của cấu trúc dữ liệu và 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, nắm vững giải thuật thực hiện thì việc thể hiệnchươ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à

Trang 6

chưa tìm ra giải thuật thì không thể có chương trình và ngược lại không thể có thuật giảikhi 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ấu trúc dữ liệu và Giải thuật xử lý dữ liệu bài toán theo yêu cầu đặt ra.

 Câu hỏi

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ậptrì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ân tới Cấu trúc dữ liệu haykhông? Tại sao?

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

Trang 7

CHƯƠNG II:

ĐỆ QUI VÀ GIẢI THUẬT ĐỆ QUI

I Khái niệm đệ qui

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 đệ qui Vậy chương trình

đệ qui là chương trình gọi đến chính nó

Phương pháp đệ qui 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 concủa bài toán

Một chương trình đệ qui hoặc một định nghĩa đệ qui thì không thể gọi đến chính nómãi mãi mà phải có một điểm dừng đến một trường hợp đặc biệt nào đó, mà ta gọi làtrường hợp suy biến (degenerate case)

Ví dụ: Cho số tự nhiên n, ta định nghĩa n! như sau:

0!1

II Giải thuật đệ qui và chương trình đệ qui

Phương pháp thiết kế một giải thuật đệ qui

a Tham số hoá bài toán

b Phân tích trường hợp chung (đưa bài toán dưới dạng bài toán cùng loại nhưng cóphạm vi giải quyết nhỏ hơn theo nghiã dần dần sẽ tiến đến trường hợp suy biến)

Trang 8

/* Ham tinh giai thua */

long giaithua(int in)

_

Viết hàm tính giai thừa theo đệ qui

Với n! = 1*2*3*…*(n-2)*(n-1)*n,

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

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

Trang 9

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

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

III Các bài toán đệ qui căn bản

1 Đệ qui tuyến tính: là một dạng đệ qui trực tiếp đơn giản nhất

Giải thuật P

Bắt đầu P

Nếu (thỏa điều kiện dừng) thì

Thực hiện lệnh SNgược lại

Bắt đầu

Thực hiện các lệnh S*

Gọi lại PKết thúcKết thúc P

(S, S* là các thao tác, lệnh không đệ qui)

Trang 10

Bắt đầu

Thực hiện các lệnh S*

Gọi lại PGọi lại PKết thúcKết thúc P

(S, S* là các thao tác, lệnh không đệ qui)

Ngược lại

Gọi lại PCuối lặp

Kết thúc P(S, S* là các thao tác, lệnh không đệ qui)

Ví dụ: Cho dãy {Xn} xác định theo công thức truy hồi

Trang 11

for (int i= 0;i<n;i++) {

kq = kq + (n-i) * (n-i) * X(i);

1 Viết hàm đệ quy tính dãy Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … Bắt đầu bằng 0

và 1, các số tiếp theo bằng tổng hai số đi trước

2 Viết hàm đệ quy tính tổng n số nguyên dương đầu tiên: tong (n) = n + tong (n – 1)

3 Trình bày các dạng giải thuật đệ qui và cho ví dụ minh họa

4 Cài đặt chương trình tìm USCLN theo thuật toán Euclide bằng pp đệ qui và không đệqui

5 Cài đặt chương trình minh họa thuật toán tìm kiếm nhị phân đệ qui và không đệ qui

6 Cho ma trận kích thước 3x3 Điền vào mỗi ô trên ma trận sao cho tổng trên mỗi dòng

là số nguyên tố Viết chương trình liệt kê tất cả các trường hợp có thể dùng đệ qui vàkhông đệ qui

7 Tìm hiểu về thuật toán quay lui và thuật toán nhánh cận

8 (*) Cài đặt chương trình minh họa bài toán Tháp Hà Nội bằng giải thuật đệ qui vàkhông đệ qui

Trang 12

9 (*) Cài đặt giải thuật tìm đường đi cho con kiến theo yêu cầu bài toán mô tả tại

Trang 13

CHƯƠNG III:

DANH SÁCH

I Danh sách và các phép toán cơ bản trên danh sách

Có 2 loại danh sách là danh sách tuyến tính và danh sách liên kết

1 Danh sách tuyến tính và các phép toán cơ bản

Khái niệm

Danh sách là một dãy hữu hạn các phần tửthuộc cùng một lớp các đối tượng nào đó.Danh sách tuyến tính là các phần tử của nóđược sắp tuyến tính: nếu n>1 thì phần aiởtrước phần tử ai+1

Với ailà phần tử ở vị trí thứ i của danh sách

 a1là phần tử đầu tiên của danh sách

 anlà phần tử cuối cùng của danh sáchMột đối tượng có thể xuất hiện nhiều lầntrong một danh sách

• Khởi tạo danh sách

• Xác định độ dài của danh sách

• Loại bỏ phần tử ở vị trí thứ p trong danh sách

• Xen phần tử x vào danh sách sau vị trí p

• Xen phần tử x vào danh sách trước vị trí p

• Tìm kiếm trong danh sách có chứa phần tử x hay không?

• Kiểm tra danh sách có đầy hay không?

• Kiểm tra danh sách có rỗng hay không?

Trang 14

X Z Y

B

D C

B A

B A

D C

B A

Danh sách liên kết là cấu trúc dữ liệu động, có thể thêm hay hủy node của danh sáchtrong khi chạy chương trình Với cách cài đặt các thao tác thêm hay hủy node ta cần thayđổi lại vùng liên kết cho phù hợp

Tuy nhiên, việc lưu trữ danh sách liên kết tốn bộ nhớ hơn danh sách kề vì mỗi nodecủa danh sách phải chứa thêm vùng liên kết Ngoài ra việc truy xuất node thứ i trong danhsách liên kết chậm hơn vì phải duyệt từ dầu danh sách

Có nhiều kiểu tổ chức liên kết giữa các phần tử trong danh sách như :

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

Trang 15

• Tạo danh sách liên kết rỗng

• Kiểm tra danh sách có rỗng hay không?

• Kiểm tra danh sách có đầy không?

• Chèn, Xoá, tìm kiếm

• Duyệt danh sách

II Cài đặt danh sách theo cấu trúc mảng

Sử dụng mảng để lưu trữ các phần tử củadanh sách, trong đó mỗi thành phần

củamảng sẽ lưu giữ một phần tử của danh sách

Các phần tử liên tiếp nhau của danh sáchđược lưu trữ trong các thành phần liên

Maxchiều dài tối đa của danh sách

Xây dựng cấu trúc List gồm 2 thành phần

– elementlà một mảng các phần tử thuộckiểu dữ liệu item

– count lưu chỉ số của thành phần mảng lưugiữ phần tử cuối cùng của danh sách

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

Khởi tạo danh sách rỗng, ta gán giá trị count = 0

void Init(List &L){

long Length(List L){

1: Danh sách đầy0: Danh sách chưa đầyint isFull(List L)

{

if (L.count = = max)

return 1;

Trang 16

– Bước 1:Thực hiện kiểm tra nếu danh sáchkhông rỗng và p chỉ vào một phần tử trong

danh sách thì thực hiện bước 2,ngược lại thì dừng

 q =1 nếu việc xoá thành công

 q = 0 nếu việc xoá không thành công

void Delete(List &L, long p, int &q)

{

int i;

q = 0;

if (p<=L.count){

i = p;

Trang 17

{

L.element[i] = L.element[i+1];i++;

}L.count =L.count -1;

q = 1;

}}

6 Chèn phần tử X vào danh sách sau vị trí p

 Phần tử x thuộc kiểu Item cần chèn

 Tham biến q cho biết việc chèn có thànhcông hay không?

– Output:

 q =1 nếu việc chèn thành công

 q = 0 nếu việc chèn không thành công

void InsertAfter(List &L, long p,Item x, int &q)

i ;

}

Trang 18

L.element[p] = x;

L.count = L.count +1;

q =1;

}}

7 Chèn phần tử X vào danh sách trước vị trí p

Thuật toán:

– Bước 1:Thực hiện kiểm tra nếu danh sáchchưa đầy và p chỉ vào một phần tử

trongdanh sách thì thực hiện bước 2, ngược lạithì dừng

– Bước 2: Ta tịnh tiến các phần tử ở các vị trí L.count, L.count -1,…đến các vị

 Phần tử x thuộc kiểu Item cần chèn

 Tham biến q cho biết việc chèn có thành công hay không?

– Output:

 q =1 nếu việc chèn thành công

 q = 0 nếu việc chèn không thành công

void InsertBefore(List &L, long p,Item x, int &q)

L.count = L.count +1;

q =1;

}

}

8 Tìm kiếm phần tử x trong danh sách

Ta sử dụng phương pháp tìm kiếm tuầntự xây dựng hàm Search

• Input:

 Danh sáchL

Trang 19

 Phần tửx

 Tham biếnfound cho biết có tìm được haykhông?

 Thambiến pchobiếtvịtrícủaphầntửx trongdanhsáchnếux cótrongdanhsách

• Output:

 Found:

 1:nếu có x trong danh sách

 0:nếu khôngcó x trong danh sách

}

9 Duyệt danh sách

Trong nhiều bài toán chúng ta cần phảithao tác với các phần tử của danh sách.Do

đó cần phải đi qua danh sách từ phầntử đầu tiên cho đến hết

Xây dựng hàm Traverse duyệt danh sách

• Input:

 Danh sách L

• Output:

 Nonevoid Travese(List &L)

{

long i = 1;

while(i<=L.count){

ThaoTac(L.element[i]);

i++;

}}

10 Bài toán quản lí sinh viên

Kiểu dữ liệu Sinh viên gồm các trường Mã,Tên, Điểm Toán, Điểm Lý, Điểm Hoá.– Yêu cầu:

 Xâydựngdanhsáchđểquảnlýđiểmsv

Trang 20

printf(“Sinh vien %s” ,L.element[i].ten);

Trang 21

III Cài đặt danh sách theo cấu trúc danh sách liên kết (đơn, kép)

Mỗi phần tử liên kết với phần tử đứng sau nĩ trong danh sách

DSLK đơn là chuỗi các node, được tổ chức theo thứ tự tuyến tính

Mỗi node gồm 2 phần:

• Phần Data, information: lưu trữ các thông tin về bản thân phần tử

• Phần link hay con trỏ: lưu trữ địa chỉ của phần tử kế tiếp trong danh sách,hoặc lưu trữ giá trị NULL nếu là phần tử cuối danh sách

a Cấu trúc dữ liệu khai báo một danh sách liên kết đơn

// khai báo cấu trúc của một phần tử (node)

typedef struct Node

{

int data; // Data là kiểu đã định nghĩa trướcNode *link; //con trỏ chỉ đến cấu trúc NODE} NODE;

Ví dụ : Ðịnh nghĩa danh sách đơn lưu trữ hồ sơ sinh viên:

typedef struct SinhVien //Data

Trang 22

Y B

b Tổ chức quản lý một danh sách liên kết đơn

Để quản lý một xâu đơn chỉ cần biết địa chỉ phần tử đầu xâu

Con trỏ First sẽ được dùng để lưu trữ địa chỉ phần tử đầu xâu, ta gọi First là đầuxâu Ta có khai báo :

// khai báo cấu trúc của một danh sách

typedef struct List // kiểu danh sách liên kết

Trang 23

last t

Có 3 vị trí thêm phần tử vào danh sách

 Thêm vào đầu danh sách: trường hợp này có thể xảy ra 2 trường hợp

Trường hợp 1: thêm 1 phần tử vào một danh sách rỗng

//input: danh sách (first, last), phần tử mới new_ele

//output: danh sách (first, last) với new_ele ở đầu DS

Trang 24

Hàm thêm một phần tử vào đầu danh sách:

void AddFirst(LIST &l, NODE* new_ele)

{

if (l.first == NULL) //Xâu rỗng{

}else{

}}

//input: danh sách (first, last), thành phần dữ liệu X

//output: danh sách (first, last) với phần tử chứa X ở đầu DS

 Tạo phần tử mới new_ele để chứa dữ liệu X

 Nếu tạo đƣợc:

Thêm new_ele vào đầu danh sách

 Ngƣợc lại

Báo lỗi

Hàm thêm một thành phần dữ liệu vào đầu

NODE* Insertfirst(LIST &l, int x)

Hàm tạo một danh sách bằng cách thêm phần tử vào đầu danh sách

void create_list_first(LIST &l, int x)

{

Trang 25

 Thêm một phần tử vào cuối danh sách

//input: danh sách (first, last), phần tử mới new_ele

//output: danh sách (first, last) với new_ele ở cuối DS

void InsertLast(LIST &l, NODE *new_ele)

{

if (l.first==NULL){ l.first = new_ele;

X

Trang 26

l.last = l.first;

}else{ l.last->link = new_ele;

l.last = new_ele ;}

}

Thêm một thành phần dữ liệu vào cuối danh sách

Thuật toán

//input: danh sách (first, last), thành phần dữ liệu X

//output: danh sách (first, last) với phần tử chứa X ở cuối DS

 Tạo phần tử mới new_ele để chứa dữ liệu X

 Nếu tạo đƣợc:

Thêm new_ele vào cuối danh sách

 Ngƣợc lại

Báo lỗi

Hàm thêm một thành phần dữ liệu vào cuối danh sách

NODE* InputLast(LIST &l)

{ int x,n;

printf(“Nhap so phan tu :”);

scanf(“%d”,&n);

for(int i=0;i<n;i++){

printf(“Nhap phan tu thu %d :”,i);

scanf(“%d”,&x);

NODE* p=GetNode(x);

InsertLast(l, new_ele);

}}

Tạo danh sách bằng cách thêm phần tử vào cuối danh sách

void create_list_last(list &l, int x)

InsertLast(l,p);

Trang 27

D C

q

B A

last

E

}}

 Chèn một phần tử sau phần tử q

new_ele

Thuật toán

//input: danh sách (first, last), q, phần tử mới new_ele

//output: danh sách (first, last) với new_ele ở sau q

Trang 28

if (q!=NULL && new_ele !=NULL){

3) Duyệt danh sách

Duyệt danh sách là thao tác thường được thực hiện khi có nhu cầu xử lý các phần tửcủa danh sách theo cùng một cách thức hoặc khi cần lấy thông tin tổng hợp từ các phần tửcủa danh sách như:

• Đếm các phần tử của danh sách,

• Tìm tất cả các phần tử thoả điều kiện,

• Hủy toàn bộ danh sách (và giải phóng bộ nhớ)

Thuật toán

Bước 1: p = first; //Cho p trỏ đến phần tử đầu danh sách

Bước 2: Trong khi (Danh sách chưa hết) thực hiện

cout<<p->data<<“\t”;

p=p ->link;

}

Trang 29

Trong khi (p != NULL) và (p->Info != k ) thực hiện:

p:=p->link;// Cho p trỏ tới phần tử kếBước 3:

Nếu p != NULL thì p trỏ tới phần tử cần tìmNgược lại: không có phần tử cần tìm

5) Xóa một node trong danh sách

Xóa node đầu của danh sách, để xóa node đầu danh sách L (khác rỗng)

• Gọi p là node đầu của danh sách (là L.first)

• Cho l.first trỏ vào node sau node p (là p->link)

• Nếu danh sách trở tahnh2 rỗng thì L.last=NULL

Trang 30

p D

B1: p = first; // p là phần tử cần hủyB2:

B21 : l.first = l.first->link; // tách p ra khỏi xâuB22 : free(p); // Hủy biến động do p trỏ đếnB3: Nếu l.first=NULL thì l.last = NULL; //Xâu rỗng

 Hàm xóa một node đầu của danh sách

void RemoveFirst(LIST &l)

{

if(l.first != NULL){

NODE* p=l.first;

l.first=p->link;

if(l.first == NULL) l.last=NULL;//Nếu danh sách rỗngfree(p);

}}

 Xóa node sau node q trong danh sách

Điều kiện để có thể xóa đƣợc node sau q là :

• q phải khác NULL

• Node sau q phải khác NULL

Có 3 thao tác

• Gọi p là node sau q

• Cho vùng link của q trỏ vào node đứng sau p (là l.link)

• Nếu p là phần tử cuối thì l.last trỏ vào q

B2: Nếu (p != NULL) thì // q không phải là cuối xâu

B21 : q->link= p->link; // tách p ra khỏi xâuB22 : free(p); // Hủy biến động do p trỏ đến

last

E B

A

Trang 31

Hàm xóa node sau node q trong danh sách

void RemoveAfter(LIST &l, NODE *q )

6) Hủy toàn bộ danh sách

Để hủy toàn bộ danh sách, thao tác xử lý bao gồm hành động giải phóng một phần

tử, do vậy phải cập nhật các liên kết liên quan:

}

IV Cài đặt danh sách theo cấu trúc đặc biệt (ngăn xếp, hàng đợi)

1 Ngăn xếp

a Định nghĩa:

Trang 32

Ngăn xếp (Stack) là một danh sách mà ta giới hạn việc thêm vào hoặc loại bỏ mộtphần tử chỉ thực hiện tại một đầu của danh sách, đầu này gọi là đỉnh (TOP) của ngăn xếp.

Ta có thể xem hình ảnh trực quan của ngăn xếp bằng một chồng đĩa đặt trên bàn.Muốn thêm vào chồng đó 1 đĩa ta để đĩa mới trên đỉnh chồng, muốn lấy các đĩa ra khỏichồng ta cũng phải lấy đĩa trên trước Như vậy ngăn xếp là một cấu trúc có tính chất “vàosau - ra trước” hay “vào trước – ra sau“ (LIFO (last in - first out ) hay FILO (first in – lastout))

b Các phép toán trên ngăn xếp

•  MAKENULL_STACK(S): tạo một ngăn xếp rỗng

•  TOP(S) xem như một hàm trả về phần tử tại đỉnh ngăn xếp Nếu ngăn xếp rỗngthì hàm không xác định Lưu ý rằng ở đây ta dùng từ "hàm" để ngụ ý là TOP(S) có trảkết quả ra Nó có thể không đồng nhất với khái niệm hàm trong ngôn ngữ lập trình như

C chẳng hạn, vì có thể kiểu phần tử không thể là kiểu kết quả ra của hàm trong C

•  POP(S) chương trình con xoá một phần tử tại đỉnh ngăn xếp

•  PUSH(x,S) chương trình con thêm một phần tử x vào đầu ngăn xếp

•  EMPTY_STACK(S) kiểm tra ngăn xếp rỗng Hàm cho kết quả 1 (true) nếungăn xếp rỗng và 0 (false) trong trường hợp ngược lại

• Như đã nói từ trước, khi thiết kế giải thuật ta có thể dùng các phép toán trừu tượngnhư là các "nguyên thủy" mà không cần phải định nghĩa lại hay giải thích thêm Tuynhiên để giải thuật đó thành chương trình chạy được thì ta phải chọn một cấu trúc dữliệu hợp lí để cài đặt các "nguyên thủy" này

Ví dụ: Viết chương trình con Edit nhận một chuỗi kí tự từ bàn phím cho đến khi gặp kí tự

@ thì kết thúc việc nhập và in kết quả theo thứ tự ngược lại

c Cài đặt ngăn xếp:

Trang 33

Do ngăn xếp là một danh sách đặc biệt nên ta có thể sử dụng kiểu dữ liệu trừu tượngdanh sách để biểu diễn cách cài đặt nó Như vậy, ta có thể khai báo ngăn xếp như sau:

typedef List Stack;

Khi chúng ta đã dùng danh sách để biểu diễn cho ngăn xếp thì ta nên sử dụng cácphép toán trên danh sách để cài đặt các phép toán trên ngăn xếp Sau đây là phần cài đặtngăn xếp bằng danh sách

Thêm phần tử vào ngăn xếp

void Push(Elementtype X, Stack *S)

{

Insert_List (x, First (*S), &S);

}

Xóa phần tử ra khỏi ngăn xếp

void Pop (Stack *S)

bỏ thì thực hiện ở đầu kia của danh sách, gọi là đầu hàng (FRONT)

Xếp hàng mua vé xem phim là một hình ảnh trực quan của khái niệm trên, người mới đếnthêm vào cuối hàng còn người ở đầu hàng mua vé và ra khỏi hang, vì vậy hàng còn đượcgọi là cấu trúc FIFO (first in - first out) hay "vào trước - ra trước"

Bây giờ chúng ta sẽ thảo luận một vài phép toán cơ bản nhất trên hàng

Các phép toán cơ bản trên hàng

Trang 34

 MAKENULL_QUEUE(Q) khởi tạo một hàng rỗng.

 FRONT(Q) hàm trả về phần tử đầu tiên của hàng Q

 ENQUEUE(x,Q) thêm phần tử x vào cuối hàng Q

 DEQUEUE(Q) xoá phần tử tại đầu của hàng Q

 EMPTY_QUEUE(Q) hàm kiểm tra hàng rỗng

 FULL_QUEUE(Q) kiểm tra hàng đầy

Cài đặt hàng

Nhƣ đã trình bày trong phần ngăn xếp, ta hoàn toàn có thể dùng danh sách để biểudiễn cho một hàng và dùng các phép toán đã đƣợc cài đặt của danh sách để cài đặt cácphép toán trên hàng Tuy nhiên làm nhƣ vậy có khi sẽ không hiệu quả, chẳng hạn dùngdanh sách cài đặt bằng mảng ta thấy lời gọi INSERT_LIST(x,ENDLIST(Q),Q) tốn mộthằng thời gian trong khi lời gọi DELETE_LIST(FIRST(Q),Q) để xoá phần tử đầu hàng(phần tử ở vị trí 0 của mảng) ta phải tốn thời gian tỉ lệ với số các phần tử trong hàng đểthực hiện việc dời toàn bộ hàng lên một vị trí Để cài đặt hiệu quả hơn ta phải có một suynghĩ khác dựa trên tính chất đặc biệt của phép thêm và loại bỏ một phần tử trong hàng.Cài đặt hàng bằng danh sách liên kết (cài đặt bằng con trỏ)

Cách tự nhiên nhất là dùng hai con trỏ front và rear để trỏ tới phần tử đầu và cuốihàng Hàng đƣợc cài đặt nhƣ một danh sách liên kết có Header là một ô thực sự, xem hìnhII.13

Khai báo cần thiết

typedef ElementType; //kiểu phần tử của hàng

Trang 35

void MakeNullQueue(Queue

*Q){Position Header;

Header=(Node*)malloc(sizeof(Node)); //Cấp phát HeaderHeader->Next=NULL;

Thực chất là xoá phần tử nằm ở vị trí đầu hàng do đó ta chỉ cần cho front trỏ tới vị trí

kế tiếp của nó trong hàng

Trang 36

CHƯƠNG IV:

CÁC PHƯƠNG PHÁP SẮP XẾP CƠ BẢN

I Định nghĩa bài toán sắp xếp

Sắp xếp là quá trình xử lý một danh sách các phần tử (hoặc các mẫu tin) để đặt chúngtheo một thứ tự thỏa mãn một tiêu chuẩn nào đó dựa trên nội dung thông tin lưu giữ tạimỗi phần tử

Khái niệm nghịch thế

• Xét một mảng các số a[0], a[1], … a[n-1]

• Nếu có i<j và a[i] > a[j], thì ta gọi đó là một nghịch thế

Mảng chưa sắp xếp sẽ có nghịch thế

Mảng đã có thứ tự sẽ không chứa nghịch thế: a[0] a[1]  …  a[n -1]

II Các Phương pháp chọn trực tiếp Selection sort

a Ý tưởng:

Nhận xét: Mảng có thứ tự thì a[i]=min(a[i], a[i+1], …, a[n-1])

Ý tưởng: mô phỏng một trong những cách sắp xếp tự nhiên nhất trong thực tế:

• Chọn phần tử nhỏ nhất trong n phần tử ban đầu, đưa phần tử này về vị trí đúng

là đầu dãy hiện hành

• Xem dãy hiện hành chỉ còn n-1 phần tử của dãy ban đầu, bắt đầu từ vị trí thứ 2;lặp lại quá trình trên cho dãy hiện hành đến khi dãy hiện hành chỉ còn 1 phầntử

b Thuật toán:

//input: dãy (a, n)

//output: dãy (a, n) đã được sắp xếp

Bước 1 : i = Vị trí đầu;

Bước 2 : Tìm phần tử a[min] nhỏ nhất trong dãy hiện hành từ a[i]

đến a[n-1]

Bước 3 : Nếu min i: Hoán vị a[min] và a[i]

Bước 4 : Nếu i chưa là Vị trí cuối

 i = Vị trí kế(i);

 Lặp lại Bước 2Ngược lại: Dừng //n phần tử đã nằm đúng vị trí

Ví dụ minh họa A[]:

i=1; j=2 ->8; min=5

Trang 37

c Cài đặt thuật toán:

void SelectionSort(int a[],int n )

if (min != i)Swap(a[min], a[i]);

}}

d Đánh giá giải thuật

Ở lƣợt thứ i, cần (n-i) lần so sánh để xác định phần tử nhỏ nhất hiện hành

Số lƣợng phép so sánh không phụ thuộc vào tình trạng của dãy số ban đầu

Trang 38

Vị trí này chính là pos thỏa : a[pos-1] a[i ]< a[pos] (1posi).

Chi tiết hơn:

Dãy ban đầu a[0] , a[1] , , a[n-1], xem như đã có đoạn gồm một phần tử a[0] đãđược sắp

Thêm a[1] vào đoạn a[0] sẽ có đoạn a[0] a[1] được sắp

Thêm a[2] vào đoạn a[0] a[1] để có đoạn a[0] a[1] a[2] được sắp

Tiếp tục cho đến khi thêm xong a[n-1] vào đoạn a[0] a[1] a[n-1] sẽ có dãy a[0]a[1]… A[n-1] được sắp

b Thuật toán

//input: dãy (a, n)

//output: dãy (a, n) đã được sắp xếp

Bước 1: i = 2; // giả sử có đoạn a[0] đã được sắpBước 2: x = a[i]; Tìm vị trí pos thích hợp trong đoạn a[0]

đến a[i] để chèn x vàoBước 3: Dời chỗ các phần tử từ a[pos] đến a[i-1] sang

phải 1 vị trí để dành chổ cho xBước 4: a[pos] = x; // có đoạn a[0] a[i] đã được sắpBước 5: i = i+1;

Nếu i n : Lặp lại Bước 2

Ngược lại : Dừng

Trang 39

Ví dụ minh họa A[]:

c Cài đặt thuật toán:

void InsertionSort(int a[], int n )

}

Trang 40

}Nhận xét

Khi tìm vị trí thích hợp để chèn a[i] vào đoạn a[0] đến a[i-1], do đoạn đã được sắp 

có thể sử dụng giải thuật tìm nhị phân để thực hiện việc tìm vị trí pos  giải thuật sắp xếpchèn nhị phân Binary Insertion Sort

Lưu ý: Chèn nhị phân chỉ làm giảm số lần so sánh, không làm giảm số lần dời chỗ.Ngoài ra, có thể cải tiến giải thuật chèn trực tiếp với phần tử cầm canh để giảm điềukiện kiểm tra khi xác định vị trí pos

d Đánh giá giải thuật

Các phép so sánh xảy ra trong mỗi vòng lặp tìm vị trí thích hợp pos Mỗi lần xácđịnh vị trí pos đang xét không thích hợp  dời chỗ phần tử a[pos-1] đến vị trí pos

Giải thuật thực hiện tất cả N-1 vòng lặp tìm pos, do số lượng phép so sánh và dời chỗnày phụ thuộc vào tình trạng của dãy số ban đầu, nên chỉ có thể ước lược trong từngtrường hợp như sau:

IV Các Phương pháp đổi chỗ trực tiếp Interchange Sort

//input: dãy (a, n)

//output: dãy (a, n) đã được sắp xếp

Bước 1 : i = 1; // bắt đầu từ đầu dãyBước 2 : j = i+1; //tìm các cặp phần tử a[j] < a[i], j>iBước 3 : Trong khi j n thực hiện

Nếu a[j]<a[i]: a[i]a[j];

j = j+1;

Bước 4 : i = i+1;

Nếu i < n: Lặp lại Bước 2

Ngược lại: Dừng

Ngày đăng: 11/10/2022, 13:26

HÌNH ẢNH LIÊN QUAN

Xếp hàng mua vé xem phim là một hình ảnh trực quan của khái niệm trên, ngƣời mới đến thêm vào cuối hàng cịn ngƣời ở đầu hàng mua vé và ra khỏi hang, vì vậy hàng cịn đƣợc gọi là cấu trúcFIFO(first in - first out) hay &#34;vào trƣớc - ra trƣớc&#34;. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
p hàng mua vé xem phim là một hình ảnh trực quan của khái niệm trên, ngƣời mới đến thêm vào cuối hàng cịn ngƣời ở đầu hàng mua vé và ra khỏi hang, vì vậy hàng cịn đƣợc gọi là cấu trúcFIFO(first in - first out) hay &#34;vào trƣớc - ra trƣớc&#34; (Trang 33)
Hình ảnh một cây nhị phân - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
nh ảnh một cây nhị phân (Trang 52)
Hình 1Sơ đồ mạng máy tính. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
Hình 1 Sơ đồ mạng máy tính (Trang 60)
Hình2 Sơ đồ mạng máy tính với đa kênh thoại. Định nghĩa 2 - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
Hình 2 Sơ đồ mạng máy tính với đa kênh thoại. Định nghĩa 2 (Trang 61)
Hình 3 Sơ đồ mạng máy tính với kênh thoại thơng báo. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
Hình 3 Sơ đồ mạng máy tính với kênh thoại thơng báo (Trang 61)
Hình 4 Mạng máy tính với kênh thoại một chiều. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
Hình 4 Mạng máy tính với kênh thoại một chiều (Trang 62)
Ví dụ 1 Trên đồ thị vơ hƣớng cho trong hình 5: a, d, c, f ,e là đƣờng đi đơn độ dài 4 - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
d ụ 1 Trên đồ thị vơ hƣớng cho trong hình 5: a, d, c, f ,e là đƣờng đi đơn độ dài 4 (Trang 63)
Ví dụ 2 Trên đồ thị cĩ hƣớng cho trong hình 1.6: a, d, c, f ,e là đƣờng đi đơn độ dài 4 - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
d ụ 2 Trên đồ thị cĩ hƣớng cho trong hình 1.6: a, d, c, f ,e là đƣờng đi đơn độ dài 4 (Trang 64)
Ví dụ 5 Trong đồ thị Gở hình2, đỉnh d và e là đỉnh rẽ nhánh, cịn các cạnh (d, g) và (e, f) là cầu. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
d ụ 5 Trong đồ thị Gở hình2, đỉnh d và e là đỉnh rẽ nhánh, cịn các cạnh (d, g) và (e, f) là cầu (Trang 65)
Ví dụ 7 Xét đồ thị cho trong hình 8, ta cĩ deg(a) = 1, deg(b) = 4, deg(c) = 4, deg(f) = 3, deg(d) = 1, deg(e) = 3, deg(g) = 0 - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
d ụ 7 Xét đồ thị cho trong hình 8, ta cĩ deg(a) = 1, deg(b) = 4, deg(c) = 4, deg(f) = 3, deg(d) = 1, deg(e) = 3, deg(g) = 0 (Trang 67)
Hình 8 Đồ thị vơ hướng. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
Hình 8 Đồ thị vơ hướng (Trang 67)
Hình 9 Đồ thị cĩ hướng. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
Hình 9 Đồ thị cĩ hướng (Trang 68)
Lập bảng để giải bài tốn tìm đƣờng đi ngắn nhất - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
p bảng để giải bài tốn tìm đƣờng đi ngắn nhất (Trang 77)
Nhận xét bảng kết quả đã thu đƣợc. - Giáo trình Nhập môn cấu trúc dữ liệu và giải thuật (Nghề: Thiết kế đồ hoạ - CĐ/TC) - Trường Cao đẳng nghề Đồng Tháp
h ận xét bảng kết quả đã thu đƣợc (Trang 77)

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

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