Danh sách liên kết đôi Doubly Linked List... typedef struct {nodeptr head, pos, rear; int count; } list; rear... Tăng biến count.
Trang 1Danh sách liên kết đôi (Doubly Linked List)
Trang 2• Là danh sách mà mỗi phần tử có 2 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 nó
rear
Trang 3Cài đặt DSLK đôi
• Cài đặt: dựa trên con trỏ, bao gồm:
• 3 con trỏ: head (đầu ds), pos (phần tử hiện hành), và rear (cuối ds)
• biến count: số phần tử của danh sách
typedef struct nodet {
elem data;
struct nodet *next, * prev ; } node;
typedef node *nodeptr;
data
prev next
Trang 4typedef struct {
nodeptr head, pos, rear;
int count;
} list;
rear
Trang 5Các thao tác trên danh sách liên kết đôi
• Tương tự như danh sách liên kết đơn ngoại trừ
2 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ử trong 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
Trang 6Chèn phần tử x vào danh sách
• Chèn đầu danh sách (xét theo chiều xuôi):
– q = head
– newp->next = q
– head = newp
rear
head
newp
Trang 7Chèn phần tử x vào danh sách
• Chèn sau p (xét theo chiều xuôi):
– q = p->next
– newp->next=q
– p->next = newp
newp
rear
Trang 8Giải thuật chèn
1. Cấp phát bộ nhớ cho newp, gán dữ liệu
2. Xác định con trỏ q=(p==NULL? head:p->next)
3 Kết nối xuôi
3.2 Nếu p=NULL thì
head = newp 3.3 Ngược lại
4 Kết nối ngược
4.2 Nếu q=NULL thì
rear = newp 4.3 Ngược lại
5 Tăng biến count
Trang 9Hà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++;
Trang 10Hà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 ;
}
Trang 11Bổ sung 2 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;
Trang 12• 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