4/28/2010 1 Chương 7. Bài 3. Queue ĐỖ BÁ LÂM ViỆN CNTT&TT, TRƯỜNG ĐHBK HÀ NỘI Nội dung 1. Khái niệm queue 2. Xây dựng queue 2.1. Sử dụng mảng 2.2. Sử dụng danh sách liên kết 2 1. Khái niệm queue Queue (Hàng đợi) Là một hàng chờ đợi, xếp hàng (waiting line) Là một cấu trúc dữ liệu trong đó cho phép sử dụng cả 2 phía: một phía để thêm và một phía để lấy ra phần tử 3 4/28/2010 2 lối sau lối trước 1. Khái niệm Queue Dữ liệu được thêm vào ở lối sau (rear), và lấy ra ở lối trước (front) Cấu trúc FIFO (First In First Out) – Vào trước ra trước Thao tác enqueue(Element e) Element dequeue() Các thao tác cơ bản của Queue enQueue: Thêm một phần tử vào Queue Queue Enqueue D Data A B front rear A B D front rear Queue Các thao tác cơ bản của Queue deQueue: Lấy một phần tử khỏi Queue Queue Dequeue A Data B D front rear A B D front rear Queue 4/28/2010 3 Ứng dụng của Queue Hàng đợi trong các phòng bán vé Truy nhập vào các thiết bị dùng chung tại văn phòng (ví dụ máy in) 7 Ghi nhớ Queue được hình dung như một hàng đợi bao gồm nhiều nhiều người xếp hàng với 2 thao tác đưa vào và đẩy ra theo nguyên tắc: Người nào vào trước sẽ được ra trước – FIFO (First In First Out) 2. Xây dựng Queue Lưu trữ được các đối tượng dữ liệu Xây dựng 2 thao tác Push và Pop theo nguyên tắc FIFO Có hai cách cài đặt queue Sử dụng mảng Sử dụng danh sách liên kết 4/28/2010 4 2.1. Sử dụng mảng Biễu diễn Queue dưới dạng mảng Q Lưu trữ chỉ số phần tử lối trước và lối sau của Queue qua biến F và R Khởi tạo F=R=-1 Queue rỗng (empty) F = R = -1 Queue đầy (full) R=MAX-1 0 1 2 MAX-1 F (Front) R (Rear) 2.1. Sử dụng mảng Để thuận tiện định nghĩa cấu trúc Queue gồm mảng và 2 biến Front, Rear #define MAX 100 typedef ElementType; typedef struct { ElementType Elements[MaxLength]; //Lưu trữ các chỉ số int Front, Rear; } Queue; Queue Q; 11 2.1. Sử dụng mảng Khởi tạo Queue Front = -1 Rear = -1 Khi bổ sung thêm một phần tử vào Queue Nếu Front=-1 thì gán Front=0 Rear tăng lên 1. Khi lấy ra một phần tử trong Queue Nếu Front==Rear thì gán Front = Rear = -1 Ngược lại Front tăng lên 1 12 4/28/2010 5 Enqueue int EnQueue(ElementType N){ if(Q.Rear==MAX-1) return 0; else{ if(Q.Front==-1) Q.Front=0; Q.Rear=Q.Rear+1; Q.Elements[Q.Rear]=X; return 1; } } 13 Dequeue int DeQueue(ElementType *N){ if(Q.Front == -1) return 0; else{ *N = Q.Element[Q.Front]; if (Q.Front == Q.Rear){ Q.Front = -1; Q.Rear = -1; }else Q.Front=Q.Front+1; return 1; //Dequeue thanh cong } } 2.1. Sử dụng mảng Nhược điểm của cách tổ chức lưu trữ này Hiện tượng ĐẦY (Full) vẫn xảy ra dù mảng Q vẫn còn chỗ nhưng R = MAX-1 15 0 1 2 MAX-1 F (Front) R (Rear) 4/28/2010 6 EMPTY QUEUE [1] [2] [1] [2] [0] [3] [0] [3] [5] [4] [5] [4] front = -1 front = 0 rear = -1 rear = 2 J2 J1 J3 Cải tiến [1] [2] [1] [2] [0] [3][0] [3] [5] [4] [5] [4] J2 J3 J1 J4 J5 J6 J5 J7 J8 J9 Cải tiến Thêm vào theo chiều kim đồng hồ front =0 rear = 4 front =4 rear = 2 2.2. Sử dụng danh sách liên kết Biểu diễn Front trỏ tới đầu danh sách Rear: trỏ tới cuối danh sách Queue là cấu trúc FIFO (First In First Out) Thao tác Push, Pop? 18 Rear Front 4/28/2010 7 2.2. Sử dụng danh sách liên kết Push Thêm một nút vào sau nút cuối cùng trong danh sách Pop Lấy giá trị nút đầu tiên trong danh sách Loại bỏ nút này khỏi danh sách 19 2.2. Sử dụng danh sách liên kết struct node { ElemType data; struct node *next; }; struct node *Front, *Rear; //Front, Rear được khai báo là hai biến toàn cục 7 1 8 \ Front Rear void enQueue(ElemType N){ struct node *Temp; Temp=(struct node *) malloc(sizeof(struct node)); Temp->data = N; Temp->next = NULL; if(Front==NULL){ Front = Temp; Rear = Temp; }else{ Rear->next = Temp; Rear = Rear->next; }} enQueue 7 1 8 \ Front 45 Temp Rear 4/28/2010 8 void enQueue(ElemType N){ struct node *Temp; Temp=(struct node *) malloc(sizeof(struct node)); Temp->data = N; Temp->next = NULL; if(Front==NULL){ Front = Temp; Rear = Temp; }else{ Rear->next = Temp; Rear = Rear->next; }} enQueue 7 1 8 Front 45 Temp Rear void enQueue(ElemType N){ struct node *Temp; Temp=(struct node *) malloc(sizeof(struct node)); Temp->data = N; Temp->next = NULL; if(Front==NULL){ Front = Temp; Rear = Temp; }else{ Rear->next = Temp; Rear = Rear->next; }} enQueue 7 1 8 Front 45 Temp Rear int deQueue(ElementType *N){ struct node *Temp=Front; if(Front==NULL) return 0; else{ *N = Front->data; if(Front==Rear){ Front = NULL;Rear = NULL; }else Front = Front->next; free(Temp); return 1; } } deQueue 7 1 8 Front 45 Rear Temp 4/28/2010 9 int deQueue(ElementType *N){ struct node *Temp=Front; if(Front==NULL) return 0; else{ *N = Front->data; if(Front==Rear){ Front = NULL;Rear = NULL; }else Front = Front->next; free(Temp); return 1; } } deQueue 7 1 8 Front 45 Rear Temp int deQueue(ElementType *N){ struct node *Temp=Front; if(Front==NULL) return 0; else{ *N = Front->data; if(Front==Rear){ Front = NULL;Rear = NULL; }else Front = Front->next; free(Temp); return 1; } } deQueue 1 8 Front 45 Rear Temp Bài tập Demo dQueue.c Bài 1. Kiểm tra tính đối xứng của một xâu Dùng stack: lưu các kí tự của xâu Dùng Queue: lưu các kí tự của xâu Lấy lần lượt khỏi stack và queue các phần tử và so sánh 27 4/28/2010 10 Bài tập Ví dụ Đầu vào : MADAM Bước 1: Đọc xâu từ trái sang phải, lưu vào trong Stack và Queue Bước 2: Lấy lần lượt các ký tự ra khỏi Stack và Queue M A D A M M A D A M Stack Queue top front M A D A A D A M Stack Queue top front M = M M A D D A M Stack Queue top front A= A Bài tập Bài 2. Kiểm tra cặp ngoặc Mỗi dấu “(”, “{”, or “[” đều phải có một dấu đóng tương ứng “)”, “}”, or “[” Đúng: ( )(( )){([( )])} Sai: )(( )) Sai: ({[ ])} Viết giải thuật nhận một xâu đầu vào gồm các ký tự mở , đóng ngoặc. Kiểm tra xâu có hợp lệ không 29 Thảo luận 30 . e) Element dequeue() C c thao t c cơ bản c a Queue enQueue: Thêm một phần tử vào Queue Queue Enqueue D Data A B front rear A B D front rear Queue C c thao t c cơ bản c a Queue deQueue: Lấy một. Front->next; free(Temp); return 1; } } deQueue 1 8 Front 45 Rear Temp Bài tập Demo dQueue .c Bài 1. Kiểm tra tính đối xứng c a một xâu Dùng stack: lưu c c kí tự c a xâu Dùng Queue: lưu c c. lượt c c ký tự ra khỏi Stack và Queue M A D A M M A D A M Stack Queue top front M A D A A D A M Stack Queue top front M = M M A D D A M Stack Queue top front A= A Bài tập Bài 2. Kiểm tra c p