• 用C++写的带模板双向链表


      1 #ifndef _BLIST_H_
      2 #define _BLIST_H_
      3 
      4 #include <iostream>
      5 
      6 using namespace std;
      7 
      8 template<class T>
      9 class List{
     10 
     11 private:
     12     class Node{
     13     public:
     14         T data;
     15         Node * next;
     16         Node * prev;
     17         Node(const T & val=T())    :data(val),next(),prev(){}
     18         //在此节点后面添加节点new_node;
     19         void addNodeAfter( Node * new_node);
     20         //删除此节点后面一个节点,并释放占用内存
     21         void delNodeAfter();
     22     };
     23     
     24 private:
     25     Node * head;
     26     Node * tail;
     27     size_t size_;
     28 
     29 public:
     30     //分别为head,tail new 一个初始化的Node,并互相链接.
     31     List();
     32     
     33     /*read operation part
     34     *
     35     */
     36     //返回元素个数
     37     size_t size() const;
     38     //判断链表是否为空
     39     bool isEmpty() const;
     40     //读取链首元素的值,若没有元素,则返回head->data(后面以此处理);
     41     const T & getFirst() const;
     42     //读取链尾元素的值
     43     const T & getLast() const;
     44     //读取指定下标(1~size)处的值,若下标超出范围,则返回head->data
     45     const T & valueAt(size_t index) const;
     46     //依值返回节点
     47     Node * getNodeByVal(const T & item) const;
     48     //依值返回下标
     49     size_t getIndexByVal(const T & item) const;
     50     //依下标返回节点
     51     Node * getNodeByIndex(size_t index) const;
     52     //打印所有元素的值
     53     void showAll() const;
     54     
     55     /*write operation part
     56     *
     57     */
     58     //添加元素到链首
     59     void addFirst(const T & item);
     60     //添加元素到链尾
     61     void addLast(const T & item);
     62     //向指定下标处添加元素
     63     void addAt(size_t index, const T & item);
     64     //移除链首元素
     65     T removeFirst();
     66     //移除链尾元素
     67     T removeLast();
     68     //移除下标指定的元素
     69     T removeAt(size_t index);
     70     //移除同item等值的元素
     71     T removeVal(const T & item);
     72     //清理链表,释放内存。保留链首和链尾,以便再次使用.
     73     void clear();
     74     //销毁链表
     75     ~List();
     76 };
     77 
     78 template<class T>
     79 //注意此处嵌套类的定义使用文法
     80 void List<T>::Node::addNodeAfter(List<T>::Node * new_node)
     81 {
     82     new_node->prev = this;
     83     new_node->next = next;
     84     next->prev = new_node;
     85     next = new_node;
     86 }
     87 
     88 template<class T>
     89 void List<T>::Node::delNodeAfter()
     90 {
     91     next->next->prev = this;
     92     delete next;
     93     next = next->next;
     94 }
     95 
     96 template<class T>
     97 List<T>::List()
     98 {
     99     head = new Node;
    100     tail = new Node;
    101     head->next = tail;
    102     tail->prev = head;
    103     size_ = 0;
    104 }
    105 
    106 template<class T>
    107 size_t List<T>::size() const
    108 {
    109     return size_;
    110 }
    111 
    112 template<class T>
    113 bool List<T>::isEmpty() const
    114 {
    115     return size_ == 0;
    116 }
    117 
    118 template<class T>
    119 void List<T>::addFirst(const T & item)
    120 {
    121     Node * new_node = new Node(item);
    122     head->addNodeAfter(new_node);
    123     ++size_;
    124 }
    125 
    126 template<class T>
    127 void List<T>::addLast(const T & item)
    128 {
    129     Node * new_node = new Node(item);
    130     tail->prev->addNodeAfter(new_node);
    131     ++size_;
    132 }
    133 
    134 template<class T>
    135 void List<T>::addAt(size_t index, const T & item)
    136 {
    137     if(index <= 1)
    138         addFirst(item);
    139     else if(index > size_)
    140         addLast(item);
    141     else
    142     {
    143         Node * new_node = new Node(item);
    144         Node * pos = getNodeByIndex(index);
    145         pos->prev->addNodeAfter(new_node);
    146         ++size_;
    147     }
    148 }
    149 
    150 template<class T>
    151 const T & List<T>::getFirst() const
    152 {
    153     return head->next->data;
    154 }
    155 
    156 template<class T>
    157 const T & List<T>::getLast() const
    158 {
    159     return tail->prev->data;
    160 }
    161 
    162 template<class T>
    163 const T & List<T>::valueAt(size_t index) const
    164 {
    165     Node * retNode = getNodeByIndex(index);
    166     if(retNode == NULL)
    167         return head->data;
    168     return retNode->data;
    169 }
    170 
    171 template<class T>
    172 //返回嵌套类类型要用 typename 关键字注明类型,不然编译器报错
    173 typename List<T>::Node * List<T>::getNodeByVal(const T & item) const
    174 {
    175     Node * ret = head->next;
    176     while(ret != tail)
    177     {
    178         if(ret->data == item)
    179             return ret;
    180         ret = ret->next;
    181     }
    182     return NULL;
    183 }
    184 
    185 template<class T>
    186 size_t List<T>::getIndexByVal(const T & item) const
    187 {
    188     int ret = 0;
    189     Node * current = head->next;
    190     while(current != tail)
    191     {
    192         ++ret;
    193         if(current->data == item)
    194             return ret;
    195         current = current->next;
    196     }
    197     return 0;
    198 }
    199 
    200 template<class T>
    201 typename List<T>::Node * List<T>::getNodeByIndex(size_t index) const
    202 {
    203     if(index < 1 || index > size_)
    204         return NULL;
    205     Node * ret = head->next;
    206     for(int i = 1; i < index; i++)
    207         ret = ret->next;
    208     return ret;
    209 }
    210 
    211 template<class T>
    212 T List<T>::removeFirst()
    213 {
    214     if(isEmpty())
    215     {
    216         cout << "empty data!
    ";
    217         return T();
    218     }
    219     T ret = getFirst();
    220     head->delNodeAfter();
    221     --size_;
    222     return ret;
    223 }
    224 
    225 template<class T>
    226 T List<T>::removeLast()
    227 {
    228     if(isEmpty())
    229     {
    230         cout << "empty data!
    ";
    231         return T();
    232     }
    233     T ret = getLast();
    234     tail->prev->prev->delNodeAfter();
    235     --size_;
    236     return ret;
    237 }
    238 
    239 template<class T>
    240 T List<T>::removeAt(size_t index)
    241 {
    242     Node * del_node = getNodeByIndex(index);
    243     if(del_node == NULL)
    244         return head->data;
    245     T ret = del_node->data;
    246     del_node->prev->delNodeAfter();
    247     --size_;
    248     return ret;
    249 }
    250 
    251 template<class T>
    252 T List<T>::removeVal(const T & item)
    253 {
    254     Node * del_node = getNodeByVal(item);
    255     if(del_node == NULL)
    256         return head->data;
    257     T ret = del_node->data;
    258     del_node->prev->delNodeAfter();
    259     --size_;
    260     return ret;
    261 }
    262 
    263 template<class T>
    264 void List<T>::showAll() const
    265 {
    266     cout << "[";
    267     if(isEmpty())
    268     {
    269         cout << "]
    ";
    270         return;
    271     }
    272     Node * temp = head->next;
    273     while(temp != tail->prev)
    274     {
    275         cout << temp->data << ", ";
    276         temp = temp->next;
    277     }
    278     cout << temp->data << "]
    ";
    279 }
    280 
    281 template<class T>
    282 void List<T>::clear()
    283 {
    284     Node * del_node = NULL;
    285     Node * temp = head->next;
    286     while(temp != tail)
    287     {
    288         del_node = temp;
    289         temp = temp->next;
    290         delete del_node;
    291     }
    292     head->next = tail;
    293     tail->prev = head;
    294     size_ = 0;
    295 }
    296 
    297 template<class T>
    298 List<T>::~List()
    299 {
    300     clear();
    301     delete head;
    302     delete tail;
    303     head = tail = NULL;
    304 }
    305 
    306 #endif
    双向链表
     1 #include "blist.h"
     2 
     3 #include <iostream>
     4 #include <string>
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     List<int> list;
    10     list.addFirst(10);
    11     list.addLast(20);
    12     list.addLast(30);
    13     list.addFirst(5);
    14     list.addAt(1,3);
    15     list.addAt(10,100);
    16     cout << "list.size() = " << list.size() << endl;
    17     cout << "getFirst = " << list.getFirst() << endl;
    18     cout << "getLast = " << list.getLast() << endl;
    19     for(int i = 0; i <= list.size() +1; i++)
    20         cout << "valueAt("<< i << ") = " << list.valueAt(i) << endl;
    21     cout << "getIndexByVal(30) = " << list.getIndexByVal(30) << endl;
    22     list.showAll();
    23     list.removeAt(4);
    24     cout << "After remove index 4
    ";
    25     list.showAll();
    26     list.removeVal(5);
    27     cout << "After remove value 5
    ";
    28     list.showAll();
    29     cout << "After clear
    ";
    30     list.clear();
    31     list.showAll();
    32     return 0;
    33 }
    链表测试代码
  • 相关阅读:
    (winform cookie)如何向某网址Post信息,并得到CookieContainer以便以后直接通过验证
    NBear官方MSN群
    NBear 支持基于操作符重载的强类型Where及OrderBy查询
    NBear视频 0.1 NBear类库结构及功能简介[发布时间:9/5]
    NBear 使用Entity Configurator设置实体元数据、生成数据库创建脚本
    ORM中的继承关系映射全解——单表继承体系、一实体一具体表、一实体一扩展表、接口映射
    实例解析继承体系重构及ORM映射
    NBearV2.1.0,新增Oracle和MySql Db Provider,诚征测试
    NBear视频 1.1 实体定义基础[发布时间:9/5]
    使用主动实体(ActiveEntity)简化继承体系映射类的写操作
  • 原文地址:https://www.cnblogs.com/endenvor/p/7653699.html
Copyright © 2020-2023  润新知