zoukankan      html  css  js  c++  java
  • C++双向循环链表

    先说一说双向循环链表的逆置,网上搜了一箩筐,用VS2017,基本上不成功,尽管明白道理是怎么回事,但是总感觉,不像c++的类,感觉用起来还得传指针啊,传链表啊等参数,不太像双向循环链表类的专属函数。虽然c语言写出来双向循环链表最好,但是既然学了c++,就尽量用一下c++的特点,能用多少是多少,也有利于对c++理解。好了废话不多说,凉一凉自己写的一般一般的双向循环链表吧。

      1 #include<iostream>
      2 
      3 using namespace std;
      4 
      5 template<class T> class DoubleLinkedList;
      6 
      7 template<class T>
      8 class MyNode    
      9 {
     10     friend class DoubleLinkedList<T>;
     11 private:
     12     T elem;
     13     MyNode *prev;
     14     MyNode *next;
     15     MyNode(){}
     16     MyNode(const T &theelem)
     17         :elem(theelem) {
     18         prev = NULL;
     19         next = NULL;
     20     }
     21 };
     22 
     23 template<class T>
     24 class DoubleLinkedList
     25 {
     26 public:
     27     DoubleLinkedList() 
     28     {
     29         first = new MyNode<T>(); 
     30         first->prev = first->next = first;
     31     }
     32     ~DoubleLinkedList(){ makeEmpty(); }
     33 
     34     bool IsEmpty(); // 判断链表是否为空
     35     void makeEmpty(); // 清空链表
     36     int  Length(); // 计算链表的长度
     37     void Insert(int index, const T &x); // 按照索引插入值(节点)
     38     void Push_head(const T &x); // 向链表的头部插入值  头插法
     39     void Push_back(const T &x); // 向链表的尾部插入值  尾插法
     40     void Delete(T x); // 按值删除节点
     41     void Index_Delete(const int &n); // 按索引删除节点
     42     void Invert(); // 逆置
     43     void Concatenate(DoubleLinkedList<T> &b); // 连接链表
     44     void show(); // 显示链表,这只是方便,一般得做成迭代器
     45 private:
     46     MyNode<T> *first;
     47 };
     48 template<class T>
     49 bool DoubleLinkedList<T>::IsEmpty()
     50 {
     51     return first == NULL;
     52 }
     53 
     54 template<class T>
     55 void DoubleLinkedList<T>::makeEmpty()
     56 {
     57     MyNode<T> *p;
     58     MyNode<T> *pNode = first->next;
     59     while (pNode != first)
     60     {
     61         p = pNode;
     62         pNode = pNode->next;
     63         delete p;
     64     }
     65     delete first;
     66     first = NULL;
     67 }
     68 
     69 template<class T>
     70 int  DoubleLinkedList<T>::Length()
     71 {
     72     int size = 0;
     73     MyNode<T> * p = first->next;
     74     if (IsEmpty()) cout << "The size is 0" << endl;
     75     else
     76     {
     77         while (p != first)
     78         {
     79             size++;
     80             p = p->next;
     81         }
     82     }
     83     return size;
     84 }
     85 
     86 template<class T>
     87 void DoubleLinkedList<T>::Insert(int index, const T &x)
     88 {
     89     MyNode<T> * insertNode = new MyNode<T>(x);
     90     MyNode<T> * p = first->next;
     91     if (Length() < index) {
     92         Push_back(x);
     93         return;
     94     }
     95     if (index < 1) {
     96         Push_head(x);
     97         return;
     98     }
     99     int count = 1;
    100     while (count < index && p != first)
    101     {
    102         count++;
    103         p = p->next;
    104     }
    105     insertNode->next = p;
    106     p->prev->next = insertNode;
    107     insertNode->prev = p->prev;
    108     p->prev = insertNode;
    109     return;
    110 }
    111 
    112 template<class T>
    113 void DoubleLinkedList<T>::Push_head(const T &x)
    114 {
    115     MyNode<T>* newNode = new MyNode<T>(x);
    116     newNode->prev = first;
    117     newNode->next = first->next;
    118     first->next->prev = newNode;
    119     first->next = newNode;
    120 }
    121 
    122 template<class T>
    123 void DoubleLinkedList<T>::Push_back(const T &x)
    124 {
    125     MyNode<T>* newNode = new MyNode<T>(x);
    126     newNode->prev = first->prev;
    127     newNode->next = first;
    128     first->prev->next = newNode;
    129     first->prev = newNode;
    130 }
    131 
    132 template<class T>
    133 void DoubleLinkedList<T>::Delete(T x)
    134 {
    135     MyNode<T>* p = first->next;
    136     while (p->elem != x && p != first)
    137     {
    138         p = p->next;
    139     }
    140     p->next->prev = p->prev;
    141     p->prev->next = p->next;
    142     delete p;
    143     return;
    144 }
    145 
    146 template<class T>
    147 void DoubleLinkedList<T>::Index_Delete(const int &n)
    148 {
    149     MyNode<T>* del = NULL;
    150     MyNode<T>* p = first->next;
    151     int count = 0;
    152     if (n < 0)
    153     {
    154         del = p;
    155         p->next->prev = first;
    156         first->next = p->next;
    157         delete del;
    158         return;
    159     }
    160     else if(n > Length())
    161     {
    162         del = first->prev;
    163         first->prev = del->prev;
    164         del->prev->next = first;
    165         delete del;
    166         return;
    167     }
    168     while (count < n && p != first)
    169     {
    170         count++;
    171         p = p->next;
    172     }
    173     del = p;
    174     p->next->prev = p->prev;
    175     p->prev->next = p->next;
    176     delete del;
    177 }
    178 
    179 template<class T>
    180 void DoubleLinkedList<T>::Invert()
    181 {
    182         // 我这里只考虑链表至少有一个实数节点的情况
    183         // 让p指向下一个节点,再把首节点与第一个实数节点做成一个循环链表,
    184     MyNode<T>* p = first->next;
    185     MyNode<T>* q = p;
    186     p = p->next;
    187     first->prev = q;
    188     q->next = first;
    189 
    190        // 只要把接下来的节点一个一个放到头部就行了
    191     while (p != first)
    192     {
    193         MyNode<T> *r;
    194         r = p;
    195         p = p->next;
    196         r->prev = first;
    197         r->next = first->next;
    198         first->next->prev = r;
    199         first->next = r;
    200     }
    201 }
    202 
    203 // 我选择将循环链表b的数值直接放到所连接链表的后面,这样改变b就不会改变连接后的链表
    204 
    205 template<class T>
    206 void DoubleLinkedList<T>::Concatenate(DoubleLinkedList<T> &b)
    207 {
    208     MyNode<T>* p = b.first;
    209     
    210     if(IsEmpty())
    211     {
    212         first = p;
    213     }
    214     else if(b.IsEmpty())
    215     {
    216         return;
    217     }
    218     else {
    219         while (p->next != b.first)
    220         {
    221             p = p->next;
    222             Push_back(p->elem);
    223         }
    224         return;
    225     }
    226     return;
    227 }
    228 
    229 template<class T>
    230 void DoubleLinkedList<T>::show()
    231 {
    232     if (IsEmpty())
    233     {
    234         return;
    235     }
    236     MyNode<T>* p=first->next;
    237     while (p != first)
    238     {
    239         cout << p->elem << " ";
    240         p = p->next;
    241     }
    242     cout << endl;
    243 
    244 }
    245 
    246 // 下面测试的代码没啥可看的
    247 
    248 int main()
    249 {
    250     cout << "hello world!" << endl;
    251 
    252     DoubleLinkedList<int> a;
    253     a.Push_head(30);
    254     a.Push_head(20);
    255     a.Push_head(10);
    256     a.Push_back(40);
    257     a.Push_back(50);
    258     a.Push_back(60);
    259     a.Index_Delete(2);
    260     a.show();
    261     a.Insert(1, 35);
    262     a.Insert(-1, 100);
    263     a.show();
    264     int size;
    265     
    266     a.Delete(100);
    267     size = a.Length();
    268     a.Index_Delete(20);
    269     a.show();
    270     cout << "size: " << size << endl;
    271 
    272     DoubleLinkedList<int> intList;
    273     DoubleLinkedList<int> intList1;
    274 
    275     intList.Push_back(1);
    276     intList.Push_back(2);
    277     intList.Push_back(3);
    278     intList.Push_back(4);
    279 
    280     intList1.Push_back(5);
    281     intList1.Push_back(6);
    282     intList1.Push_back(7);
    283     intList1.Push_back(8);
    284     intList.Concatenate(intList1);
    285     intList.show();
    286     intList.Invert();
    287     intList.show();
    288     intList.Push_head(125);
    289     intList.Push_back(21);
    290     intList.Invert();
    291     intList.show();
    292     intList1.Delete(5);
    293     intList1.Delete(6);
    294     intList1.Delete(7);
    295     intList1.Delete(8);
    296     intList1.show();
    297     return 0;
    298 }      
  • 相关阅读:
    跨域在前端工程化中的实际解决方案。
    细说Vue作用域插槽,匹配应用场景。
    js数据结构之栈和队列的详细实现方法
    js数据结构之hash散列的详细实现方法
    js数据结构之集合的详细实现方法
    js数据结构之二叉树的详细实现方法
    【好记性不如烂笔头】之小程序要点记录
    回想继承、原型与原型链有感
    js数据结构之链表(单链表、双向链表、循环链表)
    js数据结构之列表的详细实现方法
  • 原文地址:https://www.cnblogs.com/yang901112/p/12721425.html
Copyright © 2011-2022 走看看