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

bài tập lớn kết thúc học phần môn cấu trúc dữ liệu và thuật toán

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

Thông tin cơ bản

Tiêu đề Các thao tác trên danh sách liên kết
Tác giả Đỗ Minh Quân
Trường học Trường Đại Học Phenikaa
Chuyên ngành Cấu trúc dữ liệu và thuật toán
Thể loại Bài tập lớn kết thúc học phần
Định dạng
Số trang 43
Dung lượng 498,19 KB

Nội dung

1.1.Các thao tác trên danh sách liên kếtDanh sách liên kết là 1 cấu trúc dữ liệu có kiểu tuần tự, mỗi phần tử trong danh sách liên kết có chứa thông tin, qua đó ta có thể truy cập tới ph

Trang 1

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

Trang 2

1.1 Các thao tác trên danh sách liên kết

Danh sách liên kết là 1 cấu trúc dữ liệu có kiểu tuần tự, mỗi phần tử trong danh sách liên kết có chứa thông tin, qua đó ta có thể truy cập tới phần tử này

Danh sách liên kết có thể được xem như là 1 sự bố trí tuần tự các phần

tử trong 1 tập Bắt đầu từ 1 nút, ta coi đó là phần tử đầu tiên trong danh sách Từ nút này, theo liên kết mà nó trỏ tới, ta có nút thứ 2, được coi là phần tử thứ 2 trong danh sách, v.v cứ tiếp tục như vậy cho đến hết danh sách Nút cuối cùng có thể có liên kết là một liên kết null, tức là không trỏ tới nút nào, hoặc nó có thể trỏ về nút đầu tiên để tạo thành 1 vòng

• Các thao tác trên danh sách liên kết

- Tạo, cấp phát, và giải phóng bộ nhớ cho 1 nút

listnode p; // Khai báo biến p

p = (listnode)malloc(sizeof(struct node));//cấp phát bộ nhớ cho p

free(p); //giải phóng bộ nhớ đã cấp phát cho nút p;

Trang 3

- Chèn một nút vào đầu danh sách

B1 Tạo và cấp phát bộ nhớ cho một nút mới ,đc trỏ tới bởi q

B2 Sau khi gán các giá trị thích hợp cho phần tử của nút mới, cho con trỏ tiếp của nút mới trỏ đến phần tử đầu tiên của nút

B3 Để p trỏ đến đầu nút danh sách ,ta cần cho p trỏ đến nút mới tạo

void Insert_Begin(listnode *p, int x){

Trang 4

- Chèn một nút vào cuối danh sách

B1 Dịch chuyển con trỏ tới nút cuối của danh sách Để làm được việc này, ta phải khai báo một biến con trỏ mới r Ban đầu, biến này, cùng với

p, trỏ đến đầu danh sách Lần lượt dịch chuyển r theo các nút kế tiếp chotới khi đến cuối danh sách

B2 Cho con trỏ tiếp của nút cuối (được trỏ tới bởi r) trỏ đến nút mới tạo

là q, và con trỏ tiếp của q trỏ tới null

void Insert_End(listnode *p, int x){

Trang 5

}

}

- Chèn một nút vào trước nút r trong danh sách

B1 Cho con trỏ tiếp của nút mới trỏ đến nút kế tiếp của nút r

B2 Cho con trỏ tiếp của nút r trỏ đến q

void Insert_Middle(listnode *p, int position, int x){

int count=1, found=0;

Trang 6

- Xóa một nút ở đầu danh sách

B1 Dùng một con trỏ tạm q trỏ đến đầu danh sách

B2 Dịch chuyển con trỏ p qua phần tử đầu tiên đến phần tử kế tiếp

Trang 7

B3 Ngắt liên kết của biến tạm q với nút tiếp theo, giải phóng bộ nhớ Cho q.

Trang 8

- Xóa một nút ở cuối danh sách

B1 Dịch chuyển con trỏ tới nút gần cuối của danh sách Để làm được việc này, ta phải dùng 2 biến tạm là q và r Lần lượt dịch chuyển q và r

từ đầu danh sách tới cuối danh sách, trong đó q luôn dịch chuyển sau r một nút Khi r tới nút cuối cùng thì q là nút gần cuối cùng nhất

B2 Cho con trỏ tiếp của nút gần cuối cùng nhất (đang được trỏ bởi q) trỏtới null Giải phóng bộ nhớ cho nút cuối cùng (đang được trỏ bởi r)

Trang 10

B3 Ngắt liên kết của nút q và giải phóng bộ nhớ cho q

void Remove_Middle(listnode *p, int position){ int count=1, found=0;

Trang 11

}

if (found==0)

printf(“Khong tim thay vi tri can xoa !”);

}

- Duyệt toàn bộ danh sách

Thao tác duyệt danh sách cho phép duyệt qua toàn bộ các phần tử của danh sách, từ phần tử đầu tiền cho tới phần tử cuối cùng

Để thực hiện thao tác này, ta cần một biến tạm r trỏ tới đầu danh sách

Từ vị trí này, theo liên kết của các nút, thực hiện duyệt qua từng phần tử trong danh sách Trong quá trình duyệt, tại mỗi nút ta có thể thực hiện các thao tác cần thiết như lấy thông tin phần tử, sửa thông tin, so sánh, v.v

r = p;

while (r-> next != null){

//thực hiện các thao tác cần thiết

r = r-> next;

Trang 13

struct node *head = NULL;

struct node *current = NULL;

//hien thi danh sach

Trang 14

//chen link tai vi tri dau tien

void insertFirst(int key, int data)

{

//tao mot link

struct node *link = (struct node*) malloc(sizeof(struct node));

Trang 15

//xoa phan tu dau tien

struct node* deleteFirst()

{

//luu tham chieu toi first link

struct node *tempLink = head;

//danh dau next toi first link la first

Trang 16

struct node *current;

for(current = head; current != NULL; current = current->next)

Trang 17

//tim mot link voi key da cho

struct node* find(int key){

//bat dau tim tu first link

struct node* current = head;

//neu list la trong

Trang 18

//xoa mot link voi key da cho

struct node* deleteKey(int key){

//bat dau tu first link

struct node* current = head;

struct node* previous = NULL;

Trang 19

//neu list la trong

Trang 21

void sort(){

int i, j, k, tempKey, tempData ;

struct node *current;

struct node *next;

int size = length();

Trang 22

// ham dao nguoc list

void reverse(struct node** head_ref) {

struct node* prev = NULL;

struct node* current = *head_ref;

Trang 23

struct node* next;

while (current != NULL) {

Trang 24

insertFirst(4,1);

insertFirst(5,40);

insertFirst(6,56);

printf("Danh sach ban dau: ");

//in danh sach

printList();

while(!isEmpty()){

struct node *temp = deleteFirst();

printf("\nGia tri bi xoa:");

printf("(%d,%d) ",temp->key,temp->data); }

printf("\nDanh sach sau khi da xoa gia tri: "); printList();

Trang 25

}else {

Trang 26

printf("Khong tim thay phan tu.");

}else {

printf("Khong tim thay phan tu.");

}

Trang 27

1.2 Các thao tác trên hàng đợi

- Thao tác khởi tạo hàng đợi

Thao tác này thực hiện việc gán giá trị 0 cho biến head, giá trị MAX -1 cho biến tail, và giá

trị 0 cho biến count, cho biết hàng đợi đang ở trạng thái rỗng

void QueueInitialize(queue *q){

Trang 28

- Thao tác kiểm tra hàng đợi rỗng

Hàng đợi rỗng nếu có số phần tử nhỏ hơn hoặc bằng 0 int QueueEmpty(queue q){

return (q.count <= 0);

}

- Thao tác thêm 1 phần tử vào hàng đợi

void Put(queue *q, int x){

Trang 29

}

return;

}

Để thêm phần tử vào cuối hàng đợi, điểm cuối tăng lên 1 (nếu điểm cuối

đã ở vị trí cuối mảng thì quay vòng điểm cuối về 0) Trước khi 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 khi giá trị biến count = MAX)

- Lấy phần tử ra khỏi hàng đợi

Để lấy phần tử ra khỏi hàng đợi, tiến hành lấy phần tử tại vị trí điểm đầu

và cho điểm đầu tăng lên 1 (nếu điểm đầu đã ở vị trí cuối mảng thì quay vòng điểm đầu về 0) Tuy nhiên, trước khi làm các thao tác này, ta phải kiểm tra xem hàng đợi có rỗng hay không

Trang 30

return x;

}

- Cài đặt hàng đợi bằng danh sách liên kết

Để cài đặt hàng đợi bằng danh sách liên kết, ta cũng sử dụng 1 danh sách liên kết đơn và 2 con trỏ head và tail lưu giữ nút đầu và nút cuối của danh sách Việc bổ sung phần tử mới sẽ được tiến hành ở cuối danh sách và việc lấy phần tử ra sẽ được tiến hành ở đầu danh sách

Khai báo 1 hàng đợi bằng danh sách liên kết như sau:

Trang 31

-Thao tác khởi tạo hàng đợi

Thao tác này thực hiện việc gán giá trị null cho nút đầu và cuối của hàngđợi, cho biết hàng

đợi đang ở 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ếu nút đầu trỏ đến NULL

int QueueEmpty(queue q){

return (q.head == NULL);

}

Thao tác thêm 1 phần tử vào hàng đợi

void Put(queue *q, int x){

q-> tail = q-> tail-> next;

if (q-> head == NULL) q-> head = q-> tail;

return;

Trang 32

Để thêm phần tử vào cuối hàng đợi, tạo và cấp phát bộ nhớ cho 1 nút mới Gán giá trị thích hợp cho nút này, sau đó cho con trỏ tiếp của nút cuối hàng đợi trỏ đến nó Nút này bây giờ trở thành nút cuối của hàng đợi Nếu hàng đợi chưa có phần tử nào thì nó cũng chính là nút đầu của hàng đợi

- Lấy phần tử ra khỏi hàng đợi

Để lấy phần tử ra khỏi hàng đợi, tiến hành lấy phần tử tại vị trí nút đầu

và cho nút đầu chuyển về nút kế tiếp Tuy nhiên, trước khi làm các thao tác này, ta phải kiểm tra xem hàng đợi có rỗng hay không

Trang 33

- Thao tác khởi tạo ngăn xếp

Thao tác này thực hiện việc gán giá trị -1 cho biến top, cho biết ngăn xếpđang ở trạng thái rỗng

- Thao tác bổ sung 1 phần tử vào ngăn xếp

void Push(stack *s, int x){

Trang 34

- Thao tác khởi tạo ngăn xếp

Thao tác này thực hiện việc gán giá trị null cho nút đầu ngăn xếp, cho biết ngăn xếp đang ở trạng thái rỗng

Trang 35

-Thao tác bổ sung 1 phần tử vào ngăn xếp

void Push(stack *s, int x){

Trang 36

1.4 Duyệt cây nhị phân

Trang 37

đủ làm không gian tìm kiếm của chúng ta, số chỉ có thể tồn tại trong không gian tìm kiếm Bây giờ chúng ta so sánh số lượng được tìm kiếm hoặc phần tử được tìm kiếm với phần tử ở giữa củakhông gian tìm kiếm hoặc trung vị và nếu bản ghi đang được tìm kiếm ít hơn, chúng tôi sẽ tìm kiếm ở nửa bên trái, còn lại chúng tôi sẽ tìm kiếm ở nửa bên phải, trong trường hợp bằng 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' trong không gian tìm kiếm và sau đó nếu

phần tử ở giữa không phải là phần tử mà chúng tôi đang 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 cho đến khi chúng tôi tìm thấy bản ghi mà chúng tôi đang tìm kiếm hoặc chúng tôi chỉ nhận được một phần tử trong không gian tìm kiếm và được thực hiện với toàn bộ việc giảm bớt này

Thao tác tìm kiếm trong cây tìm kiếm nhị phân sẽ rất giống

Trang 38

sẽ làm là chúng ta sẽ bắt đầu từ gốc và sau đó chúng ta sẽ so sánh giá trị được tìm kiếm với giá trị của gốc nếu nó bằng nhau, chúng

ta đã hoàn thành việc tìm kiếm nếu nó ít hơn chúng ta biết rằng chúng ta cần phải chuyển đến cây con bên trái vì trong cây tìm kiếm nhị phân, tất cả các phần tử trong cây con bên trái nhỏ hơn

và tất cả các phần tử trong cây con bên phải lớn hơn Tìm kiếm một phần tử trong cây tìm kiếm nhị phân về cơ bản là quá trình này, trong đó ở mỗi bước, chúng ta sẽ đi theo hướng sang trái hoặc phải và do đó ở mỗi bước, chúng ta loại bỏ một trong các cây con Nếu cây cân bằng, chúng ta gọi là cây cân bằng nếu đối với tất cả các nút, sự khác biệt giữa chiều cao của cây con bên trái

và bên phải không lớn hơn một, chúng ta sẽ bắt đầu với không

gian tìm kiếm làcác nút 'n' và khi chúng ta loại bỏ một trong các cây con, chúng ta sẽ loại bỏ các nút 'n / 2' để không gian tìm kiếm của chúng ta sẽ giảm xuống còn 'n / 2' và sau đó trong bước tiếp theo, chúng ta sẽ giảm không gian tìm kiếm xuống 'n / 4' và

chúng tôi sẽ tiếp tục giảm như vậy cho đến khi chúng tôi tìm thấy phần tử hoặc cho đến khi không gian tìm kiếm của chúng tôi giảmxuống chỉ còn một nút Tìm kiếm ở đây cũng là tìm kiếm nhị phân

và đó là lý do tại sao có tên là cây tìm kiếm nhị phân

• Chèn một nút vào BST

Cho BST, thao tác chèn phải có kết quả là BST

• Làm sao biết vị trí đặt nút 'D'?

Trang 41

- Sắp xếp chọn

Đây là một trong những giải thuật sắp xếp đơn giản nhất Ý tưởng của giải thuật như sau: Lựa chọn phần tử có giá trị nhỏ nhất, đổi chỗ cho phần tử đầu tiên Tiếp theo, lựa chọn phần tử có giá trị nhỏ thứ nhì, đổi chỗ cho phần tử thứ 2 Quá trình tiếp tục cho tới khi toàn bộ dãy được sắp

Trang 42

Như vậy, toàn bộ dãy đã được sắp

Giải thuật được gọi là sắp xếp chọn vì tại mỗi bước, một phần tử được chọn và đổi chỗ cho phần tử ở vị trí cần thiết trong dãy

Thủ tục thực hiện sắp xếp chọn trong C như sau:

Trang 43

Trong thủ tục trên, vòng lặp đầu tiên duyệt từ đầu đến cuối dãy Tại mỗi

vị trí i, tiến hành duyệt tiếp từ i tới cuối dãy để chọn ra phần tử nhỏ thứ i

và đổi chỗ cho phần tử ở vị trí i Thời gian thực hiện thuật toán tỷ lệ với N2 , vì vòng lặp ngoài (biến chạy i) duyệt qua N phần tử, và vòng lặp trong duyệt trung bình N/2 phần tử Do đó, độ phức tạp trung bình của thuật toán là O(N * N/2) = O(N2 /2) = O(N2 )

Ngày đăng: 25/07/2024, 16:09

w