数据结构重学日记(九)双链表

概念

单链表:单个指针,单向火车。

双链表:双指针,电梯。

双链表在单链表的基础上增加了一个指向前边结点的指针。

实现


typedef struct DNode{
    ElemType data;
    struct DNode * prve, *next;  // 前驱和后继指针
}DNode,* DLinkList; 

插入

假设有 到 个数据元素组成的双链表,要把 插入到 和 之间,那么设指向 的指针 p 和指向 的指针 s :

s->next = p->next
p->next->prev = s
s->prev = p
p->next = s

删除

还是 到 等数据元素组成的双链表,要删除 ,设指向 的指针 p 和指向 的指针 q:

p->next = q->next
q->next->prev = p
free(q)

这种做法就是典型的用空间换时间。

双链表头插法


DLinkList header_insert(DLinkList DL) {
    DLinkList s ;
    int x;
    DL = (DLinkList)malloc(sizeof(DNode));
    DL->next = NULL;
    DL->prev = NULL;

    scanf("%d", &x);

    while (x != 999) {
        s = (DLinkList) malloc(sizeof(DNode));
        s->data = x;
        s->next = DL->next;
        if (DL->next) {
            DL->next->prev = s;
        }
        s->prev = DL;
        DL->next = s;
        scanf("%d", &x);
    }
    return DL;

}

双链表尾插法


DLinkList last_insert(DLinkList DL) {
    DL = (DLinkList)malloc(sizeof(DNode));

    DLinkList s, r = DL;
    int x;
    DL->prev = NULL;

    scanf("%d", &x);

    while (x != 999) {
        s = (DLinkList) malloc(sizeof(DNode));
        s->data = x;
        r->next = s;
        s->prev = r;
        r = s;
        scanf("%d",&x);
    }
    r->next = NULL;
    return DL;
}

第一遍看时,对于最后一步把 r->next 置为 null 有点不理解,然后又回过头去看了看之前的视频,发现说是这样清空后可以更安全,但是经过 debug,发现这里执不执行置空都是一样的效果:

数据结构重学日记(九)双链表_第1张图片
置空
数据结构重学日记(九)双链表_第2张图片
不置空

希望有大神来指点迷津,到底为什么安全,安全在哪儿?

按位插入


bool insert_elem(DLinkList DL, int i, ElemType e) {
    DLinkList p = search_elem_by_num(DL, i - 1);
    if (p == NULL) return false;
    DLinkList s = (DLinkList) malloc(sizeof(DNode));
    s->data = e;
    s->next = p->next;
    s->prev = p;
    p->next = s;
    p->next->prev = s;
    return true;
}

按序号查找

和之前的代码是一样的。


DLinkList search_elem_by_num(DLinkList DL, int i){
    DLinkList p = DL->next;
    int j = 1;
    if(i ==0 ) return DL;
    if(i < 1) return NULL;

    while (p && j < i){
        p = p->next;
        j++;
    }
    return p;
}

删除


bool delete_elem(DLinkList DL, int i){
    DLinkList p = search_elem_by_num(DL,i -1);
    if(!p) return false;

    DLinkList  q = p->next;
    if(!p->next) return false;

    p->next = q->next;
    if(q->next){
        q->next->prev = p;
    }
    free(q);
    return true;
}

各个方法在 main 中调用即可,不再赘述。

你可能感兴趣的:(数据结构重学日记(九)双链表)