数据结构(三):线性表的链式存储结构 - 双链表的实现

双链表的特点

双链表中的每个节点有两个指针域, 一个指向其后继节点,另一个指向其前驱节点。
所以相对单链表来说,在双链表中访问一个节点的前后的节点更为方便

双链表的节点类型

对于双链表,采用类似于单链表的节点类型定义

//模板节点类型
template <typename T>
struct DLinkList
{
    T data;
    DLinkList<T> *prior;    //前驱指针 
    DLinkList<T> *next;
 }; 

双链表的基本运算方法

在双链表中,有些运算(如求长度、去元素、查找元素等算法)与单链表的相应算法是相同的。
不同的是, 在单链表中进行插入删除时涉及前后节点的一个指针域的变化。
而在双链表中,结点的插入和删除操作涉及前后结点的两个指针域的变化。

 //双链表类模板 
 template <typename T>
 class DLinkListClass
 {
    DLinkList<T>* dhead;        //双链表表头指针

public:
    DLinkListClass<T>();    //构造函数, 创建一个空栓链表
    ~DLinkListClass<T>();  //析构函数,销毁双链表
    void CreateListF(T a[], int n); //头插法建表
    void CreateListR(T a[], int n); //尾插法建表 
    bool ListInsert(int i , T e);   //插入数据元素
    bool ListDelete(int i);         //删除数据元素 
    void DispList();                //遍历显示链表 

public: //友元函数 
    template<typename A>
    friend bool Delnode(DLinkListClass<A> &L);  //删除第一个值为x的节点 

    template<typename A>
    friend bool Delmaxnode(DLinkListClass<A> &L);   //删除第一个值最大的节点 
  }; 

实现代码


template<typename A>
bool Delnode(DLinkListClass<A> &L)  //删除第一个值为x的节点 
{
    DLinkList<A> *p= L.dhead->next, *pre;
    while(p != NULL)
        p= p->next;
    if(p == NULL) return false;
    else
    {
        pre = p->prior;
        if(p->next != NULL)
            p->next->prior = pre;
        pre->next = p->next;
        delete p;
        return true;
    }
}

template<typename A>
bool Delmaxnode(DLinkListClass<A> &L)   //删除第一个值最大的节点 
{
    DLinkList<A> *p = L.dhead->next, *maxp = p, *pre;
    while(p != NULL)
    {
        if(p->data > maxp->data)
            maxp = p;
        p = p->next;
     } 
     pre = maxp->prior;
     if(maxp->next != NULL)
        maxp->next->prior = pre;
    pre->next = maxp->next;
    delete maxp;
}

//构造函数 
template<typename T>
DLinkListClass<T>::DLinkListClass()
{
    dhead = new DLinkList<T>();
    dhead->next = NULL;
    dhead->prior = NULL;
}

//析构函数 
template<typename T>
DLinkListClass<T>::~DLinkListClass<T>()
{
    DLinkList<T> *p, *q;
    p = dhead;
    q = p->next;
    while(q != NULL)
    {
        delete p;
        p = q;
        q = q->next;
    }
    delete p;
}

//头插法
template<typename T>
void DLinkListClass<T>:: CreateListF(T a[], int n)
{
    DLinkList<T> *s;
    int i;
    for(i = 0; i < n; i++)
    {
        s = new DLinkList<T>();
        s->data = a[i];
        s->next = dhead->next;
        if(dhead->next != NULL)
            dhead->next->prior = s;
        dhead->next = s;
        s->prior = dhead;
    }
}

//尾插法
template<typename T>
void DLinkListClass<T>:: CreateListR(T a[], int n)
{
    DLinkList<T> *s, *r;
    int i;
    r = dhead;
    for(i = 0; i < n; i++)
    {
        s = new DLinkList<T>();
        s->data = a[i];
        r->next = s;
        s->prior = r;
        r = s;
    }
    r->next = NULL;
}

//插入数据元素
template<typename T>
bool DLinkListClass<T>::ListInsert(int i, T e)
{
    int j =0;
    DLinkList<T> *s, *p = dhead;
    while(j < i-1 && p != NULL)
    {
        j++;
        p = p->next;
    }
    if(p == NULL) return false;
    else
    {
        s = new DLinkList<T>();
        s->data = e;
        s->next = p->next;
        if(p->next != NULL)
            p->next->prior =s;
        s->prior = p;
        p->next = s;
        return true;
    }
}

//删除数据元素
template<typename T>
bool DLinkListClass<T>::ListDelete(int i)
{
    int j =0;
    DLinkList<T> *q, *p = dhead;
    while(j < i-1 && p != NULL)
    {
        j++;
        p = p->next;
    }
    if(p == NULL) return false;
    else
    {
        q = p->next;
        if(q == NULL) return false;
        p->next = q->next;
        if(p->next != NULL)
            p->next->prior = p;
        delete q;
        return true;
    }
}

//遍历显示链表
template <typename T>
void DLinkListClass<T>::DispList()
{
    DLinkList<T> *p = dhead->next;
    while(p!= NULL)
    {
        cout << p->data << " ";
        p = p->next;
    }
}


int main()
{
    int a[5] = {1,2,3,4,5};
    char b[5] = {'a', 'b', 'c','d','e'};
    DLinkListClass<int> Link1;
    DLinkListClass<char> Link2;
    Link1.CreateListF(a, 5);
    Link2.CreateListR(b, 5);
    Link1.ListInsert(3, 55);
    Link2.ListDelete(3);

    cout << "头插法\n";
    Link1.DispList();

    Delmaxnode(Link1);

    cout << "\nDelmaxnode\n";
    Link1.DispList();
    cout << "\n尾插法\n";
    Link2.DispList();



    return 0;
}

本人github链接: https://github.com/ITMasterC 欢迎来共同探讨,C++,cocos2dx游戏,数据结构,C语言实现小游戏代码…………

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值