Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 20 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
20
Dung lượng
324,22 KB
Nội dung
Giáo án môn: Lý Thuyết Đồ Thị Nguyễn Minh Đức - ĐHQG Hà Nội 24 Chng 3 CC THUT TON TèM KIM TRấN THN V NG DNG Trong lý thuyt th, cú rt nhiu thut toỏn c xõy dng da trờn c s duyt qua tt c cỏc nh ca th sao cho mi nh ch c duyt ỳng mt ln. Do vy, vic xõy dng cỏc thut toỏn cho phộp duyt qua tt c cỏc nh ca th mt cỏch cú h thng l mt vn quan trng thu hỳt s quan tõm nghiờn cu ca nhiu nh khoa hc. Cỏc thut toỏn nh vy c gi chung l thut toỏn tỡm kim trờn th. Trong chng ny chỳng ta s nghiờn cu hai thut toỏn tỡm kim c bn trờn th l Thut toỏn tỡm kim theo chiu sõu (Depth First Search) v Thut toỏn tỡm kim theo chiu rng (Breadth First Search) v mt vi ng dng ca hai thut toỏn ny. n gin cho vic trỡnh by, chỳng ta s xột th vụ hng G = (V,E), |V| = n, |E| = m; th cú hng s c suy ra mt cỏch tng t vi mt vi im c bit cn chỳ ý. ỏnh giỏ hiu qu ca cỏc thut toỏn ny, chỳng ta ch chỳ trng n vic ỏnh giỏ phc tp tớnh toỏn ca thut toỏn, tc s phộp toỏn m thut toỏn cn thc hin trờn mi b d liu vo trong trng hp xu nht. phc tp tớnh toỏn ny c biu din bng mt hm s ca kớch thc d liu u vo. C th õy kớch thc ca d liu vo s l s nh n v s cnh m ca th. Khi ú phc tp tớnh toỏn ca thut toỏn s c biu din bng hm hai bin f(n,m) l s phộp toỏn nhiu nht m thut toỏn cn phi thc hin i vi mi th n nh, m cnh. so sỏnh tc tng ca hai hm nhn giỏ tr khụng õm f(n) v g(n) chỳng ta s dng ký hiu f(n) = O(g(n)). iu ny cú ngha tng ng vi vic tỡm c cỏc hng s dng C v N sao cho: NnnCgnf );()( Trng hp m rng, nu f(n 1 ,n 2 , ,n k ) v g(n 1 ,n 2 , ,n k ) l cỏc hm biu din, ta vit: f(n 1 ,n 2 , ,n k )=O(g(n 1 ,n 2 , ,n k )) Tỡm c cỏc hng s dng C v N sao cho: f(n 1 ,n 2 , ,n k ) Cg(n 1 ,n 2 , ,n k ) vi Nn Nu phc tp tớnh toỏn ca thut toỏn l O(g(n)) thỡ ta núi l thut toỏn cú thi gian tớnh toỏn c O(g(n)). 3.1 Thut toỏn tỡm kim theo chiu sõu trờn th (Depth First Search) í tng chớnh ca thut toỏn tỡm kim theo chiu sõu cú th c hiu nh sau: Ban u tt c cỏc nh ca th u cha c duyt n, ta s bt u vic tỡm kim t mt nh no ú, gi s nh ú l v 1 . Sau ú chn u l mt nh (cú th chn tu ý) trong danh sỏch cỏc nh k vi nh v 1 m cha c xột n v lp li quỏ trỡnh tỡm kim i vi nh u ny. bc tng quỏt, gi s ang xột nh v k , nu trong cỏc nh k vi nh v k ta tỡm c nh w l nh cha c duyt n thỡ ta s li bt u quỏ trỡnh tỡm kim t ú v w s tr thnh nh ó c duyt qua. Nu khụng cũn nh no k vi nh v k l cha c duyt n thỡ ta núi rng nh ny ó c duyt xong v quay li tip tc tỡm kim t nh m trc ú ta n c nh v k . Quỏ trỡnh c tip tc nh vy cho n khi tt c cỏc nh ca th ó c duyt ht. Nh vy ta cú th hiu mt cỏch n gin l vic tỡm kim theo chiu sõu trờn th bt u t nh v c thc hin trờn c s tỡm kim theo chiu sõu t cỏc nh cha c duyt k vi v. Quỏ trỡnh ny c mụ t bng th tc quy sau: Procedure DFS(v) Giáo án môn: Lý Thuyết Đồ Thị Nguyễn Minh Đức - ĐHQG Hà Nội 25 1 4 5 2 3 7 8 6 10 9 (* Tỡm kim theo chiu sõu trờn th bt u t nh v *) (* Cỏc bin Chuaxet v Ke l bin ton cuc *) Begin Xet_dinh(v); Chuaxet[v]:=False; For u Ke(v) do If Chuaxet[u] Then DFS(u); End; (* Chng trỡnh chớnh thc hin th tc *) BEGIN (* Khi to bin ton cc Chuaxet *) For v V do Chuaxet[v]:=True; (* Duyt th *) For v V do If Chuaxet[v] Then DFS(v); END. Nh vy, vi thut toỏn trờn õy rừ rng mi lnh gi DFS(v) s thc hin duyt qua tt c cỏc nh cựng thnh phn liờn thụng vi nh v, bi vỡ sau mi khi xột nh v l lnh gi n th tc DFS i vi cỏc nh k vi v. Mt khỏc, do mi khi thm nh v xong, bin Chuaxet[v] c gỏn giỏ tr False nờn mi nh s c thm ỳng mt ln. Thut toỏn ln lt s tin hnh tỡm kim t cỏc nh cha c xột n, vỡ vy nú s duyt c qua tt c cỏc nh ca th. (K c th khụng liờn thụng). D phc tp tớnh toỏn ca thut toỏn c ỏnh giỏ nh sau: Trc ht ta thõy rng s phộp toỏn cn thc hin trong hai chu trỡnh ca thut toỏn (Hai vũng For chng trỡnh chinh) cú c l n. Cũn th tc DFS phi thc hin khụng quỏ m ln. Do ú tng s phộp toỏn cn thc hin trong cỏc th tc ny cú c l n+m. Vy phc tp tớnh toỏn ca thut toỏn l O(n+m). Vớ d 1: Xột th vụ hng cho bi hỡnh di õy (Hỡnh 3.1) Gi s danh sỏch k ca th c lu nh sau: 1: 2 3 4 2: 1 3 3: 1 2 5 8 4: 1 9 10 Hỡnh 3.1 Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 26 1 4 3 2 5 6 7 8 9 5: 3 8 6: 7 8 7: 6 8 8: 3 5 6 7 9: 4 10 10: 4 9 Khi đó thứ tự các đỉnh được duyệt theo thuật toán trên bắt đầu từ đỉnh 1 là: 1 2 3 5 8 6 7 4 9 10 Thuật toán tìm kiếm theo chiều sâu trên đồ thị có hướng cũng được thực hiện tương tự, trong trường hợp này thủ tục DFS(v) sẽ cho phép duyệt tất cả các đỉnh u của đồ thị mà từ v có đường đi tói u. Độ phức tạp tính toán của thuật toán trong trường hợp này vẫn là O(n+m). Ví dụ 2: Xét đồ thị có hướng cho bởi hình dưới đây (Hình 3.2) Giả sử danh sách các đỉnh kề của đồ thị được lưu như sau: 1: 3 2: 1 4 3: 4: 5 5: 7 8 6: 5 7: 2 9 8: 6 9: Khi đó thứ tự các đỉnh được duyệt theo thuật toán tìm kiếm theo chiều sâu bắt đầu từ đỉnh 1 là: 1 3 2 4 5 7 9 8 6 3.2 Thuật toán tìm kiếm theo chiều rộng trên đồ thị (Breadth First Search) Tư tưởng chính của phương pháp tìm kiếm theo chiều rộng trên đồ thị có thể được hiểu như sau: Ban đầu tất cả các đỉnh của đồ thị là chưa được xét đến, ta sẽ bắt đầu việc tìm kiếm từ một đỉnh nào đó của đồ thị, giả sử đỉnh đó là v 1 . Khi duyệt đỉnh v 1 ta sẽ để ý tới tất cả các đỉnh v 11 , v 12 , , v 1k Hình 3.2 Giáo án môn: Lý Thuyết Đồ Thị Nguyễn Minh Đức - ĐHQG Hà Nội 27 k vi nh v 1 m cha c xột n ngay sau ú ln lt xột ti cỏc nh ny, khi duyt nh v 1i (i=1,2, k) ta li ý ti tt c cỏc nh k vi nú m cha c xột n ri ln lt xột n cỏc nh ú. Qua trỡnh s c nh vy cho n khi no tt c cỏc nh ca th u c xột ht. Ta cú th hỡnh dung phng phỏp ny nh hỡnh nh ca vt du loang, t mt im trờn mt phng du s loang sang ngay cỏc im lõn cn vi im ú. Vi phng phỏp ny ta thy rng cỏc nh k vi mt nh ca th s c xp hng theo th t c ln lt xột ti, do ú chỳng ta cú th dựng c ch hng i thc hin cụng vic ny. Th tc mụ t phng phỏp ny nh sau Procedure BFS(v) (* tỡm kim theo chiu rng bt u t nh v *) (* Cỏc bin Chuaxet, Ke l ton cc *) Begin Queue : = Queue v; (* Np v vo Queue *) Chuaxet[v]:=False; While Queue do Begin p Queue; (* Ly p ra khi Queue *) Xet_dinh(p); For u Ke(p) do If Chuaxet[u] then Begin Queue u; Chuaxet[u]:=False; End; End; End; (* Chng trỡnh chớnh thc hin th tc *) BEGIN (* Khi to bin ton cc Chuaxet *) For v V do Chuaxet[v]:=True; (* Duyt cỏc nh *) For v V do If Chuaxet[v] then BFS(v); END. Vi thut toỏn ny ta cng thy rng mi lnh gi BFS(v) s thc hin duyt qua cỏc nh cựng thnh phn liờn thụng vi nh v. Th tc BFS s c thc hin ln lt vi cỏc nh cha c duyt ca th, do ú nú s duyt ht tt c cỏc nh ca th. Mt khỏc, mi khi duyt xong nh v, bin Chuaxet[v] cng c gỏn giỏ tr False nờn mi nh s c thm ỳng mt ln. Lp lun tng t thut toỏn tỡm kim theo chiu sõu ta cng cú c phc tp tớnh toỏn ca thut toỏn ny l O(n+m). Vớ d 3 Xột th vụ hng cho vớ d 1 (hỡnh 3.1) Khi ú th t cỏc nh c duyt theo thut toỏn tỡm kim theo chiu rng s l: 1 2 3 4 5 8 9 10 6 7 Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 28 Ví dụ 4 Xét đồ thị có hướng cho ở ví dụ 2 (Hình 2) Khi đó thứ tự các đỉnh được duyệt theo thuật toán tìm kiếm theo chiều rộng sẽ là: 1 3 2 4 5 7 8 9 6 Dưới đây là chương trình cài đặt hai thuật toán tìm kiếm theo chiều sâu và tìm kiếm theo chiều rộng bằng ngôn ngữ lập trình C. Chương trình xử lý trên đồ thị được cho bởi danh sách kề. // // huong trinh cai dat cac thuat toan tim kiem tren do thi // Depth First Search - Breadth First Search // #include<conio.h> #include<stdio.h> #include<stdlib.h> #define VMAX 100 //So dinh toi da cho mot do thi typedef struct pp //Cau truc tu tro { int v; struct pp *next; }Link; Link *Ke[VMAX]; //Danh sach ke cua do thi int chuaxet[VMAX]; //Bien mang dung de danh dau cac dinh da xet Link *Queue; //Hang doi luu thu tu cac dinh se xet int n; //So dinh cua do thi // // Ham nhap danh sach ke cua do thi co n dinh // void nhap_dsk(Link *Ke[], int n) { int i,v; Link *pd,*p; //Khoi tao mang cac danh sach cac dinh ke cua cac dinh for(i=1;i<=n;i++) { Ke[i] = (Link*)malloc(sizeof(Link)); Ke[i]->v=i; Ke[i]->next = NULL; } //Nhap danh sach cac dinh ke cua cac dinh for(i=1;i<=n;i++) { pd = NULL; printf("\nNhap cac dinh ke voi dinh %d (nhap 0 de ket thuc!):",i); while(1) { Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 29 scanf("%d",&v); if(v==0) break; if(pd == NULL) { pd = (Link*)malloc(sizeof(Link)); p=pd; } else { p->next = (Link*)malloc(sizeof(Link)); p=p->next; } p->v=v; p->next = NULL; } Ke[i]->next = pd; } } // // Ham hien thi danh sach ke cua do thi co n dinh // void in_dsk(Link *Ke[], int n) { int i; Link *pd; printf("\nDanh sach ke cua cac dinh cua do thi:\n"); printf("\n \n"); for(i=1;i<=n;i++) { printf("\n Danh sach cac dinh ke cua dinh %d:",Ke[i]->v); pd = Ke[i]->next; while(pd!=NULL) { printf("%5d",pd->v); pd=pd->next; } } } // // Ham nap mot phan tu (mot dinh ) vao hang doi // void Push(Link *u) { Link *q,*p; q=(Link*)malloc(sizeof(Link)); q->v=u->v; q->next=NULL; if(Queue==NULL) Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 30 Queue = q; else { p=Queue; while(p->next!=NULL) p=p->next; p->next = q; } } // // Ham lay mot phan tu trong hang doi ra // int Pop() { if(Queue==NULL) return 0; //Quee rong! Link *p; p=Queue; Queue=p->next; int t=p->v; free(p); //Giai phong p return t; } // // Ham de quy tim kiem theo chieu sau bat dau tu mot dinh // void dfs(Link *u) { printf("%3d",u->v); chuaxet[u->v]=0; Link *p = Ke[u->v]->next; while(p!=NULL) { if(chuaxet[p->v]) dfs(p); p=p->next; } } // // Ham tim kiem theo chieu rong bat dau tu mot dinh // void bfs(Link *u) { Queue=NULL; //Khoi tao hang doi Push(u); chuaxet[u->v]=0; while(Queue!=NULL) { int u; Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 31 u=Pop(); printf("%5d",u); Link *p=Ke[u]->next; while(p!=NULL) { if(chuaxet[p->v]) { Push(p); chuaxet[p->v]=0; } p=p->next; } } } // // Ham in tieu de cua chuong trinh // void tieu_de() { printf("\n CHUONG TRINH CAI DAT CAC THUAT TOAN TIM KIEM TREN DO THI"); printf("\n *** \n\n"); } // // Ham hien thi Menu chon chuc nang cua chuong trinh // char menu() { printf("\n Menu chon chu nang"); printf("\n *** \n"); printf("\n\n 1. Nhap do thi cho boi danh sach ke"); printf("\n\n 2. Hien thi danh sach ke cua do thi"); printf("\n\n 3. Tim kiem theo chieu sau tren do thi"); printf("\n\n 4. Tim kiem theo chieu rong tren do thi"); printf("\n\n 5. Ket thuc chuong trinh"); printf("\n\n "); printf("\n\n Ban chon:"); char ch=getche(); return ch; } // // Chuong trinh chinh // void main() { int kt=0,i; char ch; do { clrscr(); tieu_de(); Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 32 ch = menu(); switch(ch) { case '1': //Nhap danh sach ke cua do thi clrscr(); tieu_de(); kt=1; printf("\n\n1.Nhap danh sach ke cua do thi"); printf("\n \n\n"); printf("\n\nSo dinh cua do thi n ="); scanf("%d",&n); nhap_dsk(Ke,n); printf("\n\n\n\n "); printf("\nGo mot phim bat ky de tro ve menu chon chuc nang!"); getch(); break; case '2': //Hien thi danh sach ke cua do thi clrscr(); tieu_de(); printf("\n\n2.In danh sach ke cua do thi"); printf("\n \n\n"); if(kt) in_dsk(Ke,n); else printf("\nDo thi chua duoc nhap vao!"); printf("\n\n\n\n "); printf("\nGo mot phim bat ky de tro ve menu chon chuc nang!"); getch(); break; case '3': //Tim kiem theo chieu sau tren do thi clrscr(); tieu_de(); printf("\n\n3.Tim kiem theo chieu sau tren do thi"); printf("\n \n\n"); if(kt) { //Khoi toa bien chuaxet; for(i=1;i<=n;i++) chuaxet[i]=1; //Ket qua tim kiem theo chieu sau printf("\n\nThu tu cac dinh duoc xet theo chieu xau:\n\n"); for(i=1;i<=n;i++) if(chuaxet[i]) dfs(Ke[i]); } else printf("\nDo thi chua duoc nhap vao!"); printf("\n\n\n\n "); printf("\nGo mot phim bat ky de tro ve menu chon chuc nang!"); getch(); break; Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 33 case '4': //Tim kiem theo chieu rong tren do thi clrscr(); tieu_de(); printf("\n\n4.Tim kiem theo chieu rong tren do thi"); printf("\n "); if(kt) { //Khoi toa bien chuaxet; for(i=1;i<=n;i++) chuaxet[i]=1; //Ket qua tim kiem theo chieu rong printf("\n\nThu tu cac dinh duoc xet theo chieu rong:\n\n"); for(i=1;i<=n;i++) if(chuaxet[i]) bfs(Ke[i]); } else printf("\nDo thi chua duoc nhap vao!"); printf("\n\n\n\n "); printf("\nGo mot phim bat ky de tro ve menu chon chuc nang!"); getch(); break; case '5': //Ket thuc chuong trinh printf("\n\nXin cam on ban da su dung chuong trinh!"); getch(); break; } }while(ch!='5'); } 3.3 Ứng dụng của thuật toán tìm kiếm trên đồ thị Trong mục này chúng ta sẽ thực hiện ứng dụng hai thuật toán tìm kiếm trên đồ thị đã trình bầy ở trên vào việc giải hai bài toán cơ bản trên đồ thị là bài toán tìm một đường đi nối hai đỉnh bất kỳ của đồ thị và bài toán kiểm tra tính liên thông của đồ thị (xác định số thành phần liên thông của đồ thị). 3.3.1 Bài toán tìm đường đi giữa hai đính bất kỳ của đồ thị Bài toán Giả sử u và v là hai đỉnh nào đó của đồ thị G = (V,E), Hãy tìm đường đi từ đỉnh u tới đỉnh v. Như chúng ta đã biết hai thủ tục DFS(u) và BFS(u) sẽ cho phép duyệt qua tất cả các đỉnh thuộc cùng một thành phần liên thông với đỉnh u. Vì vậy sau khi thực hiện xong thủ tục mà biến Chuaxet[v] vẫn bằng True (đỉnh v chưa được duyệt) thì có nghĩa là không có đường đi từ u tới v, ngược lại nếu Chuaxet[v] = False thì v thuộc cùng một thành phần liên thông với u, hay tồn tại một đường đi từ u tới v. Trong trường hợp này, để ghi lại đường đi từ u tưới v ta có thể dùng một biến mảng Truoc[v] để lưu lại các đỉnh đi qua trước đỉnh v trong đường đi từ u tới v. Khi đó hai thủ tục DFS(u) và BFS(u) được sửa lại như sau: Thủ tục đệ quy tìm kiếm theo chiều sâu áp dụng cho việc tìm đường đi: [...]... cac dinh ke cua dinh %d:",Ke[i ]-> v); 37 Nguyễn Minh Đức - ĐHQG Hà Nội Giáo án môn: Lý Thuyết Đồ Thị pd = Ke[i ]-> next; while(pd!=NULL) { printf("%5d",pd->v); pd=pd->next; } } } // -/ / Ham nap mot phan tu (mot dinh ) vao hang doi // -void Push(int t) { Link *q,*p; q=(Link*)malloc(sizeof(Link)); q->v=t; q->next=NULL; if(Queue==NULL) Queue... hai dinh va kiem tra lien thong) // -void dfs(int u) { chuaxet[u]=sotplt; Link *p = Ke[u ]-> next; 38 Nguyễn Minh Đức - ĐHQG Hà Nội Giáo án môn: Lý Thuyết Đồ Thị while(p!=NULL) { if(chuaxet[p->v]==1) { sTruoc[p->v]=u; dfs(p->v); } p=p->next; } } // -/ / Ham tim kiem theo chieu rong bat dau tu mot dinh // ( Ap dung de tim duong... cỏch trờn, ng i cn tỡm s l: v t1 := Truoc[v] t 2 := Truoc[t1 ] u Vớ d 5 Xột th cho bi hỡnh di õy (Hỡnh 3. 3) 2 6 5 1 8 3 7 4 Hỡnh 3. 3 Nu ỏp dng tỡm ng i theo thut toỏn tỡm kim theo chiu sõu bt u t nh 1 ta s cú: 34 Nguyễn Minh Đức - ĐHQG Hà Nội Giáo án môn: Lý Thuyết Đồ Thị Truoc[2]=1, Truoc [3] =5, Truoc[4]=5, Truoc[5]=2, Truoc[6]=5, Truoc[7]=8, Truoc[8]=6 Vy ng i tỡm theo thut toỏn tỡm kim theo chiu... -/ / Ham nhap danh sach ke cua do thi co n dinh // -3 6 Nguyễn Minh Đức - ĐHQG Hà Nội Giáo án môn: Lý Thuyết Đồ Thị void nhap_dsk(Link *Ke[], int n) { int i,v; Link *pd,*p; //Khoi tao mang cac danh sach cac dinh ke cua cac dinh for(i=1;i v=i; Ke[i ]-> next = NULL; } //Nhap danh sach... } // -/ / Ham kiem tra tinh lien thong cua do thi // -void kiemtra_lt() { sotplt=1; for(int i=1;i v) thay cho dfs(Ke[i ]-> v) } if(sotplt==2) printf("\n\nDo thi... Queue = q; else { p=Queue; while(p->next!=NULL) p=p->next; p->next = q; } } // -/ / Ham lay mot phan tu trong hang doi ra // -int Pop() { if(Queue==NULL) return 0; //Quee rong! Link *p; p=Queue; Queue=p->next; int t=p->v; free(p); //Giai phong p return t; } // -/ / Ham de quy tim kiem theo chieu... "); printf("\nGo mot phim bat ky de tro ve menu chon chuc nang!"); getch(); 42 Nguyễn Minh Đức - ĐHQG Hà Nội Giáo án môn: Lý Thuyết Đồ Thị break; case '4': //Tim duong di - theo thuat tk chieu rong clrscr(); tieu_de(); printf("\n\n4.Tim duong di - theo thuat tk chieu rong"); printf("\n -\ n\n"); if(kt) { //Khoi toa bien chuaxet; for(i=1;inext = (Link*)malloc(sizeof(Link)); p=p->next; } p->v=v; p->next = NULL; } Ke[i ]-> next = pd; } } // -/ / Ham hien thi danh sach ke cua do thi co n dinh // -void in_dsk(Link *Ke[], int n) { int i; Link *pd; printf("\nDanh sach ke cua cac dinh cua... -/ / Ham hien thi Menu chon chuc nang cua chuong trinh // -char menu() { printf("\n Menu chon chu nang"); printf("\n -* ** -\ n"); printf("\n\n 1 Nhap do thi cho boi danh sach ke"); printf("\n\n 2 Hien thi danh sach ke cua do thi"); printf("\n\n 3 Tim duong di - theo thuat tk chieu sau"); printf("\n\n 4 Tim duong di - theo thuat tk chieu rong"); . cơ bản trên đồ thị là bài toán tìm một đường đi nối hai đỉnh bất kỳ của đồ thị và bài toán kiểm tra tính liên thông của đồ thị (xác định số thành phần liên thông của đồ thị) . 3. 3.1 Bài toán tìm. q->v=u->v; q->next=NULL; if(Queue==NULL) Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 30 Queue = q; else { p=Queue; while(p->next!=NULL) p=p->next;. 3. 1) Gi s danh sỏch k ca th c lu nh sau: 1: 2 3 4 2: 1 3 3: 1 2 5 8 4: 1 9 10 Hỡnh 3. 1 Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 26 1 4 3 2 5 6 7 8 9 5: