Kiểu phần tử Trong các ứng dụng khác nhau, Stack chứa các phần tử có kiểu khác nhau int, float, … Sử dụng Stack_entry làm kiểu phần tử Người dùng có thể lựa chọn kiểu phần tử: typed
Trang 1Kỹ thuật lập trình
Chương 3 – Một số cấu trúc dữ
liệu cơ bản
Nội dung
1. Stack
1. Định nghĩa
2. Cài đặt
2. Queue
1. Định nghĩa
2. Cài đặt
3. Case study: Mô phỏng sân bay
3. Stack và Queue kết nối
4. List
3.1 Stack
Định nghĩa Stack
Stack: là danh sách mà xóa và thêm phần tử bắt buộc phải cùng được thực hiện tại một đầu duy nhất (đỉnh)
5 3 2
7
2
5 3
Push
7
Pop
Pop top
5 3 2
7 top
5 2 3
top
top
STL: Standard Template Library
Là một phần của thư viện chuẩn của C++
Cung cấp các cài đặt thuận tiện cho hầu hết các cấu trúc dữ liệu phổ biến.
Trang 2Thư viện cấu trúc dữ liệu và thuật
toán
LEDA: Library Efficient Data structure
Algorithm
Cài đặt stack
Xây dựng class Stack, gồm các thao tác:
empty()
top()
push()
pop()
Khởi tạo: thiết lập một stack rỗng
Hàm tạo
Tạo một stack rỗng
Stack :: Stack( );
precondition: None.
postcondition: The Stack exists and is initialized
to be empty.
Kiểu phần tử
Trong các ứng dụng khác nhau, Stack chứa các phần tử có kiểu khác nhau
int, float, …
Sử dụng Stack_entry làm kiểu phần tử
Người dùng có thể lựa chọn kiểu phần tử:
typedef char Stack_entry;
Æcài đặt không bị thay đổi
Xử lý lỗi
Các thao tác không hợp pháp:
Rút phần tử từ Stack rỗng Æ underflow
Thêm phần tử vào stack đầy Æ overflow
Sử dụng kiểu liệt kê Error_code:
success
underflow
overflow
Thiết kế hàm thành viên
Error_code Stack :: pop( );
precondition: None.
postcondition: If the Stack is not empty, the top of the
Stack is removed If the Stack is empty,
an Error_code of underflow is returned and the Stack is left unchanged
Error_code Stack :: push(const Stack_entry &item);
precondition: None.
postcondition: If the Stack is not full, item is added to
the top of the Stack If the Stack is full, an Error_code of overflow is returned and the Stack is left unchanged
Trang 3Thiết kế hàm thành viên
Error_code Stack :: top(Stack_entry &item) const;
precondition: None.
postcondition: The top of a nonempty Stack is copied to
item A code of fail is returned if the Stack
is empty
bool Stack :: empty( ) const;
precondition: None.
postcondition: A result of true is returned if the Stack is
empty, otherwise false is returned.
Định nghĩa lớp Stack – Sử dụng mảng
const int maxstack = 10; // small value for testing
class Stack { public:
Stack( );
bool empty( ) const;
Error_code pop( );
Error_code top(Stack_entry &item) const;
Error_code push(const Stack_entry &item);
private:
int count;
Stack_entry entry[maxstack];
};
Cài đặt
Error_code Stack :: top(Stack_entry &item) const
/* Pre: None.
Post: If the Stack is not empty, the top of the Stack is
returned in item If the Stack is empty an
Error_code of underflow is returned */
{
Error_code outcome = success;
if (count == 0)
outcome = underflow;
else
item = entry[count − 1];
return outcome;
}
3.2 Queue
Định nghĩa Queue
Queue: là danh sách mà việc thêm phần tử
phải được thực hiện tại một đầu còn xóa
phần tử phải thực hiện tại đầu kia.
Thêm (Enqueue) Xóa
(Dequeue) Đầu Cuối
• Queue là một kiểu cấu trúc FIFO: First In First Out
Ví dụ của Queue trong thực tế
Trang 4Cài đặt Queue
Kiểu phần tử: Queue_entry
Các thao tác:
Queue :: Queue( );
postcondition: The Queue has been created and is
initialized to be empty
Error_code Queue :: append(const Queue_entry &x);
postcondition: If there is space, x is added to the Queue
as its rear Otherwise an Error_code of
overflow is returned
Các thao tác
Error_code Queue :: serve( );
postcondition: If the Queue is not empty, the front of the
Queue has been removed Otherwise an Error_code of underflow is returned
Error_code Queue :: retrieve(Queue_entry &x) const;
postcondition: If the Queue is not empty, the front of the
Queue has been recorded as x
Otherwise an Error_code of underflow is returned
bool Queue :: empty( ) const;
postcondition: Return true if the Queue is empty,
otherwise return false.
Định nghĩa lớp
class Queue {
public:
Queue( );
bool empty( ) const;
Error_code append(const Queue_entry &x);
Error_code serve( );
Error_code retrieve(Queue_entry &x) const;
// Additional members will represent queue data.
};
Cài đặt – sử dụng mảng vòng
const int maxqueue = 10; // small value for testing
class Queue {
public:
Queue( );
bool empty( ) const;
Error_code serve( );
Error_code append(const Queue_entry &item);
Error_code retrieve(Queue_entry &item) const;
private:
int count;
int front, rear;
Queue_entry entry[maxqueue];
};
Cài đặt
Một số thao tác cần thiết khác:
clear
full
size
serve_and_retrieve
Trang 5bool Queue :: full( ) const;
postcondition: Return true if the Queue is full; return
false otherwise.
void Queue :: clear( );
postcondition: All entries in the Queue have been
removed; it is now empty
int Queue :: size( ) const;
postcondition: Return the number of entries in the
Queue
Error_code Queue :: serve_and_retrieve(Queue_entry &item);
postcondition: Return underflow if the Queue is empty
Otherwise remove and copy the item at the
front of the Queue to item and return success
3.3 Stack và Queue kết nối
Khai báo kiểu nút
Sử dụng struct thay vì class:
struct Node {
// data members
Node_entry entry;
Node *next;
// constructors
Node( );
Node(Node_entry item, Node *add_on = NULL);
};
Hàm tạo Node
Node :: Node( )
{
next = NULL;
}
Node :: Node(Node_entry item, Node *add_on)
{
entry = item;
next = add_on;
}
Cài đặt Stack kết nối
Sự bền vững: Thực hiện stack kết nối với
giao diện giống như cũ:
Kiểu phần tử cũ: Stack_entry
Ækhai báo:
typedef Stack_entry Node_entry;
push và pop
Đỉnh stack là nút đầu tiên của cấu trúc kết nối
Trang 6Stack kết nối
class Stack {
public:
Stack( );
bool empty( ) const;
Error_code push(const Stack_entry &item);
Error_code pop( );
Error_code top(Stack_entry &item) const;
private:
Node *top_node;
};
Thêm phần tử mới
Stack rỗng:
top_node = NULL
Thêm phần tử mới (item) làm phần tử đỉnh:
Node *new_top = new Node(item, top_node);
top_node = new_top;
Stack::push
Error_code Stack :: push(const Stack_entry &item)
/* Post: Stack_entry item is added to the top of the
Stack; returns success or returns a code of overflow
if dynamic memory is exhausted */
{
Node *new_top = new Node(item, top_node);
if (new_top == NULL) return overflow;
top_node = new_top;
return success;
}
Xóa phần tử đầu
Stack::pop
Error_code Stack :: pop( )
/* Post: The top of the Stack is removed If the Stack
is empty the method returns underflow; otherwise it
returns success */
{
Node *old_top = top_node;
if (top_node == NULL) return underflow;
top_node = old_top->next;
delete old_top;
return success;
}
Nhược điểm và Sửa chữa
Nhược điểm:
Chưa quản lý rò rỉ bộ nhớ
Sửa chữa:
Hàm hủy
Hàm tạo copy
Chồng toán tử gán
Trang 7Hàm hủy
Stack :: Stack( ) // Destructor
/* Post: The Stack is cleared */
{
while (!empty( ))
pop( );
}
Chồng toán tử gán
Stack& Stack :: operator = (const Stack &original)
/* Post: The Stack is reset as a copy of Stack original */
{
Node *new_top, *new_copy, *original_node = original.top_node;
if (original_node == NULL) new_top = NULL;
else { // Duplicate the linked nodes
new_copy = new_top = new Node(original_node->entry);
while (original_node->next != NULL) {
original_node = original_node->next;
new_copy->next = new Node(original_node->entry);
new_copy = new_copy->next;
}
}
while (!empty( )) // Clean out old Stack entries
pop( );
top_node = new_top; // and replace them with new entries.
return *this;
}
Hàm tạo copy
Stack :: Stack(const Stack &original) // copy constructor
/* Post: The Stack is initialized as a copy of Stack original */
{
Node *new_copy, *original_node = original.top_node;
if (original_node == NULL) top_node = NULL;
else { // Duplicate the linked nodes.
top_node = new_copy = new Node(original_node->entry);
while (original_node->next != NULL) {
original_node = original_node->next;
new_copy->next = new Node(original_node->entry);
new_copy = new_copy->next;
} } }
Cập nhật định nghĩa lớp
class Stack {
public:
// Standard Stack methods
Stack( );
bool empty( ) const;
Error_code push(const Stack_entry &item);
Error_code pop( );
Error_code top(Stack_entry &item) const;
// Safety features for linked structures
Stack( );
Stack(const Stack &original);
void operator = (const Stack &original);
protected:
Node *top_node;
};
Queue móc nối
Trang 8Lớp Queue
class Queue {
public:
// standard Queue methods
Queue( );
bool empty( ) const;
Error_code append(const Queue_entry &item);
Error_code serve( );
Error_code retrieve(Queue_entry &item) const;
// safety features for linked structures
Queue( );
Queue(const Queue &original);
void operator = (const Queue &original);
protected:
Node *front, *rear;
};
Hàm tạo
Queue :: Queue( )
/* Post: The Queue is initialized to be empty */
{
front = rear = NULL;
}
Thêm một phần tử
Error_code Queue :: append(const Queue_entry &item)
/* Post: Add item to the rear of the Queue and return a code of
success or return
a code of overflow if dynamic memory is exhausted */
{
Node *new_rear = new Node(item);
if (new_rear == NULL) return overflow;
if (rear == NULL) front = rear = new_rear;
else {
rear->next = new_rear;
rear = new_rear;
}
return success;
}
Xóa một phần tử
Error_code Queue :: serve( )
/* Post: The front of the Queue is removed If the Queue is empty,
return an
Error_code of underflow */
{
if (front == NULL) return underflow;
Node *old_front = front;
front = old_front->next;
if (front == NULL) rear = NULL;
delete old_front;
return success;
}