Chương II. NỘI DUNG NGHIÊN CỨU
C. Tìm kiếm danh sách sinh viên
I.Lý thuyết và ví dụ cho tìm kiếm phần tử trong danh sách liên kết kép
1. Cách tìm kiếm một phần tử trong danh sách liên kết đôi
Để thực hiện việc tìm kiếm trong danh sách liên kết kép ta cần thực hiện các bước sau :
Bước 1: Tạo Node p và gán bằng đầu danh sách: p=pHead
Bước 2: Sử dụng vòng lặp while (p!= NULL) và (p->data != x)
o Thực hiện p = p->next; // p trỏ tới phần tử kế tiếp
Bước 3: Kiểm tra kết quả sau khi thực hiện vòng lặp ở Bước 2
o Nếu p==NULL không có phần tử cần tìm;
o Ngược lại: nếu p != NULL thì trỏ đến phần tử cần tìm
2. Hàm tìm kiếm một phần tử trong danh sách liên kết đôi
Phần code ví dụ : NODE* TimKiem(DLIST ds, int x){ //tao node p NODE *p; //gan p bang phan tu dau danh sach p = ds.pHead;//su dung vong lap
while ((p!=NULL) && (p->data!=x)){
p=p->next;
} //tra ve ket qua, neu NULL thi khong tim thay return p;
} Hàm tìm kiếm trên có kiểu trả về là NODE và truyền vào danh sách cần tìm kiếm và khóa int x để tìm kiếm trong danh sách đó .
Chú ý : Hàm trên dù có tìm thấy kết quả hay không thì đều trả về một node p. Nếu p = NULL thì ta kết luận không tìm thấy , và nếu tìm thấy kết quả thì p !=NULL và ta nhận được kết quả chính là node p.
3.Chương trình tìm kiếm một phần tử trong danh sách liên kết đôi
Trước khi sử dụng hàm tìm khiếm ,ta cần đảm bảo rằng đã có các phần tử nằm trong danh sách tìm kiếm , vì thế ta sẽ nhập các phần tử vào danh sách trước sau mới gọi là hàm tìm kiếm.
Chương trình code :
#include <stdio.h>
#include <stdlib.h>
struct Node { //khai bao thanh phan du lieu co kieu int int data; //khai bao con tro next co kieu Node de chua dia chi phan tu sau Node *next; //khai bao con tro prev co kieu Node de chua dia chi phan tu truoc Node *prev; };
typedef struct Node NODE;
struct doulist{ //thanh phan dau danh sach NODE *pHead; //thanh phan cuoi danh sach
NODE *pTail; };
typedef struct doulist DLIST;
void KhoiTao(DLIST &ds){ //dat dia chi dau danh sach bang NULL ds.pHead = NULL; //dat dia chi cuoi danh sach bang NULL
ds.pTail = NULL; } NODE* TaoNode(int x) { //tao mot node p moi NODE *p;
p = new NODE; //neu p==NULL thi khong du bo nho va ket thuc viec tao node if (p==NULL) {
printf ("KHONG DU BO NHO");
return NULL;
} //gan thanh phan data = x p->data=x;//gan con tro next = NULL p->next=NULL;//gan con tro prev = NULL p->prev = NULL;//tra ve node p da tao return p; }
void ThemCuoi(DLIST &ds, NODE*p){
//kiem tra danh sach rong neu rong thi them vao dau va cuoi if (ds.pHead == NULL){
ds.pHead = ds.pTail = p;
}else{ //dat con tro next cua pTail hien tai vao p la node can them cuoi ds.pTail->next = p; //dat con tro prev cua node p ve phan tu cuoi danh sach p->prev = ds.pTail; //thay doi lai phan tu cuoi danh sach
ds.pTail = p;
} } void Nhap(DLIST &ds, int n){ //duyet N lan for(int i = 0; i < n; i++){ //nhap du lieu la so nguyen int x int x;
printf("Nhap vao so %d: ",i);
scanf("%d",&x);
//tao node p NODE *p = new NODE;
//dua du lieu vua nhap vao node p p = TaoNode(x);
//dua node p vao ham them cuoi va truyen vao node p vua tao ThemCuoi(ds,p);
} } void Xuat(DLIST ds){
//khoi tao mot node NODE *p = new NODE;
//duyet tu dau danh sach den cuoi danh sach voi dieu kien p!=NULL for(p = ds.pHead; p!= NULL; p=p->next){
//hien thi du lieu cua tung node printf("%d\n",p->data);
} } NODE* TimKiem(DLIST ds, int x){
//tao node p NODE *p;
//gan p bang phan tu dau danh sach p = ds.pHead;
//su dung vong lap while ((p!=NULL) && (p->data!=x)){
p=p->next;
} //tra ve ket qua, neu NULL thi khong tim thay return p;
} int main(){
//khai bao mot danh sach lien ket doi DLIST ds;
//nhap n phan tu int n;
printf("NHAP N: ");
scanf("%d",&n);
//khoi tao danh sach KhoiTao(ds);
//goi ham nhap tryuyen vao danh sach va N phan tu Nhap(ds,n);
//goi ham xuat cac du lieu co trong danh sach printf("DANH SACH VUA NHAP\n");
Xuat(ds);
//nhap gia tri can tim kiem int x;
printf("NHAP GIA TRI CAN TIM KIEM: ");
scanf("%d",&x);
//goi ham tim kiem truyen vao gia tri x va gan vao node p NODE *p = TimKiem(ds,x);
//kiem tra ket qua tim kiem if(p == NULL){
printf("\nKHONG TIM THAY KET QUA");
}else{
printf("\nTIM THAY KET QUA: ");
printf("%d",p->data);
} } Ví dụ cho chương trình và kết quả:
NHAP N: 5
Nhap vao so 0: 11 Nhap vao so 1: 22 Nhap vao so 2: 33 Nhap vao so 3: 44 Nhap vao so 4: 55 DANH SACH VUA NHAP 11 22 33 44 55
NHAP GIA TRI CAN TIM KIEM: 44 TIM THAY KET QUA: 44
Sau khi gọi NODE TimKiem() và gán vào NODE p ta sẽ kiểm tra điều kiện nếu p == NULL thì không tìm thấy kết quả. Ngược lại thì p!= NULL nghĩa là tìm thấy kết quả trong danh sách với khóa X cần tìm.
II. Áp dụng tìm kiếm phần tử trong danh sách liên kết kép vào đề tài
Tìm kiếm một sinh viên trên danh sách liên kết kép theo mã sinh viên: Ta cần duyệt danh sách từ đầu đến cuối và so sánh mã sinh viên của mỗi nút với mã sinh viên nhập vào.
+ Nếu tìm thấy, trả về con trỏ đến nút đó.
+Nếu không tìm thấy, trả về NULL.
Thuật toán:
Node *search(string maSV) { // tìm kiếm một sinh viên trên danh sách theo mã sinh viên Node *p = head;
// con trỏ để duyệt danh sách while (p != NULL) { // duyệt đến khi hết danh sách hoặc tìm thấy if (p->data->maSV == maSV) {
// nếu mã sinh viên của nút hiện tại trùng với mã sinh viên nhập vào, trả về con trỏ đến nút đó
return p; } p = p->next; // di chuyển con trỏ đến nút tiếp theo } // nếu duyệt hết danh sách mà không tìm thấy, trả về NULL return NULL;}