Danh sách liên kết đơi (Doubly Linked List) • Là danh sách mà mỗi phần tử có mối liên kết: – Next: để kết nối với phần tử kế tiếp – Prev: để kết nối với phần tử trước no head pos rear Cài đặt DSLK đơi • Cài đặt: dựa trỏ, bao gờm: • trỏ: head (đầu ds), pos (phần tử hiêên hành), và rear (ći ds) • biến count: sớ phần tử của danh sách typedef struct nodet { elem data; next struct nodet *next, *prev; } node; data typedef node *nodeptr; prev pos head typedef struct { rear nodeptr head, pos, rear; int count; } list; Các thao tác danh sách liên kết đơi • Tương tự danh sách liên kết đơn ngoại trừ thao tác (cục bộ) làm thay đổi liên kết: – Chèn phần tử vào danh sách – Xóa phần tử danh sách liên kết • Bổ sung thêm một số thao tác như: – Khởi đầu từ cuối danh sách – Di chuyển qua phần tử trước phần tử hiện hành Chèn phần tử x vào danh sách p q head rear ewp • Chèn đầu danh sách (xét theo chiều xuôi): – q = head – newp->next = q – head = newp Chèn phần tử x vào danh sách p head q rear • Chèn sau p (xét theo chiều xi): newp – q = p->next – newp->next=q – p->next = newp Giải thuật chèn Cấp phát bộ nhớ cho newp, gán dữ liệu Xác định trỏ q=(p==NULL? head:p->next) Kết nối xuôi 3.1 newp→ next = q; 3.2 Nếu p=NULL thi head = newp 3.3 Ngược lại p→ next = newp Kết nối ngược 4.1 newp→ prev = p; 4.2 Nếu q=NULL thi rear = newp 4.3 Ngược lại q→ prev = newp Tăng biến count Hàm chèn phần tử vào danh sách void insertlist(list &l, elem &x, nodeptr p) { nodeptr newp, q; newp = new node; memcpy(&newp->data, &x, sizeof(elem)); q = (p==NULL? l.head: p->next); newp->next = q; if (p==NULL) l.head = newp; else p->next = newp; newp->prev = p; if (q==NULL) l.rear = newp; else q->prev = newp; l.count++; } Hàm xóa phần tử trongdanh sách void deletelist(list &l, nodeptr p) { nodeptr t, q; t = (p==NULL? l.head: p->next); q = t->next; if (p==NULL) l.head = q; else p->next = q; if (q==NULL) l.rear = p; else q->prev = p; delete t; l.count ; } Bở sung hàm • Khởi đầu tử cuối danh sách void startend(list &l) { l.pos = l.rear; } • Di chuyển đến phần tử trước phần tử hiện hành void skipbefore(list &l) { if (l.pos == NULL) l.pos = l.rear; else l.pos = l.pos->prev; } • Thiết kế kiểu số nguyên lớn với các phép toán: cộng, nhân Áp dụng tính 100!, 7100 • • 349093429 675432 ... tác danh sách liên kết đơi • Tương tự danh sách liên kết đơn ngoại trừ thao tác (cục bộ) làm thay đổi liên kết: – Chèn phần tử vào danh sách – Xóa phần tử danh sách liên. ..• Là danh sách mà mỗi phần tử có mối liên kết: – Next: để kết nối với phần tử kế tiếp – Prev: để kết nối với phần tử trước no head pos rear Cài đặt DSLK đôi • Cài... tác như: – Khởi đầu từ cuối danh sách – Di chuyển qua phần tử trước phần tử hiện hành Chèn phần tử x vào danh sách p q head rear ewp • Chèn đầu danh sách (xét theo chiều xi):