首页 > 编程笔记 > C++笔记 阅读:38

C++双向链表的基本操作(图文并茂,附带实例)

在单链表中,每个节点都被附加了一个指针域,指向下一个节点。在单链表中只能向后操作,不能向前操作。

为了向前、向后操作方便,可以给每个节点都附加两个指针域,一个指针域存储上一个节点的地址,另一个指针域存储下一个节点的地址。这种链表被称为“双向链表”,如下图所示:


从上图可以看出,双向链表的每个节点都包含三个域:数据域和两个指针域。两个指针域分别存储上一个和下一个节点的地址,即指向前驱和后继。

双向链表的节点结构体定义如下图所示:

双向链表插入节点

单链表只有一个指针域,是向后操作的,不能向前操作,因此若要在单链表的节点 i 之前插入一个元素,则必须先找到节点 i-1。在节点 i 之前插入一个元素相当于把新节点放在节点 i-1 之后。

而双向链表因为有两个指针,可以向前、后两个方向操作,所以可以直接找到节点 i,把新节点插入节点 i 之前。

注意,这里假设节点 i 是存在的,若节点 i 不存在,而节点 i-1 存在,则还需要找到节点 i-1,将新节点揑入节点 i-1 之后,如下图所示:


其中:
因为 p 的前驱无标记,一旦修改了 p 的 prior 指针,p 的前驱就找不到了,所以最后修改这个指针。修改指针顺序的原则:先修改没有指针标记的那一端。

算法代码:
bool ListInsert_L(DuLinkList &L, int i, int e) { // 在第 i 个位置之前插入元素 e
    DuLinkList p = L, s;
    int j = 0;
    while (p && j < i) { // 查找节点 i,p 指向该节点
        p = p->next;
        j++;
    }
    if (!p || j > i) // i > n+1 或者 i < 1
        return false;
    s = new DuLNode;   // 生成新节点
    s->data = e;       // 将新节点的数据域置为元素 e
    p->prior->next = s;
    s->prior = p->prior;
    s->next = p;
    p->prior = s;
    return true;
}

双向链表删除节点

删除一个节点,实际上就是跳过这个节点。在单链表中必须先找到节点 i-1,才能把节点 i 跳过去。在双向链表中则不必如此,直接找到节点 i,之后修改指针即可,如下图所示:



这样就跳过了节点 p。之后用 delete p 释放被删除节点占用的内存空间。在删除节点时,修改指针没有顺序,先修改哪个指针都可以。

算法代码:
bool ListDelete_L(DuLinkList &L, int i) { // 删除第 i 个元素
    DuLinkList p = L;
    int j = 0;
    while (p && j < i) { // 查找节点 i,p 指向该节点
        p = p->next;
        j++;
    }
    if (!p || j > i) // 当 i > n 或 i < 1 时,删除位置不合理
        return false;
    if (p->next) // 若 p 的后继存在
        p->next->prior = p->prior;
    p->prior->next = p->next;
    delete p;    // 释放被删除节点占用的内存空间
    return true;
}

相关文章