Ngd ng hàng đ i

Một phần của tài liệu Kỹ Thuật Lập Trình (Trang 58 - 156)

M i v n đ c a th c t liên quan t i c ch FIFO nh c ch g i ti n, rút ti n trong ngân hàng, đ t vé máy bay đ u có th ng d ng đ c b ng hàng đ i. Hàng đ i còn có nh ng ng d ng trong vi c gi i quy t các bài toán c a H đi u hành và ch ng trình d ch nh bài toán đi u khi n các quá trình, đi u khi n n p ch ng trình vào b nh hay bài toán l p l ch. B n đ c có th tham kh o thêm trong các tài li u [1], [2]. D i đây, chúng ta đ a ra m t ng d ng c a hàng đ i đ gi i quy t bài toán “Nhà s n xu t và Ng i tiêu dùng”.

Ví d 3.2- Gi i quy t bài toán ”Ng i s n xu t và nhà tiêu dùng “ v i s các vùng đ m h n ch .

Chúng ta mô t quá trình s n xu t và tiêu dùng nh hai quá trình riêng bi t và th c hi n song hành, ng i s n xu t có th s n xu t t i đa n m t hàng. Ng i tiêu dùng ch đ c phép s d ng trong s n m t hàng. Tuy nhiên, ng i s n xu t ch có th l u tr vào kho khi và ch khi kho ch a b đ y. Ng c l i, n u kho hàng không r ng (kho có hàng) ng i tiêu dùng có th tiêu dùng nh ng m t hàng trong kho theo nguyên t c hàng nào nh p vào kho tr c đ c tiêu dùng tr c gi ng nh c ch FIFO c a queue. Sau đây là nh ng thao tác ch y u trên hàng đ i đ gi i quy t bài toán:

Ta xây d ng hàng đ i nh m t danh sách tuy n tính g m MAX ph n t m i ph n t là m t c u trúc, hai bi n front, rear tr đ n l i vào và l i ra trong queue:

typedef struct{ int mahang; char ten[20]; } hang;

typedef struct {

int front, rear; hang node[MAX]; } queue;

Thao tác Initialize: thi t l p tr ng thái ban đ u c a hàng đ i. tr ng thái này, font và rear có cùng m t giá tr MAX-1.

void Initialize ( queue *pq){

pq->front = pq->rear = MAX -1; }

Thao tác Empty: ki m tra hàng đ i có tr ng thái r ng hay không. Hàng đ i r ng khi front == rear.

int Empty(queue *pq){

if (pq->front==pq->rear) return(TRUE); return(FALSE); }

Thao tác Insert: thêm X vào hàng đ i Q. N u vi c thêm X vào hàng đ i đ c th c hi n đ u hàng, khi đó rear có giá tr 0, n u rear không ph i đ u hàng đ i thì giá tr c a nó đ c t ng lên 1 đ n v .

void Insert(queue *pq, hang x){ if (pq->rear==MAX-1 ) pq->rear=0; else

(pq->rear)++; if (pq->rear ==pq->front){

printf("\n Queue full"); delay(2000);return; }

else

pq->node[pq->rear]=x; }

Thao tác Remove: lo i b ph n t v trí front kh i hàng đ i. N u hàng đ i tr ng thái r ng thì thao tác Remove không th th c hi n đ c, trong tr ng h p khác front đ c t ng lên m t đ n v .

hang Remove(queue *pq){ if (Empty(pq)){

printf("\n Queue Empty"); delay(2000); } else { if (pq->front ==MAX-1) pq->front=0; else pq->front++; } return(pq->node[pq->front]); }

Thao tác Traver: Duy t t t c các nút trong hàng đ i. void Traver( queue *pq){

int i;

if(Empty(pq)){

printf("\n Queue Empty");

return;

}

if (pq->front ==MAX-1)

else

i = pq->front+1; while (i!=pq->rear){

printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); if(i==MAX-1)

i=0;

else

i++; }

printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); } D i đây là toàn b v n b n ch ng trình: #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <dos.h> #include <string.h> #include <math.h> #define MAX 50 #define TRUE 1 #define FALSE 0 typedef struct{ int mahang; char ten[20]; } hang; typedef struct {

int front, rear; hang node[MAX]; } queue;

/* nguyen mau cua ham*/ void Initialize( queue *pq); int Empty(queue *); void Insert(queue *, hang x); hang Remove(queue *);

void Traver(queue *); /* Mo ta ham */

void Initialize ( queue *pq){

pq->front = pq->rear = MAX -1; }

int Empty(queue *pq){

return(TRUE); return(FALSE); }

void Insert(queue *pq, hang x){ if (pq->rear==MAX-1 ) pq->rear=0; else

(pq->rear)++; if (pq->rear ==pq->front){

printf("\n Queue full"); delay(2000);return; } else pq->node[pq->rear]=x; } hang Remove(queue *pq){ if (Empty(pq)){

printf("\n Queue Empty"); delay(2000); } else { if (pq->front ==MAX-1) pq->front=0; else pq->front++; } return(pq->node[pq->front]); }

void Traver( queue *pq){ int i;

if(Empty(pq)){

printf("\n Queue Empty");

return; } if (pq->front ==MAX-1) i=0; else i = pq->front+1; while (i!=pq->rear){

printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); if(i==MAX-1)

i=0;

else

i++; }

printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); }

void main(void){ queue q;

char chucnang, front1; char c; hang mh; clrscr();

Initialize(&q); do {

clrscr();

printf("\n NGUOI SAN XUAT/ NHA TIEU DUNG"); printf("\n 1- Nhap mot mat hang");

printf("\n 2- Xuat mot mat hang"); printf("\n 3- Xem mot mat hang"); printf("\n 4- Xem hang moi nhap"); printf("\n 5- Xem tat ca");

printf("\n 6- Xuat toan bo");

printf("\n Chuc nang chon:");chucnang=getch(); switch(chucnang){

case ‘1’:

printf("\n Ma mat hang:"); scanf("%d", &mh.mahang); printf("\n Ten hang:");scanf("%s", mh.ten);

Insert(&q,mh);break;

case ‘2’:

if (!Empty(&q)){

mh=Remove(&q);

printf("\n %5d %20s",mh.mahang, mh.ten); }

else {

printf("\n Queue Empty"); delay(1000);

}

break;

case ‘3’:

front1=(q.front==MAX-1)?0:q.front+1; printf("\n Hang xuat");

printf("\n%6d%20s",q.node[front1].mahang,q.node[front1].ten); break;

case ‘4’:

printf("\n Hang moi nhap");

printf("\n%5d%20s",q.node[q.rear].mahang,q.node[q.rear].ten); break;

case ‘5’:

printf("\ Hang trong kho"); Traverse(&q);delay(2000);break; } } while(chucnang!=’0’); } 3.3. DANH SÁCH LIÊN K T N 3.3.1. Gi i thi u và đnh ngh a

M t danh sách móc n i, ho c ng n g n h n, m t danh sách, là m t dãy có th t các ph n t đ c g i là đnh. Danh sách có đi m b t đ u, g i là tiêu đ hay đnh đ u, m t đi m cu i cùng g i là đnh cu i. M i đnh trong danh sách đ u có cùng ki u ngay c khi ki u này có nhi u d ng khác nhau.

B n ch t đ ng là m t trong nh ng tính ch t chính c a danh sách móc n i. Có th thêm ho c b t đnh trong danh sách vào m i lúc, m i v trí. Vì s đnh c a danh sách không th d ki n tr c đ c, nên khi th c hi n, chúng ta ph i dùng con tr mà không dùng đ c m ng đ b o đ m vi c th c hi n hi u qu và tin c y.

M i đnh trong danh sách đ u g m hai ph n. Ph n th nh t ch a d li u. D li u có th ch là m t bi n đ n ho c là m t c u trúc (ho c con tr c u trúc) có ki u nào đó. Ph n th hai c a đnh là m t con tr ch vào đa ch c a đnh ti p theo trong danh sách. Vì v y có th d dàng s d ng các đnh c a danh sách qua m t c u trúc t tr ho c đ qui.

Danh sách móc n i đ n gi n d i đây xây d ng m i đnh c a danh sách ch l u gi m t bi n nguyên.

/*đnh c a danh sách đ n ch ch a m t s nguyên*/ struct don {

int phantu; struct don *tiep; };

typedef struct don don_t;

Trong tr ng h p này, bi n nguyên phantu c a t ng đnh ch a d li u còn bi n con tr tiep ch a đa ch c a đnh ti p theo. S đ bi u di n danh sách móc n i đ n đ c bi u di n nh hình d i đây:

Ph n_t Ph n_t Ph n_t ....

T ng quát h n, m i đnh c a danh sách có th ch a nhi u ph n t d li u. Trong tr ng h p này, h p lý h n c là đnh ngh a m t ki u c u trúc t ng ng v i d li u c n l u gi t i m i đnh. Ph ng pháp này đ c s d ng trong đnh ngh a ki u sau đây:

/*đnh c a danh sách t ng quát */ struct tq { thtin_t phantu; struc tq*tiep; }; typedef struct tq tq_t; Ki u c u trúc thtin_t ph i đ c đnh ngh a tr c đó đ t ng ng v i các d li u s đ c l u tr t i t ng đnh. Danh sách đ c t o nên t ki u đnh này gi ng nh s đ trong Hình 3.4, ngo i tr vi c m i phantu là m t bi n nguyên.

3.3.2. Các thao tác trên danh sách móc n i

Các thao tác trên danh sách móc n i bao g m vi c c p phát b nh cho các đnh và gán d li u cho con tr . danh sách đ c t o nên đúng đ n, ta bi u di n ph n t cu i danh sách là m t con tr NULL. Con tr NULL là tín hi u thông báo không còn ph n t nào ti p theo trong danh sách n a.

Ti n h n c là chúng ta đnh ngh a m t con tr t i danh sách nh sau:

struct node { int infor; struct node *next; };

typedef struct node *NODEPTR; // Con tr t i node

C p phát b nh cho m t node:

NODEPTR Getnode(void) { NODEPTR p;

P = (NODEPTR) malloc(sizeof( struct node)); Return(p);

}

Gi i phóng b nh c a m t node”

NODEPTR Freenode( NODEPTR p){ free(p);

}

Chèn m t ph n t m i vào đ u danh sách:

Các b c đ chèn m t ph n t m i vào đ u danh sách c n th c hi n là: X C p không gian b nh đ l u gi m t đnh m i;

X Thi t l p liên k t v i đnh m i.

S đ bi u di n phép thêm m t đnh m i vào đ u danh sách đ c th hi n nh trên hình 3.5.

Node c n chèn vào đ u danh sách móc n i.

Hình 3.5. Thêm đnh m i vào đ u danh sách móc n i đ n

void Push_Top( NODEPTR *plist, int x) { NODEPTR p;

p= Getnode(); // c p không gian nh cho đnh m i p -> infor = x; // gán giá tr thích h p cho đnh m i p ->next = *plist;

*plist = p; // thi t l p liên k t }

Thêm m t ph n t m i vào cu i danh sách:

thêm m t node vào cu i danh sách, ta c n th c hi n qua các b c sau: X C p phát b nh cho node m i;

X Gán giá tr thích h p cho node m i;

X Di chuy n con tr t i ph n t cu i danh sách; X Thi t l p liên k t cho node m i.

S đ th hiên phép thêm m t ph n t m i vào cu i danh sách đ c th hi n nh trong hình 3.6

Hình 3.6. Thêm node m i vào cu i danh sách.

infor next infor next infor next

infor next

infor next infor next infor next

void Push_Bottom( NODEPTR *plist, int x) { NODEPTR p, q;

p= Getnode(); // c p phát b nh cho node m i p->infor = x; // gán giá tr thông tin thích h p q = *plist; // chuy n con tr t i cu i danh sách while (q-> next != NULL)

q = q -> next;

// q là node cu i cùng c a danh sách liên k t q -> next = p; //node cu i bây gi là node p; p ->next = NULL; // liên k t m i c a p }

Thêm node m i q vào gi a danh sách tr c node p:

thêm node q vào tr c node p, chúng ta c n l u ý node p ph i có th c trong danh sách. Gi s node p là có th c, khi đó x y ra hai tình hu ng: ho c node p là node cu i cùng c a danh sách liên k t t c p->next =NULL, ho c node p ch a ph i là cu i cùng hay p->next != NULL. Tr ng h p th nh t, chúng ta ch c n g i t i thao tác Push_Bottom(). Tr ng h p th 2, chúng ta th c hi n theo các b c nh sau:

X C p phát b nh cho node m i; X Gán giá tr thích h p cho node;

X Thi t l p liên k t node q v i node k ti p p; X Thi t l p liên k t node node p v i node q; void Push_Before( NODEPTR p, int x ){

NODEPTR q; if (p->next==NULL) Push_Bottom(p, x);

else {

q= Getnode(); // c p phát b nh cho node m i q -> infor = x; // gán giá tr thông tin thích h p

q-> next = p-> next; // thi t l p liên k t node q v i node k ti p p; p->next = q; // thi t l p liên k t node p v i node k ti p q; }

}

p

q

Hình 3.7. Phép thêm ph n t vào gi a danh sách liên k t đ n.

Xoá m t node ra kh i đ u danh sách:

Khi lo i b node kh i đ u danh sách liên k t, chúng ta c n chú ý r ng n u danh sách đang r ng thì không th th c hi n vi c lo i b . Trong tr ng h p còn l i, ta th c hi n nh sau:

X Dùng node p tr t i đ u danh sách;

X D ch chuy n v trí đ u danh sách t i node ti p theo; X Lo i b liên k t v i p;

X Gi i phóng node p; void Del_Top( NODEPTR *plist) {

NODEPTR p;

p = *plist; // node p tr t i đ u danh sách; if (p==NULL) return; // danh sách r ng

(*plist) = (*plist) -> next; // d ch chuy n node g c lên node k ti p p-> next = NULL; //lo i b liên k t v i p

Freenode(p); // gi i phóng p; }

Lo i b node cu i danh sách:

M t node cu i danh sách có th x y ra ba tình hu ng sau: X Danh sách r ng: ta không c n th c hi n lo i b ;

X Danh sách ch có đúng m t node: ng v i tr ng h p lo i b node g c; Tr ng h p còn l i danh sách có nhi u h n m t node, khi đó ta ph i d ch chuy n t i node g n node cu i cùng nh t đ th c hi n lo i b .

void Del_Bottom(NODEPTR *plist) { NODEPTR p, q;

if (*plist==NULL) return; //không làm gì

else if ( (*plist)->next==NULL)) // danh sách có m t node Del_Top(plist);

else {

infor next

infor next infor next infor next

p = *plist;

while (p->next!=NULL){

q = p;

p = p->next; // q là node sau node p;

}

// p là node cu i danh sách;

q->next =NULL; //node cu i cùng là q Freenode(p); //gi i phóng p;

} }

Lo i b node gi a danh sách (tr c node p):

C n đ ý r ng, n u tr c node pNULL (p->next==NULL) thì ta không th c hi n lo i b đ c. Tr ng h p còn l i chúng ta th c hi n nh sau:

X Dùng node q tr t i node tr c node p; X Lo i b liên k t c a q;

X Gi i phóng q. void Del_before(NODEPTR p){

NODEPTR q;

if (p->next==NULL) return; // không làm gì q = p ->next;

p->next = q->next; Freenode(q); }

B n đ c có th tìm th y nh ng cài đ t c th c a danh sách liên k t đ n trong các tài li u [1], [2].

3.4. DANH SÁCH LIÊN K T KÉP

M i khi thao tác trên danh sách, vi c duy t danh sách theo c hai chi u t ra thu n ti n h n cho ng i s d ng. ôi khi chúng ta ph i di chuy n trong danh sách t node cu i lên node đ u ho c ng c l i b ng cách đi qua m t lo t các con tr . i u này có th d dàng gi i quy t đ c n u ta t ng thông tin ch a t i t ng đnh c a danh sách. Ngoài con tr ch a đa ch đnh ti p theo, ta thêm con tr tr c đ ch a đa ch đ ng sau đnh này. Làm nh v y, chúng ta thu đ c m t c u trúc d li u m i g i là danh sách liên k t kép.

struct node {

int infor;

struct node *right;// con tr t i node sau struct node *left; // con tr t i node k ti p };

Hình 3.8. Mô t m t danh sách liên k t kép.

Các thao tác trên danh sách liên k t kép c ng t ng t nh danh sách liên k t đ n. Nh ng c n chú ý r ng, m i node p c a danh sách liên k t kép có hai đ ng liên k t là p-> left và p->right;

Thao tác thêm node m i vào đ u danh sách liên k t kép:

X C p phát b nh cho node m i; X Gán giá tr thích h p cho node m i; X Thi t l p liên k t cho node m i; void Push_Top(NODEPTR *plist, int x){

NODEPTR p;

p = Getnode(); //c p phát b nh cho node p ->infor = x; //gán giá tr thích h p; p -> right = *plist; // thi t l p liên k t ph i (*plist) ->left = p; // thi t liên k t v i *plist p-> left = NULL;// thi t l p liên k t trái *plist = p;

}

Thao tác thêm node vào cu i danh sách:

X N u danh sách r ng thì thao tác này trùng v i thao tác thêm node m i vào đ u danh sách.

X N u danh sách không r ng chúng ta th c hi n nh sau: ̇ C p phát b nh cho node;

̇ Gán giá tr thích h p cho node;

̇ Chuy n con tr t i node cu i trong danh sách; ̇ Thi t l p liên k t trái;

̇ Thi t l p liên k t ph i; void Push_Bottom(NODEPTR *plist, int x){

NODEPTR p, q; if (*plist ==NULL)

Push_Top(plist, x); else {

p= Getnode();// c p phát b nh cho node p->infor =x; //gán giá tr thích h p //chuy n con tr t i node cu i danh sách

Một phần của tài liệu Kỹ Thuật Lập Trình (Trang 58 - 156)

Tải bản đầy đủ (PDF)

(156 trang)