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 }      
  • 相关阅读:
    实用机器学习 跟李沐学AI
    Explicitly drop temp table or let SQL Server handle it
    dotnettransformxdt and FatAntelope
    QQ拼音输入法 禁用模糊音
    (技术八卦)Java VS RoR
    Ruby on rails开发从头来(windows)(七)创建在线购物页面
    Ruby on rails开发从头来(windows)(十三)订单(Order)
    Ruby on rails开发从头来(windows)(十一)订单(Order)
    新员工自缢身亡,华为又站到了风口浪尖
    死亡汽油弹(Napalm Death)乐队的视频和来中国演出的消息
  • 原文地址:https://www.cnblogs.com/yang901112/p/12721425.html
Copyright © 2011-2022 走看看