数据结构与算法(七)--双向链表

双向链表

如何求链表中p结点的直接前驱,其时间性能如何?

从当前结点循环遍历判断p结点的直接前驱,时间复杂度为O(n)。

通过p->next可以直接访问p结点的后继结点,时间复杂度为O(1)。

如何快速获取p结点的前驱结点?

通过结点添加指针域指向前驱结点。

双链表:在单链表的每个结点中在设置一个指针域,指向其前驱结点.

data:存放数据元素;  next:存放该节点后继结点地址;  prior:存储该节点前驱结点地址。

双向链表定义节点结构:

typedef strcut DuLNode{
    ElemType data;            //数据域
    struct PuLNode *prior;    //指向前驱结点的指针
    struct PuLNode *next;     //指向后继结点的指针
}DuLNode, *DuLinkList;

双向链表的插入操作:

s结点的前驱指针指向p结点,p结点原来的后继指针重新指向s的前驱指针域,原来的后继指向赋给s的后继指针域。

s->prior = p;      s->next->prior=s; //s->next原来为a[i]结点,a[i]结点的prior指针域指向s结点     

s->next = p->next;   //指针域重新赋值

双向链表插入操作: 在第i个位置后插入结点e

bool ListInsert_DuL(DuLinkList &L , int i, ElemType e){
    if(!(p = GetElem_DuL(L,i))))     //查找第i个元素的结点吗,操作和单链表一样
        return false;
    s = (List)malloc(sizeof(DuLNode));      //分配新节点s内存空间
    s->data = e;
    s->next = p->next;
    p->next->prior  = s;
    p->next = s;
    return true; 
}

删除第i个节点的操作:

Demo:

bool ListDelete_Dul(DuLinkList &L, int i, ElemType e){
    p->prior->next = p->next;    //第一步
    p->next->prior = p->prior;   //第二步
    free(p);        //释放p结点的内存空间
    return true;
}

虽然双向链表的运算执行效率较高,但是每个结点都需要占用额外的一个指针域,空间复杂度翻倍。

发布了58 篇原创文章 · 获赞 31 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_37504771/article/details/104909696