bài giảng môn Cấu trúc dữ liệu và giải thuật
Cấu Truúc Dữ Liệu LVH Chương TỔNG QUAN VỀ CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT I-GIỚI THIỆU : • Việc viết chương trình để điều khiển máy tính thực cơng việc quản lý người sử dụng, đáp ứng u cầu tính tốn , tìm kiếm , thống kê , lưu trữ v… v… vấn đề khơng phải đơn giản • Việc người sử dụng phải dựa yêu cầu thực tế, thông qua thông tin đối tượng nghiệp vụ chuyên môn xử lý hệ thống cần quản lý, để đáp ứng yêu cầu lưu trữ, tính tốn xữ lý tìm kiếm thơng kê v…v…Thông tin hệ thống tổ chức thành cấu trúc liệu phù hợp, giải thuật tối ưu , sau vận dụng kỹ thuật , kỹ để chuyển hóa yêu cầu thành chương trình thơng qua số ngơn ngữ lập trình, để xử lý máy tính đáp ứng yêu cầu quản lý thông tin người sử dụng II-CẤU TRÚC DỮ LIỆU : KHÁI NIỆM: • Cấu trúc liệu mơ hình thơng tin liệu biểu diễn thơng tin đối tượng liêu hệ thống thực tế Tùy theo tính chất xử lý, thuộc tính mơ tả đối tượng, mà cấu trúc liệu tổ chức khác • Cấu trúc liệu tổ chức tuân thủ theo qui tắc kiểu liệu , kích thước ràng buộc liệu, để tổ chức lưu trữ xử lý máy tính cách tối ưu • Ví dụ : Để quản lý thơng tin nhân viên ta tổ chức cấu trúc liệu sau: struct sinhvien { char tensv[10],lop[10]; int tuoi; float hocbong; }; int i,siso; sinhvien sv[20]; VAI TRÒ CẤU TRÚC DỮ LIỆU : • Tổ chức biểu diễn đối tượng thực tế: Các thành phần liệu thực tế đa dạng phong phú thường chứa quan hệ ràng buộc với nhau, mơ hình liệu tin học toán, cần phải tổ chức, xây dựng cấu trúc liệu thích hợp nhất, cho vừa phản ảnh đầy đủ thơng tin vừa dễ dàng xử lý tính tốn máy tính • Xây dựng thao tác xử lý liệu (giải thuật): Từ yêu cầu xử lý thực tế, cần tìm giải thuật tương ứng để xác định trình tự thao tác máy tính phải thi hành kết mong muốn • Việc xây dựng cấu trúc liệu giải thuật công việc quan trọng quan hệ bổ sung cho Cấu trúc liệu tổ chức đầy đủ, xác việc xây dựng giải thuật trở nên dễ dàng • Với cấu trúc liệu chọn có giải thuật tương ứng phù hợp, cấu trúc có thay đổi thường giải thuật phải thay đổi theo TRANG Cấu Truúc Dữ Liệu LVH • Một cấu trúc liệu tốt giúp cho giải thuật xử lý phát huy tác dụng tốt hơn, đáp ứng nhanh, giải thuật rỏ ràng đơn giản dễ hiểu • Sự thành cơng chương trình tin học kết hợp chặt chẽ cấu trúc liệu giải thuật Thể qua công thức sau : Cấu trúc liệu + Giải thuật = Chương trình CÁC TIÊU CHUẨN ĐÁNH GIÁ : • Phản ánh thực tế : Đây tiêu chuẩn quan trọng nhất, định tính đắn tồn tốn Cần xem xét kỹ lưỡng dự trù trạng thái biến đổi liệu chu trình sống để chọn cấu trúc liệu lưu trữ thể xác đối tượng thực tế Chẳng hạn cần lưu ý việc chọn kiểu liệu cho biến : Ví dụ biểu diễn thơng tin NHAN VIEN có thành phần TUOI nên chọn kiểu unsign char thay chọn char int , thành phần LUONG chon kiểu unsign long thay chọn int , long float Có nhiều biến liệu phù hợp tại, mở rộng chương trình đễ đáp ứng cho yêu cầu phát triển hệ thống biến trở nên khơng phù hợp • Phù hợp với thao tác : Tiêu chuẩn giúp tăng tính hiệu tốn, việc xây dựng phát triển giải thuật đơn giản, tự nhiện hơn, chương trình đạt hiệu cao tốc độ xử lý Chẳng hạn chương trình quản lý nhân viên có liên quan đến lưu trữ ( kiểu file) , thao tác chương trình việc thương xun : Thêm, Xóa , Sửa , Tìm , Duyệt danh sách … Do tổ chức cấu trúc liệu xử lý trực tiếp công việc kiểu FILE giải thuật phức tạp, tốc độ xử lý chậm ln phải làm việc nhớ Trong trường hợp kết hợp với tổ chức liệu danh sách (dãy cấu trúc , danh sách liên kết ) sử dụng nhớ , việc xử lí nhanh , danh sách nhận thông tin bắt đầu chương trình từ danh sách FILE xử lý kết thúc chương trình danh sách tổ chức lưu lại file trước kết thúc • Tiết kiệm tài nguyên hệ thống : Khi xây dựng cấu trúc liệu nên sử dụng tài nguyên hệ thống vừa đủ đảm nhiệm chức Thơng thường có loại tài ngun thường lưu tâm CPU nhớ Tùy theo yêu cầu xử lý, yếu tố xử lý cần nhanh tiết kiệm thời gian tài nguyên nhớ cần sử dụng tối ưu ngược lại III-KIỂU DỮ LIỆU : KHÁI NIỆM: • Kiểu liệu thành phần đặc trưng cho tổ chức, hình dạng, kích thước thành phần nhập xuất tính tốn chương trình Trong ngơn ngữ lập trình kiểu thành phần cấp phát với kích thước nhớ khác tùy theo kiểu để chứa giá trị đáp ứng việc lưu trữ xử lý máy tính • Kiểu liệu xác định với : V tập giá trị hợp lệ mà đối tượng lưu trữ O tập thao tác xử lý thực thi đối tượng Ví dụ : Kiểu số nguyên int : Trong gồm tập giá trị nguyên có giá trị từ -32768 +32767 tập cho phép thực phép tóan số học + - * / %, phép tóan quan hệ < >= != == Trong kiểu chuỗi khơng cho phép sử dụng phép tóan số học này… • Trong ngơn ngữ lập trình kiểu liệu phân làm loại sau : Kiểu liệu : Là kiểu liệu mà ngơn ngữ lập trình định nghĩa sẵn Chẳng hạn : Kiểu số nguyên , số thực, kí tự, luận lý … TRANG Cấu Truúc Dữ Liệu LVH Kiểu có cấu trúc :Là kiểu liệu người sử dụng định nghĩa kiểu dùng, tùy theo mô tả thông tin đối tượng có kiểu định nghĩa khác Gồm kiểu : Chuỗi, dãy, cấu trúc , union, tập tin… Ngồi cịn có kiểu quản lí địa nhớ : Kiểu trỏ (pointer) • Ví dụ: unsign int diem; Int tong,tich; float luong; char hoten[30],diachi[50]; Int day[30]; CÁC KIỂU DỮ LIỆU CƠ BẢN: • Là loại liệu đơn giản , khơng có cấu trúc Chúng thường giá trị vô hương số nguyên, số thực, kí tự, giá trị logic ….Do tính thơng dụng đơn giản mà loại liệu ngơn ngữ lập trình xây dựng sẵn thành phần ngôn ngữ để giảm nhẹ cơng việc cho người lập trình • Bao gồm kiểu sau : Kiểu có thứ tự rời rạc : Số nguyên, kí tự, luận lý , liệt kê, miền con… Kiểu không rời rạc : Số thực • Tùy theo ngơn ngữ lập trình việc định nghĩa sẵn kiểu liệu có khác đơi chút Trong C kiểu kiểu nguyên, thực, kí tự , khơng có kiểu luận lý (Boolean) , kiểu luận lý ĐUNG (TRUE) SAI (FALSE) xem kiểu số nguyên khác zero zero Trong C kiểu kí tự thực chất kiểu số nguyên lưu trữ • Bảng biểu diễn kiểu sau : TÊN KIỂU Ý NGHĨA TẦM TRỊ KÍCH THƯỚC (Byte) int Số nguyên -32768 +32767 unsigned int Số nguyên 65535 không dấu long Số nguyên dài -2.147483648 +2.147483647 unsigned long Số nguyên dài 04.294967295 không dấu char Kí tự A Z , -128 +127 az , 09 , ,’”{]+* … unsinged char Kí tự khơng 255 dấu float Số thực -3.4*10-38 +3.4*10+38 -308 +308 double Số thực lớn -1.7*10 +1.7*10 CÁC KIỂU DỮ LIỆU CÓ CẤU TRÚC: • Với kiểu nhiều trường hợp biểu diễn đầy đủ thông tin chất vật đối tượng thực tế , yêu cầu phải có kiểu mà cho sử dụng người sử dụng tự định kiểu phù hợp dựa kiểu Đa số ngơn ngữ lập trình cài đặt sẵn số kiểu có cấu trúc cung cấp chế cho người lập trình viên tự định nghĩa kiểu liệu • Kiểu liệu người sử dụng định nghĩa kiểu dùng, tùy theo mơ tả thơng tin đối tượng có kiểu định nghĩa khác Gồm kiểu : Chuỗi, dãy, cấu trúc , union, tập tin… TRANG Cấu Truúc Dữ Liệu a) b) c) d) e) LVH Kiểu chuỗi ký tự : Kiểu dãy (mảng) : Kiểu cấu trúc (bản ghi): Kiểu union : Kiểu tập tin (FILE): IV >GIẢI THUẬT : Khái niệm: • Giải thuật bước để giải vấn đề tốn Một vấn đề có nhiều phương pháp giải quyết, nhiên tùy thuôc vào yêu cầu lựa chọn phương pháp phù hợp • Trong chương trình xử lý máy tính, tùy thuộc vào yêu cầu cần tối ưu nhớ tối ưu thời gian xử lý mà vấn đề giải nhiều giải thuật khác • Để viết chương trình ứng dụng hiệu việc xác định cấu trúc liệu giải thuật tối ưu vấn đề quan trọng Giải thuật phụ thuộc vào cấu trúc liệu tổ chức, nhiên việc lựa chọn giải thuật phù hợp tùy theo yêu cầu thực tế • Trong việc phân tích thiết kế hệ thống , qua việc khảo sát phân tích giải thuật biểu diễn lưu đồ để lưu lại kết phân tích, đồng thời làm tảng cho việc xây dựng chương trình Các bước phân tích giải thuật:: • Xác định đặc trưng liệu làm liệu nhập xuất tính tốn • Xác định thao tác cần xử lý , thao tác trừu tượng để tách biệt việc phân tích với việc cài đặt • Phân tích tốn học giải thuật nhằm tìm giá trị trung bình thời gian trường hợp xấu cho đại lượng Nghĩa thời gian xấu tối ưu trường hợp TRANG Cấu Truúc Dữ Liệu LVH Chương CÁC KIỂU DỮ LIỆU CÓ CẤU TRÚC KIỂU MẢNG: I Khái niệm : Mảng kiểu liệu bao gồm nhiều phần tử có kiểu , lưu trữ mảng lưu dãy nhớ , thơng qua vị trí nhớ (chỉ số ) ta truy xuất phần tử dãy Cú pháp khai báo : Khai báo trực tiếp ( khơng có tên kiểu ): [ độ lớn ] ; Khai báo gián tiếp : typedef [ độ lớn ] ; Truy xuất giá trị biến mảng sử dụng cú pháp (chỉ số) Ví dụ : typedef int day[50] ; int a[5] ; day h ; Float b[10] ; Char s[20] ; a[5] Mảng có phần tử nguyên : a[1],a[2],a[3],a[4],a[5] b[10] Mảng có 10 phần tử số thực : b[1],b[1],……,b[10] Biến h Mảng có 50 phần tử nguyên h[1] , h[2], … , h[50] s[20] Mảng có 20 phần tử kí tự s[1],s[2],…… a[1]=29; b[5]=2.34; s[2]=’a’; Xuất nhập mảng : Để xuất nhập mảng ta thường sử dụng vòng lặp for Ví dụ : Viết chương trình nhập vào dãy số nguyên , in dãy nhập , dãy số chẵn ,tổng số chẳn , dãy số lẽ , tổng số lẽ nhập #include for (i=1;i=1; i ) a[i+1]=a[i] ; a[1]=pt_them; *n=*n+1; } Thêm vào cuối: Void them_cuoi(list a,int *n, data pt_them) { a[*n+1]=pt_them; * n=*n+1; } b) Tìm kiếm phần tử : Dựa vào thông tin (thường mã khóa) để tìm kiếm Bằng cách duyệt qua phần tử so sánh giá trị tìm tìm thấy , Hàm tìm kiếm trả vị trí phần tử cần tìm tìm thấy dừng việc tìm kiếm int tim_pt(list a, int n, data pt_tim) { int i ; i=1; while (in) return(0); TRANG 41 Cấu Truúc Dữ Liệu LVH else return(i) ; } c) Loại bỏ phần tử : Thực tìm phần tử cần xóa , tìm thấy xóa cách lùi phần tử đứng sau trước vị trí giảm số phần tử dãy xuống void xoa_pt(list a, int *n, data pt_xoa) { int i,j ; i=tim_pt(a,*n, pt_xoa); if (i!=0) { for (j=i;jlink=NULL Giải thuật sau: void insert_last(pointer *first, data ptu_them) { point p,n; n=new dssv; n->info=ptu_them; p=*first; first if (p==NULL) { n->link=*first; *first=n; } Else p TRANG 46 Cấu Truúc Dữ Liệu { while (p->link !=NULL) p=p->link; n->link=p->link; p->link=n; } LVH NULL } c) Tìm kiếm phần tử danh sách: Giả sử cần tìm phần tử theo khóa (key) đó, việc tìm kiếm duyệt qua phần tử danh sách so sánh với giá trị tìm Hàm tìm kiếm trả địa phần tử cần tìm tìm thấy , trả trị NULL khơng tìm thấy Giải thuật hàm tìm kiếm sau : point search(point first, data ptu_tim) { point p; p=first; while (p!=NULL && strcmp(p->info.key,ptu_tim.key)!=0) p=p->link; return p; } d) Loại bỏ phần tử khỏi danh sách: Có thể có nhiều cách loại bỏ phần tử, ta xét trường hợp : loại bỏ phần tử đầu loại bỏ phần tử Loại bỏ phần tử đầu danh sách: Để loại bỏ phần tử đầu ta gán phần tử đầu cho biến p (p=first), gán first phần tử kế sau ( first= p->link), sau xóa phần tử p Giải thuật sau : void delete_first(point *first) { point p; if (*first!=NULL) { p=*first; *first=p->link; delete p; } } Loại bỏ phần tử danh sách : Ta thực việc tìm kiếm phần tử cần xóa, tìm thấy xóa phần tử cách cho vùng liên kết phần tử đứng trước đế phần tử đứng sau phần tử cần xóa, sau xóa phần tử Giải thuật sau : void delete_element(point *first,data ptu_xoa) { point p,q; p=*first; if (p->link==NULL) /* Trường hợp phần tử cần xóa phần tử đầu */ { delete p; TRANG 47 Cấu Truúc Dữ Liệu LVH *first=NULL; e) } else { /* Trường hợp phần tử cần xóa vị trí khác phần tử đầu */ while (p!=NULL) { q=p; p=p->link; if (strcmp(p->info.hoten,x.hoten)==0) break; } if (p!=NULL) { q->link=p->link; delete p; } } } Sắp xếp danh sách: Dựa khóa để xếp, ta sử dụng phương pháp đổi chổ phần tử Dùng trỏ p q cho p trỏ vào phần tử đầu , q trỏ vào phần tử kế sau, so sánh p q theo khóa đổi chổ chúng cho chưa thỏa điều kiện xếp, sau tăng biến trỏ q đến phần tử kế tiếp, tiếp tục so sánh với p đổi chổ chưa thỏa, trình tiếp tục q duyệt đến phần tử cuối cùng, tiếp tục tăng trỏ p lên phần tử kế sau, trình tiếp tục tương tự với q, danh sách xếp hoàn toàn Giải thuật sau : void sort_list(point *first) { point p,q; data tam; p=*first; while (p->link!=NULL) { q=p->link; while (q!=NULL) { if (q->info.key>p->info.key) { tam=p->info; p->info=q->info; q->info=tam; } q=q->link; } p=p->link; } } f) Duyệt (in) danh sách: TRANG 48 Cấu Truúc Dữ Liệu LVH Lần lượt duyệt qua phần tử danh sách xuất thông tin theo yêu cầu kết thúc danh sách Giải thuật sau : void print_list(point first) { point p; p=first; printf(" KEY1 KEY KEY3 ………………… \n"); if (p==NULL) printf("DANH SACH RONG"); else { while (p!=NULL) { printf(……………………………………………………………); p=p->link; } } } g) Chuyển từ danh sách vào file: Chức đáp ứng việc lưu trữ liệu đĩa sau xử lý xong Giải thuật sau : void list_file(point first,char tenf[30]) { FILE *f ; data x; point p; f=fopen(tenf,"wb"); p=first; while (p!=NULL) { x=p->info; fwrite(&x,sizeof(x),1,f); p=p->link; } fclose(f); } h) Chuyển từ file vào danh sách: Chức đáp ứng việc đưa liệu lưu trữ từ file đĩa danh sách để xử lý Giải thuật sau : void file_list(point *first,char tenf[30]) { FILE *f ; data x; f=fopen(tenf,"rb"); while (fread(&x,sizeof(x),1,f)==1) { them_cuoi(&*first,x); } fclose(f); } VÍ DỤ : Chương trình quản lý sinh viên danh sách liên kết #include #include #include typedef struct sinhvien TRANG 49 Cấu Truúc Dữ Liệu { char hoten[40]; int tuoi; float hocbong; }; typedef struct dssv { sinhvien info; struct dssv *link; }; typedef dssv *point; typedef FILE *taptin; point first; char tenf[30]; void them_dau(point *first ,sinhvien x); void them_cuoi(point *first, sinhvien x); point search(point first, sinhvien x); void xoa_ptu(point *first,sinhvien x); void xoa_ptu_dau(point *first); void in_dssv(point first); void sapxep_dssv(point *first); void dssv_file(point first, char tenf[30]); void file_dssv(point *first,char tenf[30]); void them_dau(point *first ,sinhvien x) { point p; p=new dssv; p->info=x; p->link=*first; *first=p; } void them_cuoi(point *first,sinhvien x) { point p,n; n=new dssv; n->info=x; p=*first; if (p==NULL) { n->link=*first; *first=n; } else { while (p->link !=NULL) p=p->link; n->link=p->link; p->link=n; } LVH } point search(point first, sinhvien x) { point p; p=first; while (p!=NULL && strcmp(p->info.hoten,x.hoten)!=0) p=p->link; return p; } void xoa_ptu(point *first,sinhvien x) { point p,q; p=*first; if (p->link==NULL) { delete p; *first=NULL; } else { while (p!=NULL) { q=p; p=p->link; if (strcmp(p>info.hoten,x.hoten)==0)break; } if (p!=NULL) { q->link=p->link; delete p; } } } void xoa_ptu_dau(point *first) { point p; if (first!=NULL) { p=*first; *first=p->link; delete p; } } void in_dssv(point first) { point p; p=first; printf(" HO TEN HOC BONG \n"); TUOI TRANG 50 Cấu Truúc Dữ Liệu LVH printf(" \n"); if (p==NULL) printf("ds rong"); else { while (p!=NULL) { printf("%15s %10d %15.2f \n",p->info.hoten,p>info.tuoi,p->info.hocbong); p=p->link; printf(" \n"); } } } void sapxep_dssv(point *first) { point p,q; sinhvien tam; p=*first; while (p->link!=NULL) { q=p->link; while (q!=NULL) { if (q->info.hocbong>p>info.hocbong) { tam=p->info; p->info=q->info; q->info=tam; } q=q->link; } p=p->link; } } void dssv_file(point tenf[30]) { taptin f ; sinhvien x; point p; f=fopen(tenf,"wb"); p=first; while (p!=NULL) { first,char x=p->info; fwrite(&x,sizeof(x),1,f); p=p->link; } fclose(f); } void file_dssv(point *first,char tenf[30]) { taptin f ; sinhvien x; f=fopen(tenf,"rb"); while (fread(&x,sizeof(x),1,f)==1) { them_cuoi(&*first,x); } fclose(f); } void main() { int chon; sinhvien x; first=NULL; point p; { clrscr(); printf("1-them vao dau \n"); printf("2-them vao cuoi \n"); printf("3-in danh sach \n"); printf("4-tim kiem \n"); printf("5-xoa phan tu bat ky \n"); printf("6-xoa phan tu dau danh sach \n"); printf("7-sap xep danh sach theo hoc bong \n"); printf("8-chuyen tu danh sach vao file \n"); printf("9-chuyen tu file vao danh sach \n"); printf("0-thoat \n"); printf("Chon cong viec : ");scanf("%d",&chon); fflush(stdin); switch (chon) { case 1: { clrscr(); printf("nhap ten sv :"); gets(x.hoten); TRANG 51 Cấu Truúc Dữ Liệu printf("nhap tuoi sv :");scanf("%d",&x.tuoi); printf("nhap hoc bong sv :");scanf("%f",&x.hocbong); them_dau(&first,x); break; }; case 2: { clrscr(); printf("nhap ten sv :"); gets(x.hoten); printf("nhap tuoi sv :");scanf("%d",&x.tuoi); printf("nhap hoc bong sv :");scanf("%f",&x.hocbong); them_cuoi(&first,x); break; }; case 3: { clrscr(); in_dssv(first);break; }; case 4: { clrscr(); printf("nhap ten sv tim :"); gets(x.hoten); p= search(first,x); if (p==NULL) printf("khong co sinh vien nay\n"); else { printf("da tim thay\n"); printf("ho ten %s tuoi %d \n",p->info.hoten,p->info.tuoi); } break; } case 5: { clrscr(); printf("nhap ten sv can xoa :"); gets(x.hoten); p= search(first,x); if (p==NULL) printf("khong co sinh vien nay\n"); LVH else { printf("da tim thay va xoa \n"); xoa_ptu(&first,x); } break; } case 6: { clrscr(); xoa_ptu_dau(&first); printf("da xoa \n"); break; } case 7: { clrscr(); sapxep_dssv(&first); printf("da sap xep xong \n"); break; } case 8: { clrscr(); printf("nhap ten file can luu : "); gets(tenf); dssv_file(first,tenf); break; } case 9: { clrscr(); printf("nhap ten file can doc : "); gets(tenf); file_dssv(&first,tenf); break; } } getch(); } while (chon!=0); } TRANG 52 ... xử lý mà vấn đề giải nhiều giải thuật khác • Để viết chương trình ứng dụng hiệu việc xác định cấu trúc liệu giải thuật tối ưu vấn đề quan trọng Giải thuật phụ thuộc vào cấu trúc liệu tổ chức,... dễ hiểu • Sự thành cơng chương trình tin học kết hợp chặt chẽ cấu trúc liệu giải thuật Thể qua công thức sau : Cấu trúc liệu + Giải thuật = Chương trình CÁC TIÊU CHUẨN ĐÁNH GIÁ : • Phản ánh thực... Chuỗi, dãy, cấu trúc , union, tập tin? ?? TRANG Cấu Truúc Dữ Liệu a) b) c) d) e) LVH Kiểu chuỗi ký tự : Kiểu dãy (mảng) : Kiểu cấu trúc (bản ghi): Kiểu union : Kiểu tập tin (FILE): IV >GIẢI THUẬT :