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

thảo luận cấu trúc dữ liệu và giải thuật, đề tài ứng dụng của stack ngăn xếp

15 303 2

Đ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

Định dạng
Số trang 15
Dung lượng 1,56 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Nói cách khác, ngăn xếp là một cấu trúc dữ liệu có 2 thao tác cơ bản: bổ sung push và loại bỏ pop, trong đó loại bỏ sẽ tiến hành loại phần tử mới nhất được đưa vào danh sách.. Chính vì t

Trang 1

Đề tài: Ứng dụng của Stack- Ngăn xếp

Phần I: Giới thiệu về ngăn xếp

1 Khái niệm

Ngăn xếp là một dạng đặc biệt của danh sách mà việc bổ sung hay loại bỏ một phần

tử đều được thực hiện ở một đầu của danh sách gọi là đỉnh Nói cách khác, ngăn xếp là một cấu trúc dữ liệu có 2 thao tác cơ bản: bổ sung (push) và loại bỏ (pop), trong đó loại

bỏ sẽ tiến hành loại phần tử mới nhất được đưa vào danh sách Chính vì tính chất này mà ngăn xếp còn được gọi kiểu dữ liệu có nguyên tắc LIFO (Last in first out – vào sau ra trước)

2 Các tác vụ trên ngăn xếp

a) Initialize

Chức năng: Khởi động ngăn xếp

Dữ liệu nhập: Không

Dữ liệu xuất: stack top về vị trí khởi đầu

b) Empty

Chức năng kiểm tra ngăn xếp có bị rỗng không

Dữ liệu nhập: Không

Dữ liệu xuất: True or False (True: khi ngăn xếp rỗng, False: ngăn xếp không bị rỗng)

c) Pusth

Chức năng: thêm nút mới tại đỉnh ngăn xếp

Dữ liệu nhập: nút mới

Dữ liệu xuất: không

d) Pop

Chức năng: xóa nút tại đỉnh ngăn xếp

Dữ liệu nhập: Không

Điều kiện: stack không bị rỗng

Trang 2

Dữ liệu xuất: nút bị xóa.

e) Stacktop:

Chức năng: truy xuất nút tại đỉnh ngăn xếp

Dữ liệu nhập: Không

Điều kiện: stack không bị rỗng

Dữ liệu xuất: nút tại đỉnh ngăn xếp

f) Stacksize

Chức năng: xác định số nút hiện có trong ngăn xếp

Dữ liệu: Không

Dữ liệu xuất: số nút hiện có trong ngăn xếp

g) Clearstack

Chức năng: xóa tất cả các nút ở trong ngăn xếp

Dữ liệu nhập: không

Dữ liệu xuất:stack top về vị trí khởi đầu

h) Copystack:

Chức năng: copy ngăn xếp thành ngăn xếp mới

Dữ liệu nhập: stack nguồn

Dữ liệu xuất: ngăn xếp mới giống ngăn xếp cũ

3 Phương pháp cài đặt ngăn xếp

Có rất nhiều cách cài đặt một ngăn xếp nhưng đơn giản cũng như để dễ hình dung nhất

là cài đặt bằng mảng hay còn gọi là cài đặt theo kiểu kế tiếp Ngoài ra còn nhiều cách cài đặt khác như cài đặt bằng Danh sách liên kết (DSLK đơn, DSLK vòng, DSLK kép, DSLK vòng+kép)

Trang 3

Phần II: Ứng dụng ngăn xếp vào bài toán cụ thể- Bài toán sửa kho tàu

1 Mô tả bài toán

Xét mạng đường sắt sau đây:

Các toa tàu ở đường ray A bên phải (được đánh số 1, 2, , n) cần phải hoán vị chuyển sang đường ray B bên trái B được xem như đầu ra của các toa tàu, còn A được xem là đầu vào Một toa có thể chuyển thẳng sang đường ray bên trái, hay nó có thể rẽ xuống đường ray bên cạnh (để sửa chữa) để sau này sẽ đi ra đường ray bên trái Các toa tàu không được phép đi ngược chiều

Cho trước một hoán vị toa tàu ở đầu ra B Hãy cho biết liệu hoán vị đó có xảy ra hay không

Ví dụ: Ở đầu vào, có 4 toa tàu, ở đầu ra các toa tàu theo thứ tự là 3, 1, 4, 2 Hoán vị

này không thể xảy ra Vì toa đầu tiên là toa 3, điều này chứng tỏ nó đi thẳng ra đầu ra B, còn các toa 1 và 2 được chuyển vào kho Khi ra khỏi kho thì toa 2 phải ra trước nghĩa là phải có thứ tự 2 trước 1 Điều này mâu thuẫn với thứ tự 2 sau 1 trong hoán vị 3, 1, 4, 2

2 Ý tưởng của bài toán

Bài toán cần kiểm tra tính hợp lệ của hoán vị toa tàu ở đường ray ra, dãy các toa ở đường ray vào mặc định là dãy 1, 2, , n theo thứ tự từ trái qua phải.

- Gọi (b) = {b 1 , b 2 , , b n } là dãy toa tàu ở đường ray vào, thì b i = i với i = 1, 2, ,n.

- Gọi (a) = {a 1 , a 2 , , a n } là dãy các toa tàu ở đường ray ra Việc kiểm tra tính hợp

lệ của dãy (a) như sau:

Lần lượt xét các toa tàu a i ở đường ray ra theo chiều từ trái sang phải, nghĩa là ităng dần từ 1, 2, , đến n

- Với mỗi toa a i ta tìm xem nó có trong đường ray vào không.

- Nếu a i có trong (b) thì mọi toa tàu d có có chỉ số nhỏ hơn a i chắc chắn đã được đưa vào kho sửa chữa, ví dụ với n = 5, nếu a1 = 4 thì chắc chắn các toa 1, 2, 3 đã được

đưa vào kho sửa chữa Khi đó ta đưa tất cả các toa d này vào kho (tức là đẩy chúng vào một ngăn xếp), trước khi xét toa tầu tiếp theo ở đường rayra

- Nếu a i không có trong (b) thì chắc chắn nó phải ở trong kho, hơn nữa phải ở vị trí cửa kho sửa chữa (đỉnh ngăn xếp) Nếu a i có ở vị trí cửa kho thì ta “lấy nó ra” khỏi kho, nếu

Trang 4

ngược lại thì chứng tỏ dãy (a) là dãy hoán vị không hợp lệ tại i, và đây là dấu hiệu duy nhất để kiểm tra một dãy (a) có hợp lệ hay không

3 Thuật toán

Bước 1: nhập số toa tàu, nhập hoán vị đầu ra cho trước b[i], đầu vào a[i] đánh STT 1…n

Bước 2: Nếu stack có phần tử thì so sánh với phần tử của mảng b đang xét

2.1 i=1

2.2 Nếu phần tử x ở đỉnh của stack = b[i] đang xét: chuyển 2.3, ngược lại tới 2.7

2.3 c[i]=b[i]

2.4 in ra toa này được chuyển từ kho ra đường ray ra C

2.5 tăng i thêm 1;

2.6 kiểm tra ngăn xếp Nếu ngăn xếp rỗng chuyển bước 3, ngược lại chuyển bước 2.2 2.7 Dừng lại

Bước 3: Nếu stack k có phần tử thì lần lượt kiểm tra các phần tử trong mảng đầu vào 3.1 j=1

3.2 Nếu a[j] = b[i], tới 3.3, ngược lại tới 3.7

3.3 c[i] = b[i];

3.4 In cách dịch chuyển toa này: từ đường ray vào A đến đường ray ra C

3.5 Tăng j : j++

3.6 Kiểm tra j<n, nếu đúng tới bước 3.2, ngược lại tới bước 4

3.7 Đưa a[j] vào stack

3.8 In cách dịch chuyển toa này: từ đường ray vào A đến đường ray D

Bước 4: Sau khi duyệt hết các phần tử trong b mà ngăn xếp vẫn còn phần tử, in ra không chuyển được nữa, hoán vị không xảy ra, ngược lại nếu ngăn xếp rỗng tới bước 5 Bước 5: In ra: hoán vị có thể xảy ra

Trang 5

4 Sơ đồ khối

Trang 6

5 Chương trình

Sử dụng phần mềm Cfree để chạy chương trình (chương trình được lưu bằng file CPP đính kèm)

#include<conio.h>

#include<stdio.h>

#include<stdlib.h>

#include<iostream>

#define MAX 1000

#define TRUE 1

#define FALSE 0

int n;

int j, found;

int P[MAX], B[MAX];

int *b;

// Cai dat stack bang mang

typedef struct {

int top;

int d[MAX];

}stack;

// Khoi tao stack

void stackInitialize( stack *s)

Trang 7

s->top = - 1;

return;

}

// Kiem tra ngan xep rong

int stackEmpty( stack *s)

{

if(s->top == -1) return 1;

return 0;

}

// Them phan tu vao ngan xep

int push(stack *s, int x) {

s->top = (s->top) + 1;

s->d[s->top] = x;

return s->d[s->top];

}

// Lay 1 phan tu ra khoi ngan xep

int pop(stack *s) {

return(s->d[s->top ]);

}

Trang 8

// Ham kiem tra hoan vi co xay ra hay khong

void KiemTra() {

stack s;

s.top = -1;

int *a, *c;

int i, j, count, found, x;

count = 1; found = 0;

a = (int*)malloc((n+1)*sizeof(int));

c = (int*)malloc((n+1)*sizeof(int));

printf("\n Ta chuyen lan luot roi dua ra thong bao hoan vi co xay ra hay khong.\

n ");

for(i = 1; i <= n; i++)

a[i] = i;

for(i = 1; i <= n; i++) {

while(!stackEmpty(&s)) {

x = s.d[s.top];

if(x == b[i]) {

c[i] = b[i];

printf(" chuyen tu D sang C");

pop(&s);

i++;

}

else break;

}

Trang 9

for(j = count; j <= n; j++) {

if(a[j] == b[i]) {

c[i] = b[i];

printf(" chuyen tu A sang C");

count ++;

break;

}

else {

push(&s, a[j]);

printf(" chuyen tu A sang D");

count ++;

}

}

}

if ( (count > n) &&(!stackEmpty(&s)) ) {

printf(" Hoan vi khong xay ra!");

}

if ( (count > n) &&(stackEmpty(&s)) ) printf(" Hoan vi co xay ra!"); free(a); free(c);

getch();

Trang 10

/// Ham kiem tra phuc vu cho viec liet ke cac hoan vi co the xay ra void KiemTraHoanVi() {

stack s;

s.top = -1;

int *a, *c;

int i, j, count, x;

count = 1; found = 0;

a = (int*)malloc((n+1)*sizeof(int));

c = (int*)malloc((n+1)*sizeof(int));

for(i = 1; i <= n; i++)

a[i] = i;

for(i = 1; i <= n; i++) {

while(!stackEmpty(&s)) {

x = s.d[s.top];

if(x == b[i]) {

c[i] = b[i];

pop(&s);

i++;

}

else break;

}

Trang 11

for(j = count; j <= n; j++) {

if(a[j] == b[i]) {

c[i] = b[i];

count ++;

break;

}

else {

push(&s, a[j]);

count ++;

}

}

}

if ( (count > n) &&(!stackEmpty(&s)) ) {

found = FALSE;

}

if ( (count > n) &&(stackEmpty(&s)) ) found = TRUE; free(a); free(c);

}

/// Dua ra cac hoan vi

void result() {

int i;

b = (int*)malloc((n+1)*sizeof(int));

for(i = 1; i <= n; i++)

b[i] = P[i];

Trang 12

KiemTraHoanVi();

if(found == TRUE) {

for(i = 1; i <= n; i++) printf("%3d", b[i]); printf("\n");

}

free(b);

}

/// Ham phuc vu sinh hoan vi

void Try(int i) {

int j;

for(j = 1; j <= n; j++) {

if(B[j]) {

P[i] = j;

B[j] = FALSE;

if(i == n) result();

else Try(i + 1);

B[j] = TRUE;

}

}

}

void Cackhanang(){

Trang 13

for(int i = 1; i <= n; i++) B[i] = TRUE;

Try(1);

getch();

}

main() {

int ch;

printf("\n So toa tau n = ");

scanf("%d", &n);

printf("\nChon 1 trong 3 chuc nang: \n");

printf("\nChon phim 1 neu muon kiem tra 1 hoan vi la co xay ra hay ko"); printf("\nChon phim 2 neu muon dua ra tat ca hoan vi co the xay ra."); printf("\nChon phim 3 de thoat khoi chuong trinh.\n");

while(1) {

printf("\nChon chuc nang: "); scanf("%d", &ch);

// <ul>

switch(ch) {

case 1:

b = (int*)malloc((n+1)*sizeof(int));

printf("\n Nhap thu tu can tao: \n");

fflush(stdin);

for(int i = 1; i <= n; i++) {

printf("\n b[%d] = ", i);

Trang 14

scanf("%d", &b[i]);

}

KiemTra();

free(b);break;

case 2:

printf("\n Cac hoan vi co the tao thanh la: \n");

Cackhanang();break;

case 3:

exit(0);

default:

printf("\n Chuc nang ban chon ko co Xin chon lai"); getch();

}

}

}

Trang 15

6 Demo chương trình

Ngày đăng: 13/11/2018, 22:23

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w