Báo cáo đồ án cơ sở ngành - Công nghệ thông tin - bậc đại họcĐề tài : Tìm hiểu cấu trúc mảng và các thao tác sắp xếp trên mảng (có code và demo - liên hệ vuongthienminh@gmail.com để nhận)
Trang 1ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
ĐỒ ÁN CƠ SỞ CHUYÊN NGÀNH TIN HỌC VIỄN THÔNG
Trang 2TÊN ĐỀ TÀI Tìm hiểu về cấu trúc mảng và các thao tác sắp xếp trên mảng
Chuyên ngành: Tin Học Viễn Thông
Giảng viên hướng dẫn: Nguyễn Lê Mai Duyên
Sinh viên thực hiện: Nguyễn Minh Quỳnh Mã số: 4245 Ngày nộp/nhận xét:
Ngày bảo vệ:
Trang 3ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
NHẬN XÉT CỦA GIẢNG VIÊN HƯỚNG DẪN
1
-DTU
Trang 4ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
2
-DTU
Trang 5ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
3
-DTU
Trang 6ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
4
-DTU
Trang 7ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
5
-DTU
Trang 8ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
6
-DTU
Trang 9ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
7
-DTU
Trang 10ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
8
-DTU
Trang 11ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
9
-DTU
Trang 12ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
10
-DTU
Trang 13ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
11
-DTU
Trang 14ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
12
-DTU
Trang 15ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
13
-DTU
Trang 16ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
14
-DTU
Trang 17ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
15
-DTU
Trang 18ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
16
-DTU
Trang 19ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
17
-DTU
Trang 20ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
18
-DTU
Trang 21ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
19
-DTU
Trang 22ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
20
-DTU
Trang 23ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
21
-DTU
Trang 24ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
MỤC LỤC
LỜI NÓI ĐẦU 3ĐẶC TẢ BÀI TOÁN (SPECIFICATIONS) 4YÊU CẦU CỦA BÀI TOÁN (REQUIREMENTS) 4
CƠ SỞ LÝ THUYẾT (THEORY) 4CHƯƠNG 1: TÌM HIỂU VỀ CẤU TRÚC DỮ LIỆU MẢNG 4
1 NHU CẦU TÌM KIẾM VÀ SẮP XẾP DỮ LIỆU 8
2 PHƯƠNG PHÁP NỔI BỌT (BUBBLE SORT) 9
3 PHƯƠNG PHÁP CHÈN TRỰC TIẾP (INSERTION SORT) 12
4 PHƯƠNG PHÁP CHỌN TRỰC TIẾP (SELECTION SORT) 14
5 PHƯƠNG PHÁP NHANH (QUICK SORT) 16PHÂN TÍCH YÊU CẦU (SYSTEM ANALYSIS) 19
SƠ ĐỒ KHỐI (PROCESS/FLOWCHART) 20TỔNG QUÁT 20BUBBLE SORT 21INSERTION SORT 22SELECTION SORT 23QUICK SORT 24KHAI BÁO CẤU TRÚC DỮ LIỆU (DATA STRUCTURE) 25LẬP TRÌNH/CÁC BƯỚC XÂY DỰNG BÀI TOÁN (CODING) 25KIỂM THỬ (TESTING) 29TRIỂN KHAI (IMPLEMENTATION) 29KẾT LUẬN 30TÀI LIỆU THAM KHẢO 30
22
-DTU
Trang 25ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
LỜI NÓI ĐẦU
Kính gửi đến các thầy cô giáo, đồ án cơ sở của em với đề tài được chọn là “Tìm
hiểu cấu trúc mảng và các thao tác sắp xếp”.
Trong đồ án gồm có hai phần chính:
Phần lý thuyết chungPhần bài toán ứng dụng của các phương pháp sắp xếp
Cuộc sống ngày càng hiện đại hơn, và việc phát triển công nghệ luôn làmột trong những vấn đề được đặt lên hàng đầu Trong đó công nghệ thông tin làmột ngành học mũi nhọn không chỉ đối với chỉ tiêu giảng dạy của trường ta C++
là một môn học cơ bản của một sinh viên ngành công nghệ thông tin, và đề tài vềsắp xếp mảng là một phần không thể thiếu trong bài học của C++ vì thế em đãchọn đề tài này
Vì đề tài em được chọn là đề tài em đang theo học theo tiến trình học ở lớpnên em chưa thể đi sâu, những kiến thức tìm hiểu được chưa được chi tiết Vậykhi em gửi đề tài này đến quý thầy cô, kính mong quý thầy cô xem xét, hướng dẫnthêm cho em!
Em xin chân thành cảm ơn sự nhiệt tình hướng dẫn của cô Nguyễn Lê Mai
được thuận lợi hơn trong quá trình làm đề tài Sau khi thực hiện đề tài em đã thuđược rất nhiều kiến thức bổ ích, thiết thực, góp phần rất lớn cho quá trình học tập
và công việc của bản thân em sau này
Tuy nhiên, đây là lần đầu tiên làm đồ án, kinh nghiệm trình bày một vấn đề,một đề tài của em chưa có nên em không thể tránh khỏi những thiếu sót Vậy emkính mong quý thầy cô xem xét và góp ý cho em để bản thân em có thể hoàn thiệnhơn
Em xin chân thành cảm ơn !
23
-DTU
Trang 26ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
ĐẶC TẢ BÀI TOÁN (SPECIFICATIONS)
Viết chương trình khởi tạo một mảng Random gồm 1000 phần tử, sau đó sửdụng các phương pháp sắp xếp hoặc các chức năng mà chương trình có để sắp xếpmảng trên Tính thời gian sắp xếp ứng với phương pháp sắp xếp đã chọn, sau đóxuất kết quả ra màn hình
YÊU CẦU CỦA BÀI TOÁN (REQUIREMENTS)
Cơ sở lý thuyết: Tìm hiểu cấu trúc dữ liệu mảng
Các thao tác sắp xếp trên mảng
Chương trình: Các đoạn chương trình thực hiện các thuật toán sắpxếp như: sắp xếp nổi bọt (Bubblesort), sắp xếp chèn trực tiếp (Insertionsort), sắpxếp chọn trực tiếp (Selectionsort), sắp xếp nhanh (Quicksort)
CƠ SỞ LÝ THUYẾT (THEORY)
CHƯƠNG 1: TÌM HIỂU VỀ CẤU TRÚC DỮ LIỆU MẢNG
1 KHÁI NIỆM
Mảng là một dãy các phần tử có cùng kiểu được đặt liên tiếp trong bộ nhớ
và có thể truy xuất đến từng phần tử bằng cách thêm một chỉ số vào sau tên củamảng
Điều này có nghĩa là: Chúng ta có thể lưu 5 giá trị kiểu int mà không cần
phải khai báo 5 biến khác nhau
Ví dụ: một mảng chứa 5 giá trị nguyên kiểu int có tên là huang có thể được
biểu diễn như sau:
huang 0 1 2 3 4
Trong đó mỗi một ô trống biểu diễn một phần tử của mảng, trong trường
hợp này là các giá trị kiểu int Chúng được đánh số từ 0 đến 4 vì phần tử đầu tiên
của mảng luôn là 0 bất kể độ dài của nó là bao nhiêu
Như bất kì biến nào khác, một mảng phải được khai báo trước khi có thể sử
dụng Một khai báo điển hình cho một mảng trong C++ như sau:
type name [elements];
Trong đó type là một kiểu dữ liệu hợp lệ (int, float…), name là một biến hợp lệ và trường elements chỉ định mảng đó sẽ chứa bao nhiêu phần tử.
Vì vậy, để khai báo huang như đã trình bày ở trên chúng ta chỉ cần một
dòng đơn giản như sau:
int huang[5];
24
-DTU
Trang 27ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
Chú ý: Trường elements bên trong cặp ngoặc [] phải là một giá trị hằng khi
khai báo một mảng, vì mảng là một khối nhớ tĩnh có kích cỡ xác định và trình biêndịch phải có khả năng xác định xem cần bao nhiêu bộ nhớ cấp phát cho mảngtrước khi các lệnh có thể thực hiện
2 KHỞI TẠO MỘT MẢNG
Khi khai báo một mảng với tầm hoạt động địa phương (trong một hàm),theo mặc định nó sẽ không được khởi tạo, vì vậy nội dung của nó là không xácđịnh cho đến khi chúng ta lưu các giá trị lên đó
Nếu chúng ta khai báo một mảng toàn cục (bên ngoài tất cả các hàm), nó sẽđược khởi tạo và tất cả các phần tử được đặt bằng 0 Vì vậy nếu chúng ta khai báomảng toàn cục: int huang[5];
Mọi phần tử của huang sẽ được khởi tạo là 0:
huang huang[0] huang[1] huang[2] huang[3] huang[4]
Nhưng thêm vào đó, khi chúng ta khai báo một mảng, chúng ta có thể gáncác giá trị khởi tạo cho từng phần tử của nó
này có thể được coi là một sự lặp lại không cần thiết nên C++ cho phép để trống
giữa cặp ngoặc vuông, kích thước của mảng được xác định bắng số giá trị giữa cặpngoặc nhọn
3 TRUY XUẤT ĐẾN CÁC PHẦN TỬ MẢNG
Ở bất kì điểm nào của chương trình trong tầm hoạt động của mảng, chúng
ta có thể truy xuất từng phần tử của mảng để đọc hay chỉnh sửa như là đối với mộtbiến bình thường Cấu trúc của nó như sau:
Name [index]
Như trong ví dụ trước ta có mảng huang gồm 5 phần tử có kiểu int, chúng
ta có thể truy xuất đến từng phần tử của mảng như sau:
Trang 28ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
Ví dụ: để lưu giá trị 25 vào phần tử thứ 3 của huang ta viết như sau:
Chú ý rằng phần tử thứ ba của huang là huang[2], vì mảng bắt đầu từ chỉ
số 0 Vì vậy phần tử cuối cùng là huang[4] Vì vậy nếu chúng ta viết huang[5],
chúng ta sẽ truy xuất đến phần tử thứ 6 của mảng và vượt quá giới hạn của mảng
Trong C++, việc vượt quá giới hạn chỉ số của mảng là hoàn toàn hợp lệ, tuy
nhiên nó có thể gây ra những vấn đề thực sự khó phát hiện bởi vì chúng không tạo
ra những lỗi trong quá trình dịch nhưng chúng có thể tạo ra những kết quả khôngmong muốn trong quá trình thực hiện Nguyên nhân của việc này sẽ được nói đến
kỹ hơn khi chúng ta bắt đầu sử dụng con trỏ
Cần phải nhấn mạnh rằng chúng ta sử dụng cặp ngoặc vuông cho hai tácvụ: đầu tiên là đặt kích thước cho mảng khi khai báo chúng và thứ hai, để chỉ địnhchỉ số cho một phần tử cụ thể của mảng khi xem xét đến nó
4 MẢNG NHIỀU CHIỀU
Mảng nhiều chiều có thể coi như mảng của mảng, ví dụ: mảng hai chiều cóthể tưởng tượng như là một bảng hai chiều gồm các phần tử có kiểu dữ liệu cụ thể
và giống nhau
0 1 2 3 4
12
huang biểu diễn một mảng hai chiều kích thước 3x5 có kiểu int Cách khai
báo mảng này như sau: int huang [3][5];
ví dụ: cách truy xuất đến phần tử thứ hai theo chiều dọc và thứ tư theochiều ngang trong một biểu thức như sau: huang[1][3];
Trang 29ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
Mảng nhiều chiều không bị giới hạn bởi hai chỉ số (hai chiều), chúng có thểchứa bao nhiêu chỉ số tuỳ thích mặc dù ít khi cần phải dùng đến mảng lớn hơn 3chiều Hãy thử xem xét số lượng bộ nhớ mà một mảng có nhiều chỉ số cần đến
Ví dụ: Char theky[10][30][50][70][100];
Gán một giá trị char cho mỗi giây trong một thê kỷ, phải cần đến hơn 3tỷ
giá trị chars! Chúng ta sẽ phải cần khoảng 3GB RAM để khai báo nó
Mảng nhiều chiều thực ra là một khái niệm trừu tượng vì chúng ta có thể cókết quả tương tự với mảng một chiều bằng một thao tác đơn giản giữa các chỉ sốcủa nó: int huang[3][5]; tương đương với
Dưới đây là hai ví dụ cùng với một kết quả như nhau, một sủ dụng haimảng hai chiều và một là sử dụng mảng một chiều:
#include<iostream.h> #include<iostream.h>
int quynh[HEIGHT][WIDTH]; int quynh[HEIGHT*WIDTH];
Không một chương trình nào viết gì ra màn hình nhưng cả hai đều gán giá
trị vào khối nhớ có tên huang theo cách sau:
0 1 2 3 4
0
2
Chúng ta đã định nghĩa hằng (#define) để đơn giản hóa những chỉnh sửa
sau này của chương trình , ví dụ: trong trường hợp chúng ta quyết định tăng kíchthước của mảng với chiều cao là 6 thay vì là 3, chúng ta chỉ cần thay đổi dòng:
#define HEIGHT 3thành
Trang 30ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
5 DÙNG MẢNG LÀM THAM SỐ
Vào một lúc nào đó có thể chúng ta cần phải truyền một mảng tới một hàm
như là một tham số Trong C++, việc truyền theo tham số giá trị một khối nhớ là
không hợp lệ, ngay cả khi nó được tổ chức thành một mảng Tuy nhiên chúng talại được phép truyền địa chỉ của nó, việc này cũng tạo ra kết quả thực tế giốngthao tác ở trên nhưng nhanh hơn nhiều và hiệu quả hơn
Để có thể nhận mảng là tham số thì điều duy nhất chúng ta phải làm khikhai báo hàm là chỉ định trong phần tham số kiểu dữ liệu cơ bản của mảng, tênmảng và cặp ngoặc vuông trống Ví dụ: hàm sau:
void procedure(int lee[]) Nhận vào một tham số có kiểu “mảng của char” và có tên là “lee” Để truyền tham số cho hàm này một mảng được khai báo: int mang[50];
chỉ cần gọi hàm như sau: procedure(mang);
Trong phần khai báo hàm chúng ta cũng có thể dùng tham số là các mảngnhiều chiều Cấu trúc của mảng 3 chiều như sau:
void procedure(int mang[][3][6])
Chú ý rằng cặp ngoặc vuông đầu tiên để trống nhưng các cặp ngoặc vuông
sau thí không Bạn luôn luôn phải làm vậy vì trình biên dịch C++ phải có khả
năng xác định độ lớn của các chiều thêm vào của mảng
CHƯƠNG 2: CÁC PHƯƠNG PHÁP SẮP XẾP CƠ BẢN
1 NHU CẦU TÌM KIẾM VÀ SẮP XẾP DỮ LIỆU
Trong hầu hết các hệ lưu trữ, quản lý dữ liệu, thao tác tìm kiếm thườngđược thực hiện nhất để khai thác thông tin:
Do các hệ thống thông tin thường phải lưu trữ một khối lượng dữ liệu đáng
kể, nên việc xây dựng các giải thuật cho phép tìm kiếm nhanh sẽ có ý nghĩa rấtlớn Nếu dữ liệu trong hệ thống đã được tổ chức theo một trật tự nào đó, thì việctìm kiếm sẽ tiến hành nhanh chống và hiệu quả hơn:
Vì thế, khi xây dựng một hệ quản lý thông tin trên máy tính, bên cạnh cácthuật toán tìm kiếm, các thuật toán sắp xếp dữ liệu cũng là một trong những chủ đềđược quan tâm hàng đầu
Hiện nay đã có nhiều giải thuật tòm kiếm và sắp xếp được xây dựng, mức
độ hiệu quả của từng giải thuật còn phụ thuộc vào tính chất của cấu trúc dữ liệu cụthể mà nó tác động đến Dữ liệu được lưu trữ chủ yếu trong bộ nhớ chính và trên
bộ nhớ phụ, do đặc điểm khác nhau của thiết bị lưu trữ, các thuật toán tìm kiếm vàsắp xếp được xây dựng cho các cấu trúc lưu trữ trên bộ nhớ chính hoặc phụ cũng
có những đặc thù khác nhau Chương trình này sẽ trình bày các thuật toán sắp xếp
và tìm kiếm dữ liệu được lưu trữ trên bộ nhớ chính - gọi là các giải thuật tìm kiếm
và sắp xếp nội
28
-DTU
Trang 31ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
2 PHƯƠNG PHÁP NỔI BỌT (BUBBLE SORT)
2.1 GIẢI THUẬT:
Ý tưởng chính của giải thuật là xuất phát tử cuối (đầu) dãy, đổi chỗ các cặpphần tử kề cận đưa phần tử nhỏ (lớn) hơn trong cặp phần tử đó về vị trí đứng đầu(cuối) 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 tiến hành như sau:
Bước 1: i=1; //lần xử lý đầu tiên
Bước 2: j=N; //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]:a[j]<a[j-1]; //xét cặp phần tử kế cậnj=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 thì lặp lại bước 2
Ví dụ: Cho dãy số : 12 2 8 5 1 6 4 15
29
-DTU
Trang 32ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
30
-DTU
Trang 33ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
2.2 CÀI ĐẶT:
Cài đặt thuật toán sắp xếp theo kiểu nổi bọt thành hàm BubbleSort:
void BubbleSort(int a[],int N)
{ int i,j;
for(i=0;i<N-1;i++)for(j=N-1;j>i;j )
if(a[j]<a[j-1]) //nếu sai vị trí thì đổi chỗHoanvi(a[j],a[j-1]); }
2.3 ĐÁNH GIÁ GIẢI THUẬT:
Đối với giải thuật nổi bọt, số lượng các phép so sánh xảy ra không phụthuộc vào tình trạng của dãy số ban đầu, nhưng số lượng phép hoán vị thực hiệntuỳ thuộc vào kết quả so sánh, có thể ước lượng trong từng trường hợp như sau:
n i
n n i
n i
n n i
Trang 34ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
3 PHƯƠNG PHÁP CHÈN TRỰC TIẾP (INSERTION SORT)
3.1 GIẢI THUẬT:
Giả sử có một dãy a 1 ,a 2 ,…,a n trong đó I phần tử đầu tiên a 1 ,a 2 ,…,a i-1 đã cóthứ tự Ý tưởng chính của giải thuật sắp xếp bằng phương pháp chèn trực tiếp là
tìm cách chèn phần tử a i vào vị trí thích hợp của đoạn đã được sắp xếp để có dãy
mới a 1 ,a 2 ,…,a i trở nên có thứ tự Vị trí này chính là vị trí giữa hai phần tử a k-1 và
a k thoả a k-1 <a i <a k (1<k<i)
Cho dãy ban đầu a 1 ,a 2 ,…,a n ta có thể xem như đã có đoạn gồm một phần tử
a 1 đã được sắp xếp, sau đó thêm a 2 vào đoạn a 1 a 2 được sắp, tiếp tục thêm a 3 vào
đoạn a 1 a 2 để có đoạn a 1 a 2 a 3 được sắp; tiếp tục cho đến khi thêm xong a n vào đoạn
a 1 a 2 …a n sẽ có dãy a 1 a 2 …a n được sắp
Các bước tiến hành như sau:
Bước 1: i=2; //giả sử có đoạn a[1] đã được sắp
Bước 2: x=a[i]; tìm vị trí pos thích hợp trong đoạn a[1] đến a[i-1] để chèna[i] vào
Bước 3: Dời chỗ các phần tử từ a[pos] đến a[i-1] sang phải 1 vị trí để dànhchỗ cho a[i]
Bước 4: a[pos]=x; //có đoạn a[1]…a[i] đã được sắp
Bước 5: i=i+1; nếu i<n lặp lại bước 2,ngược lại thì dừng lại
Ví dụ: Cho dãy số a:
12 2 8 5 1 6 4 15
32
-DTU
Trang 35ĐẠI HỌC DUY TÂN KHOA CÔNG NGHỆ THÔNG TIN
3.2 CÀI ĐẶT:
Cài đặt thuật toán sắp xếp chèn trực tiếp thành hàm InsertionSort:
void InsertionSort(int a[], int N){ int pos, i;
int x; //lưu giá trị a[i] tránh bị ghi đè khi dời chỗ các phần tử.for(int i=1;i<N;i++) //đoạn a[0] đã sắp
{ x=a[i]; pos=i-1; //tìm vị trí chèn x
while((pos>=0)&&(a[pos]>x)){ //kết hợp dời chỗ các phần tử sẽ đứng sau xtrong dãy mới
a[pos+1]=a[pos]; pos ;
}a[pos+1]; //chèn x cào dãy}
33
-DTU