Trong hai bài trước, ta đã tìm hiểu được khái quát và việc thêm một phần tử vào trong danh sách liên kết đôi. Việc thêm phần tử vào danh sách liên kết đôi ở bài trước chỉ dừng lại ở việc gọi hàm voi ThemDau() hoặc voi ThemCuoi(). Tuy nhiên, vấn đề ở đây ta mong muốn lấy được dữ liệu của node vừa được thêm vào danh sách liên kết đôi vì vậy ta cần đi xây dựng các hàm để nhập xuất danh sách liên kết đôi.
1.Nhập N phần tử vào danh sách liên kết đôi
Để xây dựng được hàm nhập N phần tử vào trong danh sách liên kết đôi, ta cần hiểu được những hàm sau đây:
- Hàm tạo một node trong danh sách liên kết
- Các hàm void ThemDau() hoặc void ThemCuoi() ở bài trước.
Nếu như bạn đã từng học về danh sách liên kết đơn thì việc nhập N phần tử vào danh sách liên kết đơn cũng giống như nhập N phần tử vào danh sách liên kết đôi, tuy nhiên ở đây tôi sẽ xây dựng lại nhanh hàm nhập cho danh sách liên kết đôi để phục vụ những bài sau này:
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 x: "); 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 dau hoac them cuoi va truyen vao node p vua tao ThemDau(ds,p); //ThemCuoi(ds,p) } }
2.Xuất dữ liệu của các node có trong danh sách liên kết đôi
Như đã đề cập ở phần đầu của bài viết, khi sử dụng các hàm void ThemDau() hoặc void ThemCuoi() ở bài trước ta vẫn chưa hiển thị được các giá trị của node đó ra màn hình để phục vụ việc kiểm tra, tìm kiếm, sắp xếp….
Để thực xây đựng được hàm xuất dữ liệu của các node có trong danh sách ta có thể dùng vòng lặp for hoặc vòng lặp while để duyệt qua các node có trong danh sách liên kết đôi đó. Hàm xuất này cũng giống hàm xuất của danh sách liên kết đơn.
Hàm xuất sử dụng vòng lặp for
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); } }
Hàm xuất sử dụng vòng lặp while
void Xuat(DLIST ds){ //tao node p NODE *p; p = ds.pHead; //trong khi node p chua bang NULL (p chua la phan tu cuoi) while (p!=NULL){ //hien thi du lieu printf("%d\n",p->data); //chuyen sang node tiep theo p=p->next; } }
3.Chương trình nhập xuất trong danh sách liên kết đôi hoàn chỉnh
Chương trình dưới đây tôi sẽ nhập 5 phần tử là: 11,22,33,44,55 vào danh sách liên kết đôi theo thứ tự chèn mỗi phần tử sau vào cuối danh sách.
#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 ThemDau(DLIST &ds, NODE *p) { //neu danh sach rong thi them vao node dau va cuoi if (ds.pHead == NULL){ ds.pHead = ds.pTail = p; }else { //dat con tro next cua node can them toi node dau danh sach p->next = ds.pHead; //dat con tro prev cua node dau ve node p ds.pHead->prev = p; //gan lai node dau cua danh sach bang node p ds.pHead = 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); } } 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 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 |
Chương trình trên trong khi sử dụng hàm nhập là void Nhap() ta gọi hàm void ThemCuoi() nên các phần tử được nhập vào danh sách sau khi gọi hàm xuất sẽ hiển thị ra màn hình: 11,22,33,44,55
Tuy nhiên, nếu ta gọi gàm void ThemDau() để nhập vào danh sách thì sẽ nhận được kết quả sau khi gọi hàm xuất đó là: 55,44,33,22,11