zoukankan      html  css  js  c++  java
  • 双向链表(C++实现)

    wKioL1busLOTWsqhAAAI3EcuKqo751.png

    //////////////////////////////////////////////////////////////////////////////////////
    ///////  这里建立两个类,一个节点类和一个List类,与单链表不同的是双向链表的节点要多一
    //////   个前驱指针,相应的,双向链表函数实现要与单链表实现有所差异
     
        typedef int DataType;
     
        //struct LinkNode     //节点类(复合形态)
        //{
        //  friend class SList;
                      //将SList设为友元,便于SList类可以访问节点类的私有成员
        //public:
        //  LinkNode(const DataType x);  
        //private:
        //  DataType _data;    //节点的数据
        //  LinkNode* _next;    //指向该节点的下一个节点
        //      LinkNode* _prev;    //指向该节点的前一个节点
        //};
     
        //直接用struct定义LinkNode类,因为struct的成员默认为公有数据成员,所以可直接访问
        struct LinkNode      //节点类(建议写法)
        {
            LinkNode(const DataType x);
            DataType _data;    //节点的数据
            LinkNode* _next;    //后继指针
            LinkNode* _prev;      //前驱指针
        };
     
        class List    //链表类
        {
        public:
            List();         //构造函数
            List(const List& s);        //拷贝构造
            List &operator=(List& s);    //赋值运算符的重载
            ~List();
     
        public:
            void Reverse();
            void Swap(List& s);
            void PrintSList();   //打印链表
            void PushBack(const DataType& x);    //在尾部插入一个节点
            void Clear();         //链表置空
            void PopBack();
            void PushFront(DataType x);  //头插
            void PopFront();    //删除首节点
            void Insert(LinkNode* pos, DataType x);//固定位置插入一个节点
            void Erase(LinkNode* pos);        //删除某一节点
            LinkNode* Find(DataType x);       //查找节点并返回这个节点的地址
            int Amount();   //计算链表节点的数目
            void Remove(DataType x);     //查找某节点并删除
     
        private:
            LinkNode* _head;    //指向头结点
            LinkNode* _tail;    //指向尾节点
        };
    List.h
      1   #include<iostream>
      2     using namespace std;
      3     #include<assert.h>
      4     #include"List.h"
      5  
      6     //节点类构造函数*
      7     LinkNode::LinkNode(const DataType x)
      8     :_data(x)
      9     , _next(NULL)
     10     , _prev(NULL)
     11     {}
     12  
     13     //链表类*
     14     List::List()         //构造函数
     15     : _head(NULL)
     16     , _tail(NULL)
     17     {}
     18      
     19     List::List(const List& s)          //拷贝构造
     20     : _head(NULL)
     21     , _tail(NULL)
     22     {
     23         if (s._head == NULL)
     24         {
     25             return;
     26         }
     27         LinkNode* tmp = s._head;
     28         while (tmp)
     29         {
     30             PushBack(tmp->_data);
     31             tmp = tmp->_next;
     32         } 
     33  
     34     }
     35      
     36     //赋值运算符的重载(传统方法)
     37     //SList & SList::operator=(const SList& s)    
     38     //{
     39     //  if (this != &s)
     40     //  {
     41     //      _head = NULL;
     42     //      _tail = NULL;
     43     //      LinkNode* tmp = s._head;
     44     //  do{
     45     //      PushBack(tmp->_data);
     46     //      tmp = tmp->_next;
     47     //       } while (tmp != s._head);
     48     //  }
     49     //  return *this; 
     50     //}
     51  
     52     //赋值运算符的重载(高效写法)*
     53     /*void SList::Swap(SList& s)
     54     {
     55     swap(_head, s._head);
     56     swap(_tail, s._tail);
     57  
     58     }
     59     SList&  SList::operator=(SList &s)
     60     {
     61     if (this != &s)
     62     {
     63     SList tmp(s);
     64     Swap(tmp);
     65     }
     66     return *this;
     67     }*/
     68  
     69     List&  List::operator=(List &s)     //赋值运算符的重载再优化(推荐写法)
     70     {
     71         if (this != &s)
     72         {
     73             swap(_head, s._head);
     74             swap(_tail, s._tail);
     75         }
     76         return *this;
     77     }
     78     List::~List()    //析构
     79     {
     80         Clear();
     81     }
     82  
     83     void List::Reverse()   //链表逆置(利用头插新节点的方法)
     84     {
     85         if (_head == NULL || _head== _tail)
     86         {
     87             return;
     88         }
     89         int ret = Amount();
     90  
     91     /*  //  方法一(相当于用头插的方式重新建立链表)
     92      _tail = new LinkNode(_head->_data);
     93         LinkNode* begin = NULL;
     94         LinkNode* tmp = _tail;
     95         while (--ret)
     96         {
     97             LinkNode* del = _head;
     98             _head = _head->_next;
     99             delete del;           
    100             begin = new LinkNode(_head->_data);
    101             begin->_next = tmp;
    102             tmp->_prev = begin;
    103             tmp = begin;
    104         }
    105         _head = begin;*/
    106  
    107     //////  方法二(只是交换对称位置节点的数据)**(高效)
    108         LinkNode* begin = _head;
    109         LinkNode* end = _tail;
    110         while (ret)
    111         {
    112             if (end->_next == begin)
    113                 break;
    114             ret /= 2;
    115             swap(begin->_data, end->_data);
    116             begin = begin->_next;
    117             end = end->_prev;
    118         }
    119      
    120          /*// 方法三  交换前驱和后继指针
    121           swap(_head, _tail);
    122           LinkNode* cur = _head;
    123           while (cur)
    124           {
    125               swap(cur->_prev,cur->_next);
    126               cur = cur->_next;
    127           }
    128           */
    129          
    130     }
    131  
    132     //打印链表*
    133     void List::PrintSList()
    134     {
    135         //头结点为空时,无需打印链表
    136         if (_head == NULL)
    137         {
    138             cout << "This SList is Empty !" << endl;
    139             return;
    140         }
    141         else
    142         {
    143             LinkNode* tmp = _head;  
    144            while (tmp)
    145            {
    146                 cout << tmp->_data << "-->";
    147                 tmp = tmp->_next;
    148             } 
    149             cout <<"NULL"<< endl;
    150         }
    151     }
    152      
    153     void List::PushBack(const DataType& x)    //在尾部插入一个节点*
    154     {
    155         //如果链表为空,插入节点后只有一个节点,此时_head=_tail
    156         if (_head == NULL)
    157         {
    158             _head = new LinkNode(x);
    159             _tail = _head;
    160         }
    161         else
    162         {
    163             _tail->_next = new LinkNode(x);
    164             _tail->_next->_prev=_tail;
    165             _tail = _tail->_next;
    166         }
    167     }
    168      
    169     void List::Clear()         //链表置空*
    170     {
    171         LinkNode* begin = _head;
    172         while (begin != _tail)
    173         {
    174             _head = _head->_next;
    175             delete begin;
    176             begin = _head;
    177         }
    178         _head = NULL;
    179         _tail = NULL;
    180     }
    181      
    182     void List::PopBack()    //尾删
    183     {
    184         if (_head == NULL)
    185         {
    186             cout << "This SList is empty !" << endl;
    187         }
    188         else if (_head == _tail)
    189         {
    190             delete _head;
    191             _head = NULL;
    192             _tail = NULL;
    193         }
    194         else
    195         {
    196             LinkNode* cur = _head;
    197             while (cur->_next != _tail)
    198             {
    199                 cur = cur->_next;
    200             }
    201             delete _tail;
    202             _tail = cur;
    203             _tail->_prev = cur->_prev;
    204             _tail->_next = NULL;
    205         }
    206     }
    207      
    208     void List::PushFront(DataType x)  //头插*
    209     {
    210         if (_head == NULL)
    211         {
    212             PushBack(x);
    213         }
    214         else
    215         {
    216             LinkNode* tmp = _head;
    217             _head = new LinkNode(x);
    218             _head->_next = tmp;
    219             tmp->_prev = _head;
    220         }
    221     }
    222      
    223     void List::PopFront()    //删除首节点
    224     {
    225         if (_head == NULL)
    226         {
    227             cout << "This SList is empty !" << endl;
    228             return;
    229         }
    230         LinkNode* tmp = _head;
    231         _head = _head->_next;
    232         _head->_prev = NULL;
    233         delete tmp;
    234     }
    235  
    236     //固定位置插入一个节点(这个函数需和Find函数搭配使用)
    237     //先用Find函数找到新节点需要插入的位置
    238     //(将Find函数的返回值传给Insert函数的参数pos),再在pos节点后面插入新节点x
    239     void List::Insert(LinkNode* pos, DataType x)   //*
    240     {
    241         assert(pos);
    242         if (pos == _tail)
    243         {
    244             PushBack(x);
    245         }
    246         else
    247         {
    248             LinkNode* tmp = new LinkNode(x);
    249             tmp->_next = pos->_next;
    250             pos->_next = tmp;
    251             tmp->_next->_prev = tmp;
    252             tmp->_prev = pos;
    253         }
    254     }
    255      
    256         //删除某一节点,同样,要先找到该节点并传参给Erase函数
    257     void List::Erase(LinkNode* pos)        
    258     {
    259         assert(pos);
    260         if (pos == _tail)
    261         {
    262             PopBack();
    263         }
    264         else if (pos == _head)
    265         {
    266             PopFront();
    267         }
    268         else
    269         {
    270             pos->_prev->_next = pos->_next;
    271             pos->_next->_prev = pos->_prev;
    272             delete pos;
    273         }
    274     }
    275      
    276     //查找节点并返回这个节点的地址
    277     LinkNode* List::Find(DataType x)       
    278     {
    279         if (_head == NULL)
    280         {
    281             cout << "This SList is empty !" << endl;
    282             return NULL;
    283         }
    284         else
    285         {
    286             LinkNode* tmp = _head;
    287             while (tmp != NULL)
    288             {
    289                 if (tmp->_data == x)
    290                 {
    291                     return tmp;
    292                 }
    293                 tmp = tmp->_next;
    294             } 
    295             return NULL;
    296         }
    297     }
    298      
    299     int List::Amount()   //计算链表节点的数目
    300     {
    301         if (_head == NULL)
    302         {
    303             return 0;
    304         }
    305         else
    306         {
    307             int count = 0;
    308             LinkNode* cur = _head;
    309             while (cur != _tail)
    310             {
    311                 count++;
    312                 cur = cur->_next;
    313             }
    314             return ++count;
    315         }
    316     }
    317      
    318     void List::Remove(DataType x)      //查找某节点并删除
    319     {
    320         if (_head == NULL)
    321         {
    322             cout << "This SList is empty !" << endl;
    323         }
    324         else
    325         {
    326             LinkNode* tmp = Find(x);
    327             if (tmp != NULL)
    328             {
    329                 Erase(tmp);
    330             }
    331         }
    332     }
    List.cpp
     1 #include"List.h"
     2 #include<stdlib.h>
     3 #include<iostream>
     4 using namespace std;
     5  
     6     void Test1()
     7     {
     8         List list1;
     9         list1.PushBack(1);
    10         list1.PushBack(2);
    11         list1.PushBack(3);
    12         list1.PushBack(4);
    13         list1.PushBack(5);
    14         list1.PushBack(6);
    15         list1.PrintSList();
    16  
    17     /*  List list2(list1);
    18         list2.PrintSList();*/
    19  
    20         List list2=list1;
    21         list2.PrintSList();
    22         //list2.PopBack();
    23         //list2.Clear();
    24         //list2.PushFront(0);
    25         //list2.PopFront();
    26  
    27         //////检验Find函数
    28         ////LinkNode* ret=list2.Find(4);
    29         ////if (ret != NULL)
    30         ////{
    31         ////    cout << "ret:" << ret << " " << ret->_data << endl;
    32         ////}
    33         ////else
    34         ////{
    35         ////    cout << "Not exit !" << endl;
    36         ////}
    37          
    38     /*  int ret=list2.Amount();
    39         cout << ret << endl;*/
    40  
    41         //list2.Erase(list2.Find(5));
    42         //list2.Insert(list2.Find(2), 0);
    43         //list2.Remove(3);
    44         list2.Reverse();
    45         list2.PrintSList();
    46     }
    47  
    48     int main()
    49     {
    50         Test1();
    51         system("pause");
    52     }
    Test.cpp
  • 相关阅读:
    C语言实现strcpy
    Sunday算法(字符串查找、匹配)
    C++实现堆栈
    Chrome DevTools 的 Sources 调试
    Android 时钟(由秒转变为时分秒)
    Android studio Suggestion: use tools:overrideLibrary=”jp.wasabeef.blurry” to force usage
    Android studio的 repositories配置多个url
    Android SurfaceView详解
    Android studio jni
    最齐全的Android studio 快捷键(亲测可用)
  • 原文地址:https://www.cnblogs.com/Lynn-Zhang/p/5398312.html
Copyright © 2011-2022 走看看