双向循环列表

#include<bits/stdc++.h>
using namespace std;
template<typename T>
struct DblNode {
T data; //链表结点数据
DblNode<T>* lLink, * rLink; //链表前驱、后继指针
  DblNode(T value = 0, DblNode<T>* left = NULL, DblNode<T>* right = NULL):data(value), lLink(left), rLink(right) {} //构造函数
};

template<typename T>
class DblList {
 public:
  DblList(T uniqueVal); //构造函数
  DblList(DblList<T>& L); //拷贝构造
  ~DblList(); //析构函数:释放所用存储
  void makeEmpty(); //将链表置空
  bool IsEmpty() { return first->rlink == first; } //判双链表是否为空
  DblNode<T>* getHead()const { return first; }
  DblNode<T>* Locate(int i,int d); //在链表中定位序号为i(>=0)的结点,d=0按前驱方向,d≠0按后继方向
  bool Insert(int i, const T& x, int d); //在第i个结点后插入x,d=0按前驱方向,d≠0按后继方向
  bool Remove(int i, int d); //删除第i个结点,d=0按前驱方向,d≠0按后继方向
  void output(int d); //输出,d=0按前驱方向输出, d≠0按后驱方向输出
 private:
  DblNode<T>* first;
};

template<typename T>
inline DblList<T>::DblList(T uniqueVal)
{
  //构造函数:建立双向循环链表的附加头结点,它包含了一个用于某些特定情况的值。
  first = new DblNode<T>(uniqueVal);
  if (first == NULL)
  {
    cerr << "存储分配出错!" << std::endl; //new处未能成功分配空间
    exit(1);
  }
  first->rLink = first->lLink = first;
}

template<typename T>
inline DblList<T>::DblList(DblList<T>& L)
{
  //拷贝构造函数
  T value;
  DblNode<T>* srcptr = L.getHead();
  DblNode<T>* destptr = first = new DblNode<T>;
  while (srcptr->rLink != L.first) //逐个结点复制
  {
    value = srcptr->rLink->data;
    destptr->rLink = new DblNode<T>(value);
    destptr->rLink->lLink = destptr;
    destptr = destptr->rLink;
    srcptr = srcptr->rLink;
  }
  destptr->rLink = first;
  first->lLink = destptr;
}
//析构
template<typename T>
inline DblList<T>::~DblList()
{
  makeEmpty();
  if (first != NULL)
  {
    delete first;
    first = NULL;
  }
}

template<typename T>
inline void DblList<T>::makeEmpty()
{
  //将链表置为空表
  DblNode<T>* q;
  while (first->rLink != first)
  {
    q = first->rLink;
    first->rLink = q->rLink;
    delete q;
  }
  first->lLink = first;
  first->rLink = first;
}

template<typename T>
inline DblNode<T>* DblList<T>::Locate(int i,int d)
{
  //在带附加头结点的双向循环链表中按d所指方向寻找第i个结点的地址。
  //若d=0,在前驱方向找第i个结点,若d≠0在后继方向找第i个结点
  if(first->rLink == first || i==0) return first;
  DblNode<T>* current;
  if(d==0) current = first->lLink;
  else current = first->rLink;
  for(int j=0;j<i-1;j++)
  {
    if(current == first) break;
    else if(d==0) current = current->lLink;
    else current = current->rLink;
  }
  if(current != first) return current;
  else return NULL;
}

template<typename T>
inline bool DblList<T>::Insert(int i, const T& x, int d)
{
  //建立一个包含有值x的新结点,并将其按d指定的方向插入到第i个结点之后。
  DblNode<T>* current = Locate(i, d); //查找第i个结点
  if (current == NULL) return false; //i不合理,插入失败
  DblNode<T>* newNode = new DblNode<T>(x);
  if (newNode == NULL)
  {
    cerr << "存储分配失败!" << std::endl;
    exit(1);
   }
  if (d == 0) //前驱方向插入
  {
    newNode->lLink = current->lLink;
    current->lLink = newNode;
    newNode->lLink->rLink = newNode;
    newNode->rLink = current;
  }
  else //后继方向插入
  {
    newNode->rLink = current->rLink;
    current->rLink = newNode;
    newNode->rLink->lLink = newNode;
    newNode->lLink = current;
  }
  return true;
}

template<typename T>
inline bool DblList<T>::Remove(int i, int d)
{
  //在带附加头结点的双向循环链表中按照d所指方向删除第i个结点
  DblNode<T>* current = Locate(i, d); //查找第i个结点
  if (current == NULL) return false; //i不合理,删除失败
  current->rLink->lLink = current->lLink; //从lLink链中摘下
  current->lLink->rLink = current->rLink; //从rLink链中摘下
  delete current; //删除
  return true; //删除成功
}

template<typename T>
inline void DblList<T>::output(int d)
{
  //双向循环链表的输出函数:将循环链表中按d指定方向输出
  //若d=0,从头结点向前输出,若d≠0,从头结点向后输出
  DblNode<T>* current;
  if(d==0) current = first->lLink;
  else current = first->rLink;
  while(current != first)
  {
    std::cout << current->data <<" ";
    if(d==0) current = current->lLink;
    else current = current->rLink;
  }
  std::cout << std::endl;
}
int main()
{
  DblList<int> L1(0);
  //在头结点前驱结点插入
  L1.Insert(0,10,0);
  L1.Insert(0,20,0);
  L1.Insert(0,30,0);
  L1.Insert(1,40,0);
  cout<<"逆向输出链表元素:";
  L1.output(0);
  cout<<"正向输出链表元素:";
  L1.output(1);
  cout<<endl;

  L1.makeEmpty();
  //在头结点后继结点插入
  L1.Insert(0,11,1);
  L1.Insert(0,21,1);
  L1.Insert(0,31,1);
  L1.Insert(0,41,1);
  cout<<"逆向输出链表元素:";
  L1.output(0);
  cout<<"正向输出链表元素:";
  L1.output(1);
  cout<<endl;

  DblList<int> L2(L1);
  cout<<"逆向输出链表元素:";
  L2.output(0);
  cout<<"正向输出链表元素:";
  L2.output(1);
  cout<<"前驱方向第2个结点:"<<L1.Locate(2,0)->data<<endl;
  cout<<"后继方向第2个结点:"<<L1.Locate(2,1)->data<<endl;
  L2.Remove(2,0);
  cout<<"删除前驱方向第2个节点后:";
  L2.output(1);
  L1.Remove(2,1);
  cout<<"删除后继方向第2个节点后:";
  L1.output(1);
  return 0;
}

posted @ 2023-04-11 18:17  RUI_26  阅读(34)  评论(0编辑  收藏  举报