Bài giảng Cấu trúc dữ liệu 1 - Chương 3: Danh sách đặc (Mảng)

• Mảng là tập hợp của các biến cùng kiểu ñược

xếp liên tiếp nhau trong bộ nhớ trong.

• Các loại mảng:

– Mảng 1 chiều

• <kiểu dữ liệu> tên_mảng [số_phần_tử]

– Mản nhiều chiều

• <kiểu_dữ_liệu> tên_mảng

[số_phần_tử_chiều_1][số_phần_tử_chiều_2] [số_phần

_tử_chiều_n

pdf17 trang | Chuyên mục: Cấu Trúc Dữ Liệu & Giải Thuật | Chia sẻ: dkS00TYs | Lượt xem: 2319 | Lượt tải: 1download
Tóm tắt nội dung Bài giảng Cấu trúc dữ liệu 1 - Chương 3: Danh sách đặc (Mảng), để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
 rồi ñẩy vào stack
– Toán tử ‘+’, ‘-’, ‘*’, ‘/’: lấy 2 giá trị trong stack, 
tính toán và ñẩy kết quả vào stack
– Toán tử ‘=’: in ñỉnh của stack ra
– ‘q’: kết thúc chương trình
Ký pháp Ba Lan ñảo – Ví dụ
Ban ñầu
Tính toán biểu thức: 3 5 + 2 * =
Toán tử ?
Nhập vào 3
3
Toán tử ?
Nhập vào 5
3
5
Toán tử +
Lấy ra 5 và 3
Tính 3 + 5 => 8
3
5
ðẩy 8 vào
8
Toán tử *
Lấy ra 2 và 8
Tính 8 * 2 => 16
8
ðẩy vào 16
16
Toán tử =
In ra 16
16
Toán tử ?
Nhập vào 2
8
2 2
Ký pháp Ba Lan ñảo - Hàm get_command
char get command( ) {
char command;
bool waiting = true;
cout :";
while (waiting) {
cin >> command;
command = tolower(command);
if (command == ‘?’ || command == ‘=‘ || command == ‘+’ ||
command == ‘−’|| command == ‘*’ || command == ‘/’ ||
command == ‘q’) waiting = false;
else {
cout << "Please enter a valid command:" << endl
<< "[?]push to stack [=]print top" <<endl
<< "[+] [−] [*] [/] are arithmetic operations" << endl
<< "[Q]uit." << endl;
}
}
return command;
}
Ký pháp Ba Lan ñảo - Giải thuật tính toán
Algorithm Op_process
Input: toán tử op, stack chứa các toán hạng
Output: stack chứa các toán hạng sau khi tính xong toán tử op
1. Nếu stack không rỗng
1.1. Lấy ñỉnh stack ra thành p
1.2. Bỏ phần tử trên ñỉnh stack
1.3. Nếu stack rỗng
1.3.1. ðẩy p ngược lại
1.3.2. Báo lỗi và thoát
1.4. Lấy ñỉnh stack ra thành q
1.5. Bỏ phần tử trên ñỉnh stack
1.6. Tính toán (q op p)
1.7. ðẩy kết quả vào stack
End Op_process
Ký pháp Ba Lan ñảo - Toán tử cộng
if (numbers.top(p) == underflow)
cout << "Stack rỗng";
else {
numbers.pop( );
if (numbers.top(q) == underflow) {
cout << "Stack chỉ có 1 trị”;
numbers.push(p);
}
else {
numbers.pop( );
if (numbers.push(q + p) == overflow)
cout << "Stack ñầy”;
}
}
Ký pháp Ba Lan ñảo - Chương trình chính
#include "stack.cpp"
//prototype
void introduction( );
void instructions( );
char get_command( );
bool do_command(char command, Stack &numbers);
int main( ) {
Stack stored_numbers;
introduction( ); 
instructions( );
while (do_command(get_command( ), stored_numbers));
}
//implementation
…
Ký pháp Ba Lan ñảo - Hàm do_command
bool do_command(char command, Stack &numbers) {
double p, q;
switch (command) {
case '?’:
cout > p;
if (numbers.push(p) == overflow)
cout << "Warning: Stack full, lost number" << endl; break;
case '=‘:
if (numbers.top(p) == underflow) cout << "Stack empty" << endl;
else cout << p << endl; break;
// Add options for further user commands.
case ‘q’: cout << "Calculation finished.\n"; return false;
}
return true;
}
4. Queue
• Một queue là một cấu trúc dữ liệu mà các phép toán 
thực hiện ở 2 ñỉnh, một ñỉnh gọi là ñầu hàng, một 
ñỉnh gọi là cuối hàng.
• Phần tử vào trước sẽ ra trước – FIFO (First In First 
Out)
Queue trừu tượng
• Một queue kiểu T:
– Một dãy hữu hạn kiểu T
– Một số tác vụ:
• 1. Khởi tạo queue rỗng (create)
• 2. Kiểm tra rỗng (empty)
• 3. Thêm một giá trị vào cuối của queue (append)
• 4. Bỏ giá trị ñang có ở ñầu của queue (serve)
• 5. Lấy giá trị ở ñầu của queue, queue không ñổi
(retrieve)
Thiết kế queue
enum Error_code {fail, success, overflow, underflow};
template 
class Queue {
public:
Queue(); //constructor
bool empty() const; //kiểm tra rỗng
Error_code append(const Entry &item); //ñẩy item vào
Error_code serve(); //bỏ 1 phần tử ở ñầu
Error_code retrieve(Entry &item); //lấy giá trị ở ñầu
//khai báo một số phương thức cần thiết khác
private:
//khai báo dữ liệu và hàm phụ trợ chỗ này
};
Thiết kế các phương thức
template 
bool Queue::empty() const;
Pre: Không có
Post: Trả về giá trị true nếu queue hiện tại là rỗng, ngược lại thì trả về false
template 
Error_code Queue::append(const Entry &item);
Pre: Không có
Post: Nếu queue hiện tại không ñầy, item sẽ ñược thêm vào cuối của queue. 
Ngược lại trả về giá trị overflow của kiểu Error_code và queue không ñổi.
template 
Error_code Queue::serve() const;
Pre: Không có
Post: Nếu queue hiện tại không rỗng, ñầu của queue hiện tại sẽ bị hủy bỏ. 
Ngược lại trả về giá trị underflow của kiểu Error_code và queue không ñổi.
template 
Error_code Queue::retrieve(Entry &item) const;
Pre: Không có
Post: Nếu queue hiện tại không rỗng, ñầu của queue hiện tại sẽ ñược chép vào tham
biến item. Ngược lại trả về giá trị underflow của kiểu Error_code.
Mở rộng queue
• Có thêm các tác vụ:
– Kiểm tra ñầy (full)
– Tính kích thước (size)
– Giải phóng queue (clear)
– Lấy giá trị ở ñầu và bỏ ra khỏi queue (serve_and_retrieve)
• Mã C++:
template 
class Extended_queue: public Queue {
public:
bool full( ) const;
int size( ) const;
void clear( );
Error_code serve_and_retrieve(Entry &item);
};
Có các khả năng public, 
protected, private
Tính thừa hưởng
• Dùng tính thừa hưởng:
– Extended_queue có ñầy ñủ các thành phần của Queue
– Thêm vào ñó các thành phần riêng của mình
Queue liên tục
• Dùng một array: Có xu hướng dời về cuối array
• Hai cách hiện thực ñầu tiên:
– Khi lấy một phần tử ra thì ñồng thời dời hàng lên một vị
trí.
– Chỉ dời hàng về ñầu khi cuối hàng không còn chỗ
A B C D B C D B C D E
Ban ñầu Lấy ra 1 phần tử:
dời tất cả về trước
Thêm vào 1 phần tử
A B C D B C D B C D E
Ban ñầu Lấy ra 1 phần tử Thêm vào 1 phần tử: 
dời tất cả về trước ñể
trống chỗ thêm vào
Queue là array vòng (circular array)
Array vòng với ngôn ngữ C++
• Xem array như là một vòng: 
– phần tử cuối của array nối với phần tử ñầu của
array
• Tính toán vị trí kề:
– i = ((i + 1) == max) ? 0 : (i + 1);
– if ((i + 1) == max)
i = 0;
else i = i + 1;
– i = (i + 1) % max;
ðiều kiện biên của queue vòng
Một số cách hiện thực queue liên tục
• Một array với front là phần tử ñầu và tất cả các phần
tử sẽ ñược dời lên khi lấy ra một phần tử.
• Một array có hai chỉ mục luôn tăng chỉ ñến phần tử
ñầu và cuối.
• Một array vòng có chỉ mục front và rear và một ô 
luôn trống.
• Một array vòng có chỉ mục front và rear và một cờ
(flag) cho biết queue là ñầy (rỗng) chưa.
• Một array vòng với chỉ mục front và rear có các giá
trị ñặc biệt cho biết queue ñang rỗng.
• Một array vòng với chỉ mục front và rear và một số chứa
số phần tử của queue.
Hiện thực queue liên tục
const int maxqueue = 10; // small value for testing
template 
class Queue {
public:
Queue( );
bool empty( ) const;
Error_code serve( );
Error_code append(const Entry &item);
Error_code retrieve(Entry &item) const;
protected:
int count;
int front, rear;
Entry entry[maxqueue];
};
Khởi tạo và kiểm tra rỗng
• Khởi tạo:
template 
Queue::Queue( ) {
count = 0;
rear = maxqueue − 1;
front = 0;
}
• Kiểm tra rỗng:
template 
bool Queue::empty( ) const {
return count == 0;
}
Dùng biến count ñể
biết số phần tử
trong queue
Thêm một giá trị vào queue
• Giải thuật:
1. Nếu hàng ñầy
1.1. Báo lỗi overflow
2. Tính toán vị trí cuối mới theo array vòng
3. Gán giá trị vào vị trí cuối mới này
4. Tăng số phần tử lên 1
4. Báo success
A B C
front rear
D
Loại một giá trị khỏi queue
• Giải thuật:
1. Nếu hàng rỗng
1.1. Báo lỗi underflow
2. Tính toán vị trí ñầu mới theo array vòng
3. Giảm số phần tử ñi 1
3. Báo success
A B C D
front rear
Thêm/loại một giá trị – Mã C++
template 
Error_code Queue::append(const Entry &item) {
if (count >= maxqueue) return overflow;
count++;
rear = ((rear + 1) == maxqueue) ? 0 : (rear + 1);
entry[rear] = item;
return success; 
}
template 
Error_code Queue::serve() {
if (count <= 0) return underflow;
count−−;
front = ((front + 1) == maxqueue) ? 0 : (front + 1);
return success;
}
Ứng dụng: Giả lập phi trường
• Mô tả:
– 1. Sử dụng hàng ñợi runway cho việc cất và hạ cánh.
– 2. Một máy bay có thể cất hoặc hạ cánh trong một ñơn vị
thời gian. 
– 3. Tại một thời ñiểm, số máy bay ñến là ngẫu nhiên.
– 4. Máy bay hạ cánh ñược ưu tiên trước máy bay cất cánh.
– 5. Các máy bay chờ cất/hạ cánh ñược chứa vào các hàng
ñợi tương ứng và với số lượng giới hạn.
Giả lập phi trường – Hàng ñợi
enum Runway_activity {idle, land, takeoff};
class Runway {
public:
Runway(int limit);
Error_code can_land(const Plane ¤t);
Error_code can_depart(const Plane ¤t);
Runway_activity activity(int time, Plane &moving);
void shut_down(int time) const;
private:
Extended queue landing;
Extended queue takeoff;
int queue_limit;
…
};
Giả lập phi trường – Hạ cánh
Error_code Runway :: can_land(const Plane ¤t) {
Error_code result;
if (landing.size( ) < queue_limit)
result = landing.append(current);
else
result = fail;
num_land_requests++;
if (result != success)
num_land_refused++;
else
num_land_accepted++;
return result; 
}
Giả lập phi trường – Xử lý
Runway_activity Runway::activity(int time, Plane &moving) {
Runway_activity in_progress;
if (!landing.empty( )) {
landing.retrieve(moving);
in_progress = land;
landing.serve( );
} else if (!takeoff.empty( )) {
takeoff.retrieve(moving);
in_progress = takeoff;
takeoff.serve( );
} else
in_progress = idle;
return in_progress;
}
Giả lập phi trường – Giả lập
for (int current_time = 0; current_time < end_time; current_time++) {
int number_arrivals = variable.poisson(arrival_rate);
for (int i = 0; i < number_arrivals; i++) {
Plane current_plane(flight_number++, current_time, arriving);
if (small_airport.can_land(current_plane) != success)
current_plane.refuse( );
}
int number_departures = variable.poisson(departure_rate);
for (int j = 0; j < number_departures; j++) {
Plane current_plane(flight_number++, current_time, departing);
if (small_airport.can_depart(current_plane) != success)
current_plane.refuse( );
}
Plane moving_plane;
switch (small_airport.activity(current_time, moving_plane)) {
case land: moving_plane.land(current_time); break;
case takeoff: moving_plane.fly(current_time); break;
case idle: run_idle(current_time);
}
}
66
Câu hỏi và thảo luận

File đính kèm:

  • pdfBài giảng Cấu trúc dữ liệu 1 - Chương 3 Danh sách đặc (Mảng).pdf