双向链表源代码

//#include "double1.h"头文件

template <class T>
class DoubleNode {
   friend Double<T>;
   friend DoubleCircular<T>;
   friend DoubleCircularIterator<T>;
   friend HDoubleCircular<T>;
   friend HDoubleCircularIterator<T>;
//   private:
   public:
      T data;
      DoubleNode<T> *left, *right;
};

#endif

// doubly linked list

#ifndef Double_
#define Double_


#include <iostream.h>


template<class T>
class Double {
   public:
      Double() {LeftEnd = RightEnd = 0;}
      ~Double();
      bool IsEmpty() const {return LeftEnd == 0;}
      int Length() const;
      bool Find(int k, T& x) const;
      int Search(const T& x) const;
      Double<T>& Delete(int k, T& x);
      Double<T>& Insert(int k, const T& x);
      void Output(ostream& out) const;
   private:
      DoubleNode<T> *LeftEnd,   // pointer to leftmost node
                    *RightEnd;  // pointer to rightmost node
};

template<class T>
Double<T>::~Double()
{// Double destructor. Delete all nodes.
   DoubleNode<T> *curr = LeftEnd,  // current node
                 *next;            // next node
   while (curr) {
      next = curr->right;
      delete curr;
      curr = next;
      }
}

template<class T>
int Double<T>::Length() const
{// Return the number of elements in the list.
   // count nodes
   DoubleNode<T> *curr = LeftEnd;
   int len = 0;  // number to left of curr
   while (curr) {
     len++;
     curr = curr->right;
     }
   return len;
}

template<class T>
bool Double<T>::Find(int k, T& x) const
{// Set x to the k'th element in the list.
 // Return false if no k'th; return true otherwise.
   if (k < 1 || !LeftEnd) return false;

   DoubleNode<T> *curr = LeftEnd;
   int index = 1;  // index of curr
   while (index < k && curr) {
      // move to next node
      curr = curr->right;
      index++;
      }
   if (index == k) {x = curr->data;
                    return true;}
   return false; // no k'th element
}

template<class T>
int Double<T>::Search(const T& x) const
{// Locate x.  Return position of x if found.
 // Return 0 if x not in the chain.
   if (!LeftEnd) return 0;  // list is empty

   // examine nodes
   DoubleNode<T> *curr = LeftEnd;
   int index = 1;  // index of curr
   while (curr && curr->data != x) {
      // move to next node
      curr = curr->right;
      index++;
      }
   if (curr) return index;
   return 0;
}

template<class T>
Double<T>& Double<T>::Delete(int k, T& x)
{// Set x to the k'th element and delete it.
 // Throw OutOfBounds exception if no k'th element.
   if (k < 1 || !LeftEnd)
      throw OutOfBounds(); // no k'th
  
   // p will eventually point to k'th node
   DoubleNode<T> *p = LeftEnd;
   int index = 1;  // index of p

   // move p to k'th
   for (; index < k && p; index++)
      p = p->right;

   // make sure p is at the k'th element
   if (index != k) throw OutOfBounds(); // no k'th

   // remove p from list
   if (p == LeftEnd) {
      // delete first node
      LeftEnd = LeftEnd->right;
      if (!LeftEnd)  // list is empty
         RightEnd = 0;
      else  // list is not empty
         LeftEnd->left = 0;
      }
   else if (p == RightEnd) {
           // delete last node
           RightEnd = RightEnd->left;
           RightEnd->right = 0;
           }
         else {
            // delete an interior node
            p->right->left = p->left;
            p->left->right = p->right;
            }

   // save k'th element and free node p
   x = p->data;
   delete p;

   return *this;
}

template<class T>
Double<T>& Double<T>::Insert(int k, const T& x)
{// Insert x after the k'th element.
 // Throw OutOfBounds exception if no k'th element.
 // Pass NoMem exception if inadequate space.
   if (k < 0) throw OutOfBounds();

   if (k) {// locate k'th node
      if (!LeftEnd) throw OutOfBounds();  // empty list

      // p will eventually point to k'th node
      DoubleNode<T> *p = LeftEnd;
      int index = 1;
      // move p to k'th
      for (; index < k && p; index++)
         p = p->right;
      if (index != k) throw OutOfBounds(); // no k'th

      // insert after p
      DoubleNode<T> *y = new DoubleNode<T>;
      y->data = x;
      y->right = p->right;
      p->right = y;
      y->left = p;
      if (p == RightEnd) // y is now the last node
         RightEnd = y;
      else  // y is not the last node
         y->right->left = y;
      }
   else {// insert as first element
         DoubleNode<T> *y = new DoubleNode<T>;
         y->data = x;
         if (LeftEnd) {// insert into nonempty list
            y->right = LeftEnd;
            y->left = 0;
            LeftEnd->left = y;
            }
         else {// insert into an empty list
               LeftEnd = RightEnd = y;
               y->left = y->right = 0;
               }
         LeftEnd = y;
         }

   return *this;
}

template<class T>
void Double<T>::Output(ostream& out) const
{// Insert the chain elements into the stream out.
   for (DoubleNode<T> *curr = LeftEnd;
        curr; curr = curr->right)
      out << curr->data << "  ";
}

// overload <<
template <class T>
ostream& operator<<(ostream& out, const Double<T>& x)
   {x.Output(out); return out;}

#endif

 

 

 

// test doubly linked class

#include <iostream.h>
#include "double1.h"

void main(void)
{
   try {
      Double<int> L;
      cout << "Length = " << L.Length() << endl;
      cout << "IsEmpty = " << L.IsEmpty() << endl;
      L.Insert(0,2).Insert(1,5).Insert(2,7).Insert(3,8);
      L.Insert(1,3).Insert(0,1).Insert(4,6).Insert(7,9);
      cout << "List is " << L << endl;
      cout << "IsEmpty = " << L.IsEmpty() << endl;
      int z;
      L.Find(1,z);
      cout << "First element is " << z << endl;
      L.Find(8,z);
      cout << "Eighth element is " << z << endl;
      L.Find(4,z);
      cout << "Fourth element is " << z << endl;
      cout << "Length = " << L.Length() << endl;
      cout << "8 is in position " << L.Search(8) << endl;
      cout << "1 is in position " << L.Search(1) << endl;
      cout << "10 is in position " << L.Search(10) << endl;
      cout << "6 is in position " << L.Search(6) << endl;
      L.Delete(1,z);
      cout << "Deleted element from position 1 is " << z << endl;
      cout << "List is " << L << endl;
      L.Delete(7,z);
      cout << "Deleted element from position 7 is " << z << endl;
      cout << "List is " << L << endl;
      L.Delete(3,z);
      cout << "Deleted element from position 3 is " << z << endl;
      cout << "List is " << L << endl;
      int z1, z2, z3;
      L.Delete(5,z1).Delete(1,z2).Delete(3,z3);
      cout << "Deleted elements are " << z1
           << "  " << z2 << "  " << z3 << endl;
      cout << "List is " << L << endl;
      L.Delete(1,z1).Delete(1,z2);
      cout << "Deleted elements are " << z1
           << "  " << z2 << endl;
      cout << "List is " << L << endl;
      L.Insert(0,5);
      cout << "List is " << L << endl;
      }
   catch (...) {
      cerr << "An exception has occurred" << endl;
      }
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值