⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cirhdoublylinkedlist.h

📁 回顾基础
💻 H
字号:
//带头结点的循环双链表类

#include <iostream.h>
#include "DLinkNode.h"                           //双链表结点类

template <class T>
class CirHDoublyLinkedList                       //带头结点的循环双链表类
{
  public:
    DLinkNode<T> *head;                          //双链表的头指针

    CirHDoublyLinkedList();                      //构造空双链表
    CirHDoublyLinkedList(T value[], int n);      //构造由指定数组提供元素的双链表
    ~CirHDoublyLinkedList();                     //析构
 
    bool isEmpty();                              //判断双链表是否为空
    int length();                                //返回双链表长度 
    DLinkNode<T>* getNode(int i);                //返回第i(i≥0)个结点指针
    T get(int i);                                //返回第i个元素
    bool set(int i, T x);                        //设置第i个元素为x
    friend ostream& operator<<(ostream& out, CirHDoublyLinkedList<T> &list);    //输出双链表
    DLinkNode<T>* insert(int i, T x);            //插入x作为第i个结点
    bool remove(int i, T& old);                  //删除第i个结点
    void clear();                                //清空双链表

    //循环双链表增加的操作
    void printPrev();                            //输出双链表,从后向前,沿着前驱指针
    DLinkNode<T>* insert(T x);                   //在双链表最后插入x元素结点
};

template <class T>
CirHDoublyLinkedList<T>::CirHDoublyLinkedList()  //构造空双链表
{
    this->head = new DLinkNode<T>();             //创建头结点
    head->prev = head;
    head->next = head;
}

template <class T>
CirHDoublyLinkedList<T>::CirHDoublyLinkedList(T value[], int n)   //构造由指定数组提供元素的双链表
{
    head = new DLinkNode<T>();                   //创建头结点
    head->prev = head;
    head->next = head;
    for (int i=0; i<n; i++) 
        insert(value[i]);                        //在双链表最后插入结点
}

template <class T>
CirHDoublyLinkedList<T>::~CirHDoublyLinkedList() //析构函数
{
    clear();                                     //清空双链表
}

template <class T>
bool CirHDoublyLinkedList<T>::isEmpty()          //判断双链表是否为空
{
    return head->next==head;
}

//以下函数算法同循环单链表
template <class T>
int CirHDoublyLinkedList<T>::length()            //返回双链表长度
{
    int i=0;
    DLinkNode<T> *p=head->next;
    while (p!=head)
    {
        i++;
        p = p->next;
    }
    return i;
}

template <class T>
DLinkNode<T>* CirHDoublyLinkedList<T>::getNode(int i)  //返回第i(i≥0)个结点指针,O(n)
{                                                //若双链表空或序号错误返回NULL
    if (i<0)
        return NULL;

    int j=0;
    DLinkNode<T> *p=head->next;
    while (p!=head && j<i)
    {
        j++;
        p = p->next;
    }
    if (p!=head)
        return p;                                //p指向第i个结点
    return NULL;                                 //双链表空或序号错误
}

template <class T>
T CirHDoublyLinkedList<T>::get(int i)            //返回第i个元素
{                                                //若双链表空或i指定元素序号无效则抛出异常
    DLinkNode<T> *p = getNode(i);
    if (p!=NULL)
        return p->data;
    throw "双链表空或参数i指定元素序号无效";
}

template <class T>
bool CirHDoublyLinkedList<T>::set(int i, T x)    //设置第i个元素为x
{
    DLinkNode<T> *p = getNode(i);
    if (p!=NULL)
    {
        p->data = x;
        return true;
    }
    return false;
}

template <class T>
ostream& operator<<(ostream& out, CirHDoublyLinkedList<T> &list)    //输出双链表
{
    DLinkNode<T> *p = list.head->next;
    out<<"(";
    while (p!=list.head)
    {
        out<<p->data;
        p = p->next;
        if (p!=list.head)
            out<<", ";
    }
    out<<")\n";
    return out;
}

template <class T>
void CirHDoublyLinkedList<T>::printPrev()         //输出双链表,从后向前,沿着前驱域
{
    DLinkNode<T> *p = head->prev;
    cout<<"listPrev: (";
    while (p!=head)
    {
        cout<<p->data;
        p = p->prev;
        if (p!=head)
            cout<<", ";
    }
    cout<<")\n";
}

template <class T>
DLinkNode<T>* CirHDoublyLinkedList<T>::insert(int i, T x) //插入x作为第i个结点
{
    int j=0; 
    DLinkNode<T> *p=head;
    while (p->next!=head && j<i)                 //寻找插入位置
    {
        j++;
        p = p->next;
    }
    DLinkNode<T> *q = new DLinkNode<T>(x, p, p->next);  //插入在p结点之后
    p->next->prev = q;
    p->next = q;
    return q;
}

template <class T>
DLinkNode<T>* CirHDoublyLinkedList<T>::insert(T x)   //在双链表最后插入结点
{
    DLinkNode<T> *q = new DLinkNode<T>(x, head->prev, head);  //插入在head头结点之前,相当于尾插入
    head->prev->next = q;
    head->prev = q;
    return q;
}

template <class T>
bool CirHDoublyLinkedList<T>::remove(int i, T& old)   //删除第i个结点,被删除元素存放在old变量中
{
    DLinkNode<T>* p=getNode(i);                  //p指向待删除结点
    if (p!=NULL)                                 //删除p结点自己
    {
        old = p->data;
        p->prev->next = p->next;
        p->next->prev = p->prev;
        delete p;
        return true;
    }    
    return false;
}

template <class T>
void CirHDoublyLinkedList<T>::clear()            //清空双链表
{
    DLinkNode<T> *p=head->next;
    while (p!=head)
    {
        DLinkNode<T> *q = p;
        p = p->next;
        delete q;
    }
    head->next = head;                           //设置循环双链表为空
    head->prev = head;                           //比循环单链表多此一句
}

//以上是第2章内容,实现线性表ADT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -