1. Trang chủ
  2. » Tất cả

(Tiểu luận) môn cấu trúc dữ liệu và thuật toán lớp cấu trúc dữ liệu và thuật toán 1 1(13 14fs) 2 lt

43 2 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

TRƯỜNG ĐẠI HỌC PHENIKAA KHOA KHOA HỌC CƠ BẢN ⸎⸎⸎⸎⸎ BÀI TẬP LỚN KẾT THÚC HỌC PHẦN Môn Cấu trúc liệu thuật toán Lớp Cấu trúc liệu thuật toán_1.1(13.14FS).2_LT Sinh viên : Đỗ Minh Quân Lớp : K14-CNTT3 Mã SV : 20010879 h 1.1 Các thao tác danh sách liên kết Danh sách liên kết cấu trúc liệu có kiểu tuần tự, phần tử danh sách liên kết có chứa thơng tin, qua ta truy cập tới phần tử Danh sách liên kết xem bố trí phần tử tập Bắt đầu từ nút, ta coi phần tử danh sách Từ nút này, theo liên kết mà trỏ tới, ta có nút thứ 2, coi phần tử thứ danh sách, v.v tiếp tục hết danh sách Nút cuối có liên kết liên kết null, tức khơng trỏ tới nút nào, trỏ nút để tạo thành vịng • Các thao tác danh sách liên kết - Tạo, cấp phát, giải phóng nhớ cho nút listnode p; // Khai báo biến p p = (listnode)malloc(sizeof(struct node));//cấp phát nhớ cho p free(p); //giải phóng nhớ cấp phát cho nút p; h - Chèn nút vào đầu danh sách B1 Tạo cấp phát nhớ cho nút ,đc trỏ tới q B2 Sau gán giá trị thích hợp cho phần tử nút mới, cho trỏ tiếp nút trỏ đến phần tử nút B3 Để p trỏ đến đầu nút danh sách ,ta cần cho p trỏ đến nút tạo void Insert_Begin(listnode *p, int x){ listnode q; q = (listnode)malloc(sizeof(struct node)); q-> item = x; q-> next = *p; *p = q; } h - Chèn nút vào cuối danh sách B1 Dịch chuyển trỏ tới nút cuối danh sách Để làm việc này, ta phải khai báo biến trỏ r Ban đầu, biến này, với p, trỏ đến đầu danh sách Lần lượt dịch chuyển r theo nút đến cuối danh sách B2 Cho trỏ tiếp nút cuối (được trỏ tới r) trỏ đến nút tạo q, trỏ tiếp q trỏ tới null void Insert_End(listnode *p, int x){ listnode q, r; q = (listnode)malloc(sizeof(struct node)); q-> item = x; q->next = NULL; if (*p==NULL) *p = q; else{ r = *p; while (r->next != NULL) r = r->next; r->next = q; h } } - Chèn nút vào trước nút r danh sách B1 Cho trỏ tiếp nút trỏ đến nút nút r B2 Cho trỏ tiếp nút r trỏ đến q void Insert_Middle(listnode *p, int position, int x){ int count=1, found=0; listnode q, r; r = *p; while ((r != NULL)&&(found==0)){ if (count == position){ q = (listnode)malloc(sizeof(struct node)); q-> item = x; q-> next = r-> next; h r-> next = q; found = 1; } count ++; r = r-> next; } if (found==0) printf(“Khong tim thay vi tri can chen !”); } - Xóa nút đầu danh sách B1 Dùng trỏ tạm q trỏ đến đầu danh sách B2 Dịch chuyển trỏ p qua phần tử đến phần tử h B3 Ngắt liên kết biến tạm q với nút tiếp theo, giải phóng nhớ Cho q void Remove_Begin(listnode *p){ listnode q; if (*p == NULL) return; q = *p; *p = (*p)-> next; q-> next = NULL; free(q); } h - Xóa nút cuối danh sách B1 Dịch chuyển trỏ tới nút gần cuối danh sách Để làm việc này, ta phải dùng biến tạm q r Lần lượt dịch chuyển q r từ đầu danh sách tới cuối danh sách, q ln dịch chuyển sau r nút Khi r tới nút cuối q nút gần cuối B2 Cho trỏ tiếp nút gần cuối (đang trỏ q) trỏ tới null Giải phóng nhớ cho nút cuối (đang trỏ r) void Remove_End(listnode *p){ listnode q, r; if (*p == NULL) return; if ((*p)-> next == NULL){ Remove_Begin(*p); return; h } r = *p; while (r-> next != NULL){ q = r; r = r-> next; } q-> next = NULL; free(r); } - Xóa nút trước nút r danh sách B1 Sử dụng biến tạm q trỏ đến nút đứng trước nút r B2 Cho trỏ nút r trỏ tới nút đứng sau nút q h B3 Ngắt liên kết nút q giải phóng nhớ cho q void Remove_Middle(listnode *p, int position){ int count=1, found=0; listnode q, r; r = *p; while ((r != NULL)&&(found==0)){ if (count == position){ q = r-> next; r-> next = q-> next; q-> next = NULL; free (q); found = 1; } count ++; r = r-> next; h } return; } Để thêm phần tử vào cuối hàng đợi, điểm cuối tăng lên (nếu điểm cuối vị trí cuối mảng quay vịng điểm cuối 0) Trước thêm phần tử vào hàng đợi, cần kiếm tra xem hàng đợi đầy chưa (hàng đợi đầy giá trị biến count = MAX) - Lấy phần tử khỏi hàng đợi Để lấy phần tử khỏi hàng đợi, tiến hành lấy phần tử vị trí điểm đầu cho điểm đầu tăng lên (nếu điểm đầu vị trí cuối mảng quay vòng điểm đầu 0) Tuy nhiên, trước làm thao tác này, ta phải kiểm tra xem hàng đợi có rỗng hay khơng int Get(queue *q){ int x; if (QueueEmpty(*q)) printf("Hang doi rong !"); else{ x = q-> node[q-> head]; if (q->head == MAX-1 ) q->head=0; else (q->head)++; q-> count ; } h return x; } - Cài đặt hàng đợi danh sách liên kết Để cài đặt hàng đợi danh sách liên kết, ta sử dụng danh sách liên kết đơn trỏ head tail lưu giữ nút đầu nút cuối danh sách Việc bổ sung phần tử tiến hành cuối danh sách việc lấy phần tử tiến hành đầu danh sách Khai báo hàng đợi danh sách liên kết sau: struct node { int item; struct node *next; }; typedef struct node *queuenode; typedef struct { queuenode head; queuenode tail; }queue; Khai báo tương tự ngăn xếp, nhiên, hàng đợi sử dụng biến hea tail để lưu giữ điểm đầu điểm cuối hàng Khi đó, thao tác hàng đợi cài đặt sau: h -Thao tác khởi tạo hàng đợi Thao tác thực việc gán giá trị null cho nút đầu cuối hàng đợi, cho biết hàng đợi trạng thái rỗng void QueueInitialize(queue *q){ q-> head = q-> tail = NULL; return; } Thao tác kiểm tra hàng đợi rỗng Hàng đợi rỗng nút đầu trỏ đến NULL int QueueEmpty(queue q){ return (q.head == NULL); } Thao tác thêm phần tử vào hàng đợi void Put(queue *q, int x){ queuenode p; p = (queuenode) malloc (sizeof(struct node)); p-> item = x; p-> next = NULL; q-> tail-> next = p; q-> tail = q-> tail-> next; if (q-> head == NULL) q-> head = q-> tail; return; h } Để thêm phần tử vào cuối hàng đợi, tạo cấp phát nhớ cho nút Gán giá trị thích hợp cho nút này, sau cho trỏ tiếp nút cuối hàng đợi trỏ đến Nút trở thành nút cuối hàng đợi Nếu hàng đợi chưa có phần tử nút đầu hàng đợi - Lấy phần tử khỏi hàng đợi Để lấy phần tử khỏi hàng đợi, tiến hành lấy phần tử vị trí nút đầu cho nút đầu chuyển nút Tuy nhiên, trước làm thao tác này, ta phải kiểm tra xem hàng đợi có rỗng hay khơng int Get(queue *q){ queuenode p; if (QueueEmpty(*q)){ printf("Ngan xep rong !"); return 0; }else{ p = q-> head; q-> head = q-> head-> next; return p->item; } } 1.3 Các thao tác ngăn xếp h - Thao tác khởi tạo ngăn xếp Thao tác thực việc gán giá trị -1 cho biến top, cho biết ngăn xếp trạng thái rỗng void StackInitialize(stack *s){ s-> top = -1; return; } - Thao tác kiểm tra ngăn xếp rỗng int StackEmpty(stack s){ return (s.top = = -1); } - Thao tác kiểm tra ngăn xếp đầy int StackFull(stack s){ return (s.top = = MAX-1); } - Thao tác bổ sung phần tử vào ngăn xếp void Push(stack *s, int x){ if (StackFull(*s)){ printf(“Ngan xep day !”); return; }else{ s-> top ++; s-> nut[s-> top] = x; return; h } } -Thao tác lấy phần tử khỏi ngăn xếp int Pop(stack *s){ if (StackEmpty(*s)){ printf(“Ngan xep rong !”); }else{ return s-> nut[s-> top ]; } } - Thao tác khởi tạo ngăn xếp Thao tác thực việc gán giá trị null cho nút đầu ngăn xếp, cho biết ngăn xếp trạng thái rỗng void StackInitialize(stack *s){ s-> top = NULL; return; } - Thao tác kiểm tra ngăn xếp rỗng int StackEmpty(stack s){ return (s.top == NULL); } h -Thao tác bổ sung phần tử vào ngăn xếp void Push(stack *s, int x){ stacknode p; p = (stacknode) malloc (sizeof(struct node)); p-> item = x; p-> next = s->top; s->top = p; return; } - Thao tác lấy phần tử khỏi ngăn xếp int Pop(stack *s){ stacknode p; if (StackEmpty(*s)){ printf("Ngan xep rong !"); }else{ p = s-> top; s-> top = s-> top-> next; return p->item; } } h 1.4 Duyệt nhị phân - Duyệt thứ tự trước void PreOrder (treenode root ) { if (root !=NULL) { printf(“%d”, root.item); PreOrder(root.left); PreOrder(root.right); } } - Duyệt thứ tự void InOrder (treenode root ) { if (root !=NULL) { PreOrder(root.left); printf(“%d”, root.item); PreOrder(root.right); } } - Duyệt thứ tự sau void PostOrder (treenode root ) { if (root !=NULL) { h PreOrder(root.left); PreOrder(root.right); printf(“%d”, root.item); } } 1.5 Tìm kiếm chèn tìm kiếm nhị phân Tìm kiếm khóa Để tìm kiếm giá trị, có mảng xếp, thực tìm kiếm nhị phân Giả sử muốn tìm kiếm số mảng, làm tìm kiếm nhị phân trước tiên xác định danh sách đầy đủ làm khơng gian tìm kiếm chúng ta, số tồn khơng gian tìm kiếm Bây so sánh số lượng tìm kiếm phần tử tìm kiếm với phần tử khơng gian tìm kiếm trung vị ghi tìm kiếm hơn, chúng tơi tìm kiếm nửa bên trái, cịn lại chúng tơi tìm kiếm nửa bên phải, trường hợp nhau, chúng tơi tìm thấy phần tử Trong tìm kiếm nhị phân, chúng tơi bắt đầu với phần tử 'n' khơng gian tìm kiếm sau phần tử khơng phải phần tử mà chúng tơi tìm kiếm, chúng tơi giảm khơng gian tìm kiếm thành 'n / 2'và chúng tơi tiếp tục giảm khơng gian tìm kiếm chúng tơi tìm thấy ghi mà chúng tơi tìm kiếm chúng tơi nhận phần tử khơng gian tìm kiếm thực với toàn việc giảm bớt Thao tác tìm kiếm tìm kiếm nhị phân giống Giả sử muốn tìm kiếm số, h làm gốc sau so sánh giá trị tìm kiếm với giá trị gốc nhau, hồn thành việc tìm kiếm biết cần phải chuyển đến bên trái tìm kiếm nhị phân, tất phần tử bên trái nhỏ tất phần tử bên phải lớn Tìm kiếm phần tử tìm kiếm nhị phân q trình này, bước, theo hướng sang trái phải bước, loại bỏ Nếu cân bằng, gọi cân tất nút, khác biệt chiều cao bên trái bên phải không lớn một, bắt đầu với khơng gian tìm kiếm làcác nút 'n' loại bỏ con, loại bỏ nút 'n / 2' để khơng gian tìm kiếm giảm xuống 'n / 2' sau bước tiếp theo, giảm khơng gian tìm kiếm xuống 'n / 4' tiếp tục giảm chúng tơi tìm thấy phần tử khơng gian tìm kiếm chúng tơi giảm xuống cịn nút Tìm kiếm tìm kiếm nhị phân lý có tên tìm kiếm nhị phân • Chèn nút vào BST Cho BST, thao tác chèn phải có kết BST • Làm biết vị trí đặt nút 'D'? h • Điểm then chốt: Cho BST giá trị cần chèn, có vị trí cho giá trị BST • Sử dụng BSTT(root, 'D') để xác định vị trí trống chèn 'D' • Chèn nút 'D Xác định vị trí chèn h Sử dụng BSTT(root, 'D') để xác định vị trí trống chèn 'D' Chèn nút • Sử dụng BSTT(root, 'D') để xác định vị trí trống chèn 'D' • Chèn nút 'D' 1.6 Giải thuật xếp h - Sắp xếp chọn Đây giải thuật xếp đơn giản Ý tưởng giải thuật sau: Lựa chọn phần tử có giá trị nhỏ nhất, đổi chỗ cho phần tử Tiếp theo, lựa chọn phần tử có giá trị nhỏ thứ nhì, đổi chỗ cho phần tử thứ Quá trình tiếp tục toàn dãy h Như vậy, toàn dãy Giải thuật gọi xếp chọn bước, phần tử chọn đổi chỗ cho phần tử vị trí cần thiết dãy Thủ tục thực xếp chọn C sau: void selection_sort(){ int i, j, k, temp; for (i = 0; i< N; i++){ k = i; for (j = i+1; j < N; j++){ if (a[j] < a[k]) k = j; } temp = a[i]; a[i] =a [k]; a[k] = temp; } h } Trong thủ tục trên, vòng lặp duyệt từ đầu đến cuối dãy Tại vị trí i, tiến hành duyệt tiếp từ i tới cuối dãy để chọn phần tử nhỏ thứ i đổi chỗ cho phần tử vị trí i Thời gian thực thuật toán tỷ lệ với N2 , vịng lặp ngồi (biến chạy i) duyệt qua N phần tử, vịng lặp duyệt trung bình N/2 phần tử Do đó, độ phức tạp trung bình thuật toán O(N * N/2) = O(N2 /2) = O(N2 ) h

Ngày đăng: 04/04/2023, 09:11

Xem thêm:

w