430 likes | 839 Views
Cấu Trúc Dữ Liệu & Giải Thuật. Stack and Queue. GV : Phạm Ngọc Nam Khoa : CNTT Email: tgtnam3012@gmail.com. Stack (Ngăn xếp). Queue (Hàng Đợi). Giới thiệu. Một số hình ảnh thông dụng. Một chồng Sách Vở ở trên bàn Một chồng Đĩa Nhận xét gì từ các ví dụ trên ?.
E N D
Cấu Trúc Dữ Liệu & Giải Thuật Stack and Queue GV : PhạmNgọc Nam Khoa : CNTT Email: tgtnam3012@gmail.com
Giớithiệu Mộtsốhìnhảnhthôngdụng • MộtchồngSáchVở ở trênbàn • MộtchồngĐĩa • Nhậnxétgìtừcácvídụtrên?
Giớithiệu Địnhnghĩa: • Ngăn xếp là cấu trúc chứa các đối tượng làm việc theo cơ chế “ vào sau ra trước” (Last in First out). • đối tượng có thể được thêm vào bất kỳ lúc nào, nhưng chỉ có đối tượng vào sau cùng mới được phép lây ra khỏi ngăn xếp.
Cácthaotáctrênngănxếp • Lưu trữ Ngăn Xếp. • khởi tạo Stack rỗng • Kiểm tra Ngăn Xếp rỗng. • Thêm một phần tử vào Ngăn Xếp. • Lấy một phần tử ra khỏi Ngăn Xếp. • Lấy thông tin của phần tử đầu Ngăn Xếp.
Lưutrữ Stack bằng DSLK • Thêm vào đầu danh sách(AddHead): • phần tử mới thêm nằm ở đầu danh sách • Truy xuất danh sách: Truy xuất phần tử nằm ở đầu trước. • => Thích hợp với tính chất của Ngăn Xếp.
Lưutrữ Stack bằng DSLK • Càiđặt • khaibáocấutrúc 1 phầntửtrong Stack • structNodeStack{ • dataType data; • NodeStack *pNext; • }; • khaibáocấutrúc Stack • struct Stack{ • int count; • NodeStack *pHead; • };
Khởitạo Stack • Cài đặt: • void InitStack(Stack &s) • { • s.count = 0; • s.pHead==NULL) • }
Kiểmtra Stack Rỗng • Ngăn xếp rỗng khi không chứa phần tử nào. • Cài đặt: • bool IsEmpty(const Stack s) • { • if(s.pHead==NULL) • return true; • return false; • }
Kiểmtra Stack đầy • Ngăn xếp đầy khi không thể cấp phát thêm vùng nhớ. • Khi thêm 1 phần tử vào Ngăn Xếp, nếu không cấp phát được vùng nhớ => Thông báo ngăn xếp đầy. bool IsFull(const Stack &s) { NodeStack *pNew=new NodeStack; if(pNew == NULL)// nếu ko tạo đc stack đầy return true; return false;// stack ko đầy }
Thêmmộtphầntử • Giải Thuật: • Tương tự thao tác thêm đầu(AddHead). • Nếu không thêm được(do không cấp phát được vùng nhớ) trả về giá trị cho biết ngăn xếp đầy. • Cài đặt:
Thêmmộtphầntử • Cài đặt: • int Push(Stack &s, int x) • { • NodeStack *pNew = new NodeStack; • if(pNew == NULL) • return 0;// ko cấp phát được • vùng nhớ, stack đầy • pNew -> data = x; • pNew -> pNext = NULL; • if(s.pHead == NULL){ • s.pHead = pNew; • return 1; • } • else{ • pNew -> pNext = s.pHead; • s.pHead = pNew; • return 1; • } • }
Thêmmộtphầntử • Cài đặt cách khác • int Push(Stack &s, int x) • { • if(IsFull(s)) • return 0;// stack đầy ko thêm đc • NodeStack *pNew = new NodeStack; • pNew -> data = x; • pNew -> pNext = s.pHead; • s.pHead = pNew; • s.count ++; • return 1; // thêm thành công • }
Lấymộtphầntửrakhỏingănxếp • Lấy đối tượng ở đầu Ngăn Xếp ra khỏi Ngăn Xếp và trả về giá trị của đối tượng đó. • Nếu Stack rỗng báo lỗi. • Thuật toán: • kiểm tra Ngăn Xếp rỗng hay không • Nếu không: • Ghi nhận giá trị của phần tử ở đầu Ngăn Xếp. • Xóa phần tử đầu ra khỏi Ngăn Xếp. • Trả về giá trị đã ghi nhận.
Lấymộtphầntửrakhỏingănxếp • Cài đặt • DataType * Pop(Stack &s) • { • // Kiểm tra Ngăn Xếp rỗng • if(……………….) • return 0; • // Ghi nhận giá trị đầu Ngăn Xếp • datatype x= l.pHead->data; • // Xóa đầu Ngăn Xếp • / / Trả về giá trị đã ghi nhân • return …; • }
Lấymộtphầntửrakhỏingănxếp • Cài đặt • int Pop(Stack &s) • { • if(s.pHead = = NULL) • return 0; // stack rỗng không lấy ra được • NodeStack * pNew = s.pHead; • s.pHead = pNew ->pNext; • delete pNew ; • s.count --; • return 1; // xóa thành công • }
Lấymộtphầntửrakhỏingănxếp • Cài đặt • int Pop(Stack &s, int &outdata) • { • if(IsEmpty(s)) • return 0; // stack rỗng không lấy ra được • NodeStack * pNew = s.pHead; • outdata = pNew -> data; • s.pHead = pNew ->pNext; • delete pNew ; • s.count --; • return 1; // lấy ra thành công • }
Cácứngdựngcủa Stack • Lưu vết trong các giải thuật “back-tracking” • Bài toán “N quân hậu”
Giớithiệu • Queue làcấutrúcchứacácđốitượnglàmviệctheo qui tắc “ Vàosauratrước(FIFO)”. • Các đối tượng có thể được thêm vào hàng • đợi bất kì lúc nào nhưng chỉ có đối tượng thêm vào đầu tiên mới được lấy ra khỏi hàng đợi. • Việc thêm vào diễn ra ở cuối, việc lấy ra diễn • ra ở đầu.
Cácthaotáctrên Queue • Lưu trữ Queue. • kiểm tra Queue rỗng • Thêm một phần tử vào cuối Queue. • Lấy một phần tử ở đầu ra khỏi Queue. • Lấy thông tin của đối tượng ỏ đầu Queue.
Lưutrữ Queue bằng DSLK • Khai báo hàng đợi như một DSLK với phần tử đầu (pHead) và đuôi (pTail). • Phần tử đầu: nơi lấy dữ liệu hàng đợi ra. • Phần tử đuôi: nơi thêm phần tử vào
KiểmtraQueue rỗng • Hàng đợi rỗng khi không có phần tử nào • (DS rỗng) • Cài đặt • bool IsEmpty(NodeQueue *q) • { • if(q->pHead = = NULL) • return true; • return false; • }
KiểmtraQueue đầy • Hàng đợi đầy khi không thể cấp phát thêm • vùng nhớ. • Khi thêm 1 phần tử vào hàng đợi, nếu không cấp phát được vùng nhớ -> Thông báo hàng đợi đầy • Cài đặt • bool IsFull(…) • { • if(…) • … • }
Thêmphầntửvàocuối Queue • Giải thuật: • Tương tự thao tác thêm cuối. • Nếu không thêm được (do không cấp phát • được vùng nhớ) trả về giá trị cho biết hàng đợi đầy • Càiđặt: • intEnQueue (NODE *&pHead, NODE *&pTail, Data x) • { • //tạo 1 nút mới • if(<không tạo được>) • return 0; • //thêm nút mới vào đuôi • return 1; • }
Lấyphầntửđầurakhỏi Queue • Giải thuật: • Ghi nhận giá trị của phần tử ở đầu hàng đợi. • Xóa phần tử đầu ra khỏi hàng đợi. • Trả về giá trị đã ghi nhận. • Càiđặt: • Data DeQueue(NODE*& pHead, NODE*& pTail) • { • //kiểm tra Queue rỗng? • if(…) • return …; • ////ghi nhận giá trị đầu Queue • Data x = pHead -> data; • //xóa đầu Queue… • //trả về giá trị đã ghi nhận • return _______; • }
Lấyphầntửđầu Queue • Giải thuật: • Chỉ lấy thông tin của đối tượng đầu hàng đợi mà không hủy đối tượng khỏi hàng đợi. • Càiđặt: • Kiểm tra hàng đợi rỗng? • Trả về giá trị của phần tử đầu hàng đợi. • Data DeQueue(NODE*& pHead) • { • …. • }
CácứngdựngcủaQueue • Sử dụng giải 1 số bài toán lý thuyết đồ thị. • …