Với yêu cầu nhập số N từ bàn phím chính là số lượng phần tử trong danh sách liên kết đơn. Để thực hiện được công việc nhập này bạn đọc hay đảm bảo rằng đã hiểu được các cách thêm phần tử vào đầu danh sách là hàm void ChenDau() và thêm phần tử vào cuối danh sách là hàm void ChenCuoi().
1.Nhập N phần tử vào danh sách liên kết đơn
Hàm void Nhap(LIST &ds, int n) dưới đây nhận LIST &ds làm danh sách cần được nhập phần từ và int n là số lượng phần tử cần thêm vào danh sách. Hàm này có chức năng tạo ra một Node p mới và nhận giá trị int x đưa vào Node p sau đó truyền vào hàm ChenDau() để thực hiện chèn vào đầu danh sách:
void Nhap(LIST &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 chen dau ChenDau(ds,p); } }
Chú ý:
- Các hàm TaoNode(), ChenDau() đã được nêu ra ở những bài trước vì thế nếu quên, bạn đọc vui lòng xem lại.
- Ví dụ trên thực hiện cho danh sách liên kết đơn lưu trữ dữ liệu kiểu số nguyên nên ta sử dụng int x, tùy vào trường hợp khác nhau mà ta sẽ sử dụng kiểu dữu liệu khác nhau như float, char….hay kiểu dữ liệu struct SinhVien mà ta tự định nghĩa!
Tương tự như chèn vào đầu danh sách, ta cũng có thể áp dụng hàm trên cho chèn cuối vào danh sách bằng cách thay đổi hàm:
ChenDau(ds,p);
Bằng hàm:
ChenCuoi(ds,p);
Chi tiết hàm nhập vào phần tử vào cuối danh sách liên kết đơn:
void Nhap(LIST &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 chen cuoi ChenCuoi(ds,p); } }
2.Xuất dữ liệu từ các node có trong danh sách liên kết đơn
Hàm void Xuat(LIST ds) dưới đây nhận LIST ds làm danh sách cần được duyệt qua tất cả phần tử. Hàm này có chức năng duyệt từ phần tử đầu tiên (ds.pHead) đến phần tử cuối cùng (ds.pTail) trong danh sách liên kết đơn. Có 2 cách để duyệt tất các các node trong danh sách liên kết đơn:
Cách 1: Duyệt bằng vòng lặp for
void Xuat(LIST 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); } }
Cách 2: Duyệt bằng vòng lặp while
void Xuat(LIST 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; } }
Chú ý:
- Ở trong vòng lặp for, tôi sử dụng p!= NULL nghĩa là điều kiện duyệt các phần tử chưa chạm đến phần NULL của danh sách (phần null là địa chỉ cuối của danh sách)
- p->data chính là việc lấy dữ liệu mà ta đã nhập vào các node có trong danh sách
3.Chương trình nhập xuất trong danh sách liên kết đơn hoàn chỉnh
#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 Node *next; }; typedef struct Node NODE; struct list{ //thanh phan dau danh sach NODE *pHead; //thanh phan cuoi danh sach NODE *pTail; }; typedef struct list LIST; void KhoiTao(LIST &ds){ //dat dia chi dau danh sach bang NULL ds.pHead = NULL; //dat dia chi cuoi danh sach bang NULL ds.pTail = NULL; } int KiemTraRong(LIST ds){ //neu phan tu dau danh sach NULL if (ds.pHead == NULL){ //tra ve 1 la co NULL return 1; } //truong hop nguoc lai tra ve khong null return 0; } NODE* TaoNode(int x) { //tao mot node p moi NODE *p; p = new NODE; //neu p==NULL thi khong du bo nho 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; //tra ve node p da tao return p; } void ChenDau(LIST &ds, NODE *p) { //neu phan tu dau rong thi danh sach rong if (ds.pHead==NULL){ //chen dau va cuoi deu bang node p ds.pHead = p; ds.pTail = p; } //nguoc lai danh sach khong rong else { //gan con tro next cua node p bang phan tu dang la dau tien cua danh sach p->next = ds.pHead; //gan pHead bang node p ds.pHead = p; } } void ChenCuoi (LIST &ds, NODE *p){ //neu phan tu dau rong thi danh sach rong if (ds.pHead==NULL) { //chen dau va cuoi deu bang node p ds.pHead=p; ds.pTail=p; } //nguoc lai danh sach khong rong else { //gan con tro cua phan tu cuoi trong danh sach bang node p ds.pTail->next=p; //gan pTail bang node p ds.pTail=p; } } void Nhap(LIST &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 chen cuoi ChenCuoi(ds,p); } } void Xuat(LIST 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 LIST ds; //nhap so luong N tu ban phim int n; printf("Nhap N: "); scanf("%d",&n); //khoi tao danh sach KhoiTao(ds); //goi ham nhap va truyen danh sach va so luong N vao Nhap(ds,n); //goi ham xuat du lieu printf("\nDU LIEU TRONG DANH SACH LIEN KET DON\n"); Xuat(ds); }
Nhap N: 5
Nhap vao so x: 11 Nhap vao so x: 22 Nhap vao so x: 33 Nhap vao so x: 44 Nhap vao so x: 55 DU LIEU TRONG DANH SACH LIEN KET DON 11 22 33 44 55 |
Ở chương trình trên, trong hàm void Nhap(LIST &ds, int n) tôi sử dụng nhập node vào danh sách liên kết đơn theo cách chèn cuối vì vậy tôi gọi hàm void ChenCuoi(ds,p) và nhận được kết quả khi xuất dữ liệu ra màn hình theo thứ tự là: 11 22 33 44 55
Nếu tôi sử dụng hàm void ChenDau(ds,p) thay thế thì kết quả nhận được khi xuất dữ liệu ra màn hình sẽ theo thứ tự là: 55 44 33 22 11