数据结构-非循环双链表

179 阅读2分钟

非循环双链表

结点(d_node)结构

struct d_node {
    int data;
    d_node *prior, *next;
};

双链表一个结点由两个指针元素prior和next,以及一个数据元素data构成。data用于存放结点d_node的数据,prior用于指向链表中上一个结点的地址,next用于指向链表下一个结点的地址,多个结点构成了双向的链表,即双链表。

结点(d_node)与单链表(node)结点的不同

最大的不同在于添加了一个指针元素prior,用于指向链表中前一个结点的地址。

这种结点结构相较于单链表,在某些情况下能够省去很多不必要的麻烦(比如删除一个指定结点,或者是寻找某个结点的上一个结点的地址等)。

尾插法创建非循环双链表

d_node *newDoubleList_Tail() {
    int x;
    d_node *l = new d_node;
    d_node *s, *r = l;
    cin >> x;
    while (x != 9999) {
        s = new d_node;
        s->data = x;
        r->next = s;
        s->prior = r;
        r = s;
        cin >> x;
    }
    r->next = NULL;
    return l;
}

输入数据元素,当输入9999时停止输入并生成返回双链表表头的地址。

尾插法创建双链表基本与创建单链表一致,只是在每次循环添加结点时要将当前结点的prior指针指向上一个结点。

增删改查操作

增删改查基本与单链表的思路一致,注意prior指针的操作即可。

涉及到删除某结点时,直接让该结点prior指针指向的结点的next指针指向当前结点的next,并释放掉当前结点的内存空间,即

//设指向当前结点的指针为s,前一个结点为r
    r=s->prior;
    r->next=s->next;
    delete(s);

遍历双链表和求双链表的表长

//遍历双链表
void display(d_node *&l) {
    d_node *s = l->next;
    while (s != NULL && s != l) {
        cout << s->data << " ";
        s = s->next;
    }
    if (s == NULL) cout << "双链表" << endl;
    if (s == l) cout << "循环双链表" << endl;
}
//求双链表表长
int length(d_node *&l) {
    int n = 0;
    d_node *s = l->next;
    while (s != NULL && s != l) {
        n++;
        s = s->next;
    }
    return n;
}

(和单链表操作完全一致)