1. Trang chủ
  2. » Luận Văn - Báo Cáo

bài tập lớn cấu trúc dữ liệu và giải thuật

35 1 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Nội dung

Đến một bước nào đó, khi khôngcó phép đổi chỗ nào xảy ra thì toàn bộ dãy đã được sắp.Như vậy, sau lần duyệt đầu tiên, phần tử nhỏ nhất của dãy sẽ lần lượt được đổi chỗ cho cácphần tử lớn

Trang 1

BỘ GIÁO DỤC VÀ ĐÀO TẠOTRƯỜNG ĐẠI HỌC CÔNG NGHỆ ĐÔNG Á

Trang 2

BỘ GIÁO DỤC VÀ ĐÀO TẠOTRƯỜNG ĐẠI HỌC CÔNG NGHỆ ĐÔNG Á

Trang 3

Tên sinh viênMã sinh viênPhân Công

Heap SortĐịnh giá biểu thức số học

Merge SortChuyển từ 10 -> 2

Quick SortCây nhị phân

Insertion SortStooge Sort

Bubble SortTìm kiếm tuyến tính

Select SortTìm kiếm Nhị Phân

Trang 4

MỤC LỤC

Nô 6i dung

Trang 5

NỘI DUNG:I.Các thuật toán sắp xếp

1.Bubble Sort – Nổi Bọt :

Giải thuật sắp xếp nổi bọt được thực hiện theo nguyên tắc: Duyệt nhiều lần từ cuối lên đầudãy, tiến hành đổi chỗ 2 phần tử liên tiếp nếu chúng ngược thứ tự Đến một bước nào đó, khi khôngcó phép đổi chỗ nào xảy ra thì toàn bộ dãy đã được sắp.

Như vậy, sau lần duyệt đầu tiên, phần tử nhỏ nhất của dãy sẽ lần lượt được đổi chỗ cho cácphần tử lớn hơn và “nổi” lên đầu dãy Lần duyệt thứ 2, phần tử nhỏ thứ 2 sẽ nổi lên vị trí thứ nhì dãy.v.v

● Ý tưởng:

▪ Xuất phát từ cuối dãy, đổi chỗ các cặp phần tử kế cận để đưa phần tử nhỏ hơn trong cặp phần tử đó về vị trí đúng đầu dãy hiện hành, sau đó sẽ không xét đến nó ở bước tiếp theo, do vậy ở lần xử lý thứ i sẽ có vị trí đầu dãy là i

▪ Lặp lại xử lý trên cho đến khi không còn cặp phần tử nào để xét.

● Các Bước Của Thuật Toán

❖ Bước 1 : i = 0; // lần xử lý đầu tiên

❖ Bước 2 : j = N-1;//Duyệt từ cuối dãy ngược về vị trí i Trong khi (j > i) thực hiện:

Nếu a[j]<a[j-1]

j = j-1;❖ Bước 3 : i = i+1; // lần xử lý kế tiếp

Nếu i >=N-1: Hết dãy DừngNgược lại : Lặp lại Bước 2

● Cài Đặt Thuật Toán Nổi Bọt :

def bubbleSort(arr): # độ dài của mảng n = len(arr)

# xét từng phần tử trong mảng for in i range(n):

# xét các phần tử còn lại for in j range(0, n - i - 1):

# nếu nó lớn hơn phần tử bên cạnh nó

Trang 6

# hai số sẽ đổi chỗ cho nhau arr[j], arr[j + ] = arr[j + 1 1] arr[j], arr = [4, , , , , , , , 9 14 6 17 8 5 2 11 3 27 12, , , ]bubbleSort(arr)

print("Sorted array is:")for in i range len( (arr)): print("%d" % arr[i]),

4 9 14 6 17 8 5 2 11 3 12 27

4 9 14 6 17 8 5 2 11 3 12 27

4 9 14 6 17 8 5 2 3 11 12 27

4 9 14 6 17 8 5 2 3 11 12 274 9 14 6 17 8 2 5 3 11 12 274 9 14 6 17 2 8 5 3 11 12 274 9 14 6 2 17 8 5 3 11 12 27

A[5],a[6]A[4],a[5]

Trang 7

4 9 2 14 6 17 8 5 3 11 12 274 2 9 14 17 8 5 3 11 12 27 6 2 4 9 14 6 17 8 5 3 11 12 27

2 4 9 14 17 8 5 3 6 11 12 27

2 4 9 14 17 8 5 6 3 11 12 27

2 4 9 14 17 8 6 3 5 11 12 272 4 9 14 17 6 3 8 5 11 12 272 4 9 14 6 3 17 8 5 11 12 272 4 9 14 3 6 17 8 5 11 12 272 4 9 3 14 6 17 8 5 11 12 272 4 3 9 14 6 17 8 5 11 12 272 3 4 9 14 6 17 8 5 11 12 27

2 3 4 9 14 6 17 8 5 11 12 27

2 3 4 9 14 6 17 8 5 11 12 27

2 3 4 9 14 6 17 5 8 11 12 272 3 4 9 14 6 5 17 8 11 12 272 3 4 9 14 5 6 17 8 11 12 272 3 4 9 5 14 6 17 8 11 12 272 3 4 5 9 14 6 17 8 11 12 272 3 4 5 9 14 6 17 8 11 12 272 3 4 5 9 14 6 17 8 11 12 27

2 3 4 5 9 14 6 17 8 11 12 27

2 3 4 5 9 14 6 8 17 11 12 272 3 4 5 9 14 6 8 17 11 12 272 3 4 5 9 6 14 8 17 11 12 272 3 4 5 6 9 14 8 17 11 12 272 3 4 5 6 9 14 8 17 11 12 272 3 4 5 6 9 14 8 17 11 12 27

A[5],a[6]A[4],a[5]

Trang 8

12 3 4 5 6 9 14 8 17 11 12 27

2 3 4 5 6 9 8 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 27

2 3 4 5 6 8 9 14 17 11 12 272 3 4 5 6 8 9 14 17 11 12 27

Trang 9

● Độ Phức Tạp Của Thuật Toán Nổi Bọt

Thuật toán sắp xếp nhanh QuickSort:

Sắp xếp nhanh (quicksort) là là thuật toán sắp xếp dựa trên kỹ thuật chia để trị, cụ thể ý tưởng là: chọn một điểm làm chốt (gọi là pivot), sắp xếp mọi phần tử bên trái chốt đều nhỏ hơn chốt và mọi phần tử bên phải đều lớn hơn chốt, sau khi xong ta được 2 dãy con bên trái và bên phải, áp dụng tương tự cách sắp xếp này cho 2 dãy con vừa tìm được cho đến khi dãy con chỉ còn 1 phần tử.

Phần tử được chọn làm chốt rất quan trọng, nó quyết định thời gian thực thi của thuật toán Phần tử được chọn làm chốt tối ưu nhất là phần tử trung vị, phần tử này làm cho số phần tử nhỏ hơn trong dãy bằng hoặc xấp xỉ số phần tử lớn hơn trong dãy Tuy nhiên, việc tìm phần tử nàyrất tốn kém, phải có thuật toán tìm riêng, từ đó làm giảm hiệu suất của thuật toán tìm kiếm nhanh, do đó, để đơn giản, người ta thường sử dụng phần tử chính giữa làm chốt.

Thuật toán phân chia và trị này là thuật toán sắp xếp được sử dụng thường xuyên nhất được đề cập trong bài viết này Khi được định cấu hình chính xác, nó cực kỳ hiệu quả và không yêu cầu sửdụng merge sort Chúng tôi phân vùng danh sách xung quanh một phần tử trục, sắp xếp các giá trịxung quanh trục

Chọn pivot là số cuối cùng có giá trị 32

So sánh số bên trái đầu tiên là 50 > 23(số bên phải) và 50 > 32 (pivot) => Đổi vị trí 50 với 23.So sánh tiếp tục 50 > 9 (số bên phải) và 50 > 32 (pivot) => Đổi vị trí 50 với 9

So sánh tiếp tục 50 > 18 (số bên phải) và 50 > 32 (pivot) => Đổi vị trí 50 với 18So sánh tiếp tục 50 < 61 (số bên phải) và 50 > 32 (pivot) => Giữ nguyên vị trí 50So sánh tiếp tục 50 < 32 (số bên phải) và 50 > 32 (pivot) => Đổi vị trí 50 với 32.

Trang 10

Vậy sau bước này chúng ta có 2 mảng lớn hơn 32 và nhỏ hơn 32 Tiếp tục làm lại như vậy với 2 mảnh

Trong bài viết này, mình cũng sẽ sử dụng phần tử chính giữa làm chốt, thuật toán cài đặt trong PyThon như sau

Code :

defpartition(arr low high, , ): = ( i low-1 ) pivot arr = [high] forjinrange(low high , ): ifarr[] <= pivot: = i i+

arr[i arr], [] = arr[j arr], [] arr[+ ],1arr[high] = arr[high arr], [+] return ( i+ )

defquickSort(arr low high, , ): iflow high < :

= pi partition(arr low high, , ) quickSort(arr low pi, , -1) quickSort(arr pi, + , high)

arr = [int( ) xfor xininput("Nhập Số ").split(",")]

n = len(arr) quickSort(arr n,0, -1) print ("Danh Sách Số:") for ini range(n): print ("%d" %arr[])

Trang 11

mỗi dãy con đều đã có thứ tự

• Ví dụ: dãy 2 ,5 ,4, 3, 9, 8, 6, 17 ,14, 11có thể coi như gồm 6 dãy con không giảm (2); (5, 4); (3); (9, 8); (6, 17);(14,11)▪ Dãy đã có thứ tự coi như có 1 dãy con.

❖ Hướng tiếp cận: tìm cách làm giảm số dãy con không giảm của dãy ban đầu.

❖ Mảng a chia làm 2 phần bằng nhau.❖ Sắp xếp 2 phần

MergeSort arr mid+ (, 1,R)

Merge arr mid (, , L, R)

❖ Các dãy con tăng dần sẽ được tách ra 2 dãy phụ theo nguyên tắc phân phối đều luân phiên

❖ Trộn từng cặp dãy con của hai dãy phụ thành một dãy con của dãy ban đầu � dãy mới có số lượng dãy con giảm đi so với dãy ban đầu

❖ Bước 1 : k = 1; // dãy con có 1 phần tử là dãy không giảm❖ Bước 2 : Lặp trong khi (k < N) // dãy còn hơn 1 dãy con

Trang 12

▪ Bước 2.1: Phân phối đều luân phiên dãy a , a , …, a thành 2 dãy 12nb, c theo từng nhóm k phần tử liên tiếp nhau.

● b = a , …, a , a1k2k+1, …, a , …3k● c = a , …, a , ak+12k3k+1, …, a , …4k

▪ Bước 2.2: Trộn từng cặp dãy con gồm k phần tử của 2 dãy b, c vào a

▪ Bước 2.3: k = k*2;▪

def mergeSort(arr): if len(arr) > :1

# Tìm phần giữa của mảng mid = len(arr)//2 L = arr[:mid] # thành 2 nửa R = arr[mid:] # Sắp xếp nửa đầu mergeSort(L) # Sắp xếp nửa sau mergeSort(R) i = j = k = 0

# Sao chép dữ liệu vào mảng tạm thời L [] và R [] while i < len(L) and j < len(R):

L[i] < R[j]:if arr[k] = L[i] i += 1 else: arr[k] = R[j] j += 1 k += 1

# Kiểm tra xem có phần tử nào còn lại không while i < len(L):

arr[k] = L[i] i += 1 k += 1 while j < len(R): arr[k] = R[j] j += 1 k += 1# Mã để in danh sáchdef printList(arr): for in range leni ( (arr)): print(arr[i], end=" ") print()

if name == ' main ': arr = [2, 5, 4, 3, 9, 8, 6, 17, 14, 11] print("Các số trong mảng:", end="\n") printList(arr)

mergeSort(arr)

Trang 13

-Độ phức tạp của thuật toán:

Độ phức tạp về thời gian: Sắp xếp các mảng trên các máy khác nhau Merge Sort là một

thuật toán đệ quy và độ phức tạp thời gian có thể được biểu thị như sau.T (n) = 2T (n / 2) + θ (n)

- Sự lặp lại trên có thể được giải quyết bằng cách sử dụng phương pháp tree lặp lại hoặc phương pháp Master Nó nằm trong trường hợp II của Phương pháp Master và nghiệm của sự tái diễn là θ (nLogn) Độ phức tạp thời gian của Sắp xếp hợp nhất(Merge Sort) là θ(nLogn) trong cả 3 trường hợp (xấu nhất, trung bình và tốt nhất) vì sắp xếp hợp nhất luôn chia mảng thành hai nửa và mất thời gian tuyến tính để hợp nhất hai nửa.

Trang 14

Giải thuật này coi như dãy được chia làm 2 phần Phần đầu là các phần tử đãđược sắp Từ phần tử tiếp theo, chèn nó vào vị trí thích hợp tại nửa đã sắp saocho nó vẫn được sắp

● Giả sử có một dãy a , a , ,a trong đó i phần tử đầu tiên a , a , ,a đã 01n-101i-1

có thứ tự

● Tìm cách chèn phần tử a vào vị trí thích hợp của đoạn đã được sắp để có i

dãy mới a , a , ,a trở nên có thứ tự Vị trí này chính là vị trí giữa hai 01i

phần tử a và a thỏa a < a < a (1≤k≤i) k-1kk-1ik

Các Bước Của Thuật Toán

1Bước 1 : i = 1;//giả sử có đoạn a[1] đã được sắp

2Bước 2 : x = a[i]; Tìm vị trí pos thích hợp trong đoạn a[1] đến a[i-1]để chèn a[i] vào

3Bước 3 : Dời chỗ các phần tử từ a[pos] đến a[i-1] sang phải1 vị trí để dành chổ cho a[i]

4Bước 4 : a[pos] = x; //có đoạn a[1] a[i] đã được sắp

for in i range(1, len(arr)):

key = arr[i]

# Di chuyển các phần tử của arr [0 i-1], đó là # lớn hơn khóa, đến một vị trí phía trước # vị trí hiện tại của họ

j = i-1

while j >=0 and key < arr[j] : arr[j+ ] = arr[j]1 j -= 1 arr[j+1] = key

# Mã trình điều khiển để kiểm tra ở trên

Trang 15

insertionSort(arr)print ("Mảng đã sắp xếp là”:)for in i range len( (arr)): print ("%d" %arr[i])

kết quả:

Mô tả thuật toán:

i j=i-1 [4, 9, 14, 6, 17, 8 , 5 , 2 ,11 ,3 ,27 ,12] swap0 1 [4, 9, 14, 6, 17, 8 , 5 , 2 ,11 ,3 ,27 ,12] (a[0];a[0])1 2 [4, 9, 14, 6, 17, 8 , 5 , 2 ,11 ,3 ,27 ,12] (a[1];a[1])2 3 [4,6, 9, 14, 17, 8 , 5 , 2 ,11 ,3 ,27 ,12] (a[2];a[3])3 4 [4,6, 9, 14, 17, 8 , 5 , 2 ,11 ,3 ,27 ,12] (a[a];a[a])4 5 [4, 6, 8, 9, 14, 17, 5 , 2 ,11 ,3 ,27 ,12] (a[a];a[a])5 6 [4, 5, 6, 8, 9, 14, 17, 2 ,11 ,3 ,27 ,12] (a[5];a[5])6 7 [4, 5, 6, 8, 9, 14, 17, 2 ,11 ,3 ,27 ,12] (a[6];a[6])7 8 [2,4, 5, 6, 8, 9, 14, 17 ,11 ,3 ,27 ,12] (a[1];a[7])8 9 [2,4, 5, 6, 8, 9,11 , 14, 17,3 ,27 ,12] (a[6];a[8])9 10 [2, 3, 4, 5, 6, 8, 9,11 , 14, 17 ,27 ,12] (a[9];a[9])10 11 [2, 3, 4, 5, 6, 8, 9,11 , 14, 17 ,27 ,12] (a[10];a[10])

Trang 16

Code :

- import sys

A = [4, , , , , , , , 9 14 6 17 8 5 2 11 3 27 12, , , ,]

# Duyệt qua tất cả các phần tử mảngfor in i range len( (A)):

# Tìm phần tử tối thiểu còn lại # mảng không được sắp xếp min_idx = i

for in j range(i+1, len(A)): A[min_idx] > A[j]:if min_idx = j

# Hoán đổi phần tử tối thiểu được tìm thấy với # phần tử đầu tiên

A[i], A[min_idx] = A[min_idx], A[i]

# Mã trình điều khiển để kiểm tra ở trênprint ("Sorted array")

Trang 18

8 9 11 2 3 4 5 6 8 9 11 12 17 27 14 a[8], a[11]

Sắp xếp Stooge là một thuật toán sắp xếp đệ quy Nó được định nghĩanhư bên dưới (để sắp xếp thứ tự tăng dần)

Bước 1: Nếu giá trị tại chỉ mục 0 lớn hơn giá trị ở chỉ mục cuối cùng, hoán đổi chúng.Bước 2: Đệ quy,

a) Stooge sắp xếp 2/3 ban đầu của mảng b) Stooge sắp xếp 2/3 cuối cùng của mảng c) Stooge sắp xếp lại 2/3 ban đầu để xác nhận.

LƯU Ý: Luôn lấy điểm kết thúc của ((2/3) * N) để chọn phần tử

Minh họa thuật toán : Đầu vào: 4 5 3 21

Sau đó, sắp xếp đệ quy 2/3 phần tử cuối cùng.1 3 4 5 2

1 2 3 4 5

Một lần nữa, hãy sắp xếp 2/3 phần tử ban đầu để xác nhận dữ liệu cuối cùng được sắp xếp.1 2 3 4 5

● Code:

Trang 19

l >= h:if return

# Nếu phần tử đầu tiên nhỏ hơn # cuối cùng, hãy hoán đổi chúng if arr[l]>arr[h]:

t = arr[l] arr[l] = arr[h] arr[h] = t

# Nếu có nhiều hơn 2 phần tử trong # mảng

if h-l+1 2: t = (int)((h-l+ )/ )1 3

# Sắp xếp đệ quy 2/3 phần tử đầu tiên stoogesort(arr, , l (h-t))

# Sắp xếp đệ quy 2/3 phần tử cuối cùng stoogesort(arr, l+t (h)),

# Sắp xếp đệ quy 2/3 phần tử đầu tiên # một lần nữa để xác nhận stoogesort(arr, , l (h-t))

# dẫn xuấtarr = [2, , , , ]n = len(arr)

stoogesort(arr, n- )1print("Mảng đã sắp xếp là:")for in i range(0, n): print(arr[i], end = "\n")

Trang 20

7.Heap Sort – Sắp Xếp Đống:

Heap sort là một kỹ thuật sắp xếp dựa trên so sánh dựa trên cấu trúc dữ liệu Binary Heap Nó tương tự như sắp xếp lựa chọn trong đó đầu tiên chúng ta tìm phần tử tối thiểu và đặt phần tử tối thiểu ở đầu Chúng tôi lặp lại quá trình tương tự cho các phần tử còn lại.

Tại sao biểu diễn dựa trên mảng cho Binary Heap?

Vì một đống nhị phân là một cây nhị phân hoàn chỉnh, nó có thể dễ dàng được biểu diễn dưới dạng một mảng và biểu diễn dựa trên mảng là không gian hiệu quả Nếu nút cha được lưu trữ ở chỉ mục I, nút con bên trái có thể được tính bằng 2 * I + 1 và nút con bên phải bằng 2 * I + 2 (giả sử việc lập chỉ mục bắt đầu bằng 0).

Thuật toán sắp xếp đống để sắp xếp theo thứ tự tăng dần:1 Xây dựng một đống tối đa từ dữ liệu đầu vào

2 Tại thời điểm này, mục lớn nhất được lưu trữ ở gốc của đống Thay thế nó bằng mục cuối cùng

của đống, sau đó giảm kích thước của đống xuống 1 Cuối cùng, chất đống gốc của cây

3 Lặp lại bước 2 khi kích thước của đống lớn hơn 1.Ý Tưởng

Dữ liệu đầu vào: 4, 10, 3, 5, 1 4 (0)

/ \ 10 (1) 3 (2) / \ 5 (3) 1 (4)

Các số trong ngoặc đại diện cho các chỉ số trong mảng biểu diễn dữ liệu.

Áp dụng quy trình heapify cho chỉ mục 1: 4 (0)

/ \ 10 (1) 3 (2) / \5 (3) 1 (4)

Áp dụng quy trình heapify cho chỉ mục 0: 10 (0)

/ \ 5 (1) 3 (2)

Trang 21

/ \ 4 (3) 1 (4)

Thủ tục heapify tự gọi đệ quy để xây dựng heap theo cách từ trên xuống.

# Để xếp đống cây con bắt nguồn từ chỉ mục i.# n là kích thước của đống

def heapify(arr n i):, ,

largest = i # Initialize largest as root l = * i + 2 1 # left = 2*i + 1 r = * i + 2 2 # right = 2*i + 2

# Xem liệu con bên trái của root có tồn tại hay không và # lớn hơn gốc

if l < n and arr[largest] < arr[l]: largest = l

# Xem liệu con bên phải của root có tồn tại hay không và # lớn hơn gốc

if r < n and arr[largest] < arr[r]: largest = r

# Thay đổi gốc, nếu cần if largest != i:

arr[i] arr[largest] = arr[largest] arr[i] , , # hoán đổi # Xử lý gốc.

heapify(arr, , n largest)

# Hàm chính để sắp xếp một mảng có kích thước đã chodef heapSort(arr):

n = len(arr) # Xây dựng mức tối đa for in i range(n // - 2 1, , -1- ):1 heapify(arr, i) # Từng phần tử trích xuất một for in i range(n - 1 0, , -1): arr[i], arr[0] = arr[0], arr[i] # swap heapify(arr, , i0)

# Mã trình điều khiểnarr = [4, , , , ]heapSort(arr)n = len(arr)

print("Mảng đã sắp xếp là: ")for in i range(n): print("%d" % arr[i]),

Ngày đăng: 09/05/2024, 10:57

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w