C++封装链表list的简单实现(双向)

C++封装一个简单的linklist实现。本来没有写的意思的,做一道题目顺便就稍稍写了一下。

简单的做了一下,只实现了几个常用的功能而已。没有做迭代器,有点麻烦。只是写写而已,平时用还是STL或者Boost库的好。

测试代码在最下面

17-List 简单封装.h

   1: #ifndef _17_LIST_JDFZ_H__
   2: #include <iostream>
   3:  
   4:  
   5: template<typename T>
   6: struct listNode
   7: {
   8:     listNode<T>*    next;    //后继指针
   9:     listNode<T>*    prev;    //前驱指针
  10:     T            data;    //数据域
  11: };
  12:  
  13: template<typename T>
  14: class list
  15: {
  16: public:
  17:     list<T>();
  18:     ~list<T>();
  19:     list<T>& insertHead(T t);    //头插入
  20:     list<T>& insertTail(T t);    //尾插入
  21:     list<T>& merge(list& l);    //合并
  22:     list<T>& reverse();            //逆置链表
  23:     void show()const;            //显示
  24:  
  25:     list<T>& sort(bool(*less)(T t1 , T t2));        //排序
  26:     const listNode<T>* findValue(const T t)const;    //查找节点
  27:     bool update(int index , const T t);                //修改节点
  28:     list<T>& remove(const T t);                        //移除节点
  29: private:
  30:     listNode<T> voidNode;    //空的头节点
  31:     size_t        size;        //节点个数
  32: };
  33:  
  34:  
  35:  
  36:  
  37:  
  38: template<typename T>
  39: list<T>::list()
  40: {
  41:     //初始化头部空节点
  42:     voidNode.next = &voidNode;
  43:     voidNode.prev = &voidNode;
  44:     size = 0;
  45: }
  46:  
  47: template<typename T>
  48: list<T>::~list()
  49: {
  50:     listNode<T>* p = voidNode.next;    //头节点指针
  51:     while (p != &voidNode) {//没有走回到空节点
  52:         p = p->next;    //指向下一个
  53:         delete p->prev;    //删除前驱
  54:     }
  55:     voidNode.next = &voidNode;
  56:     voidNode.prev = &voidNode;
  57:     size = 0;
  58: }
  59:  
  60: //#######################################################################
  61: //头插入
  62: template<typename T>
  63: list<T>& list<T>::insertHead(T t)
  64: {
  65:     listNode<T>* temp = new listNode<T>;    //new 的时候一定要带类型
  66:     temp->data = t;    //保存数据
  67:     temp->next = voidNode.next;    //后继是原头节点
  68:     temp->prev = &voidNode;        //前驱是空节点
  69:  
  70:     voidNode.next = temp;        //空节点的后继是新的头节点
  71:     temp->next->prev = temp;    //原头节点的前驱是新头节点
  72:     size += 1;
  73:     return *this;
  74: }
  75: //#######################################################################
  76: //尾插入
  77: template<typename T>
  78: list<T>& list<T>::insertTail(T t)
  79: {
  80:     listNode<T>* temp = new listNode<T>;
  81:     temp->data = t;    //保存数据
  82:     temp->next = &voidNode;    //后继是空节点
  83:     temp->prev = voidNode.prev;    //前驱是原尾节点
  84:  
  85:     voidNode.prev = temp;    //指向新的最后的节点
  86:     temp->prev->next = temp;    //原本的最后节点的下一个指向新的尾节点
  87:  
  88:     size += 1;
  89:     return *this;
  90: }
  91: //#######################################################################
  92: //合并
  93: template<typename T>
  94: list<T>& list<T>::merge(list& l)
  95: {
  96:     voidNode.prev->next = l.voidNode.next;    //尾节点的下一个是外部list的头节点
  97:     l.voidNode.next->prev = voidNode.prev;//外部list的头节点的上一个是这个的尾节点
  98:  
  99:     voidNode.prev = l.voidNode.prev;    //新的尾节点是外部list的尾节点
 100:     l.voidNode.prev->next = &voidNode;    //新尾部节点的下一个是空节点
 101:  
 102:     size += l.size;
 103:     //外部list清空
 104:     l.voidNode.next = &l.voidNode;
 105:     l.voidNode.prev = &l.voidNode;
 106:  
 107:     return *this;
 108: }
 109: //#######################################################################
 110: // 排序链表    compare为判断函数
 111: template<typename T>
 112: list<T>& list<T>::sort(bool(*compare)(T t1 , T t2))
 113: {
 114:     listNode<T>* pfind;    //查找点指针
 115:     listNode<T>* ptemp;    //临时节点指针
 116:     listNode<T>* p = voidNode.next;    //头节点指针
 117:     while (p != &voidNode) {
 118:         //从头开始找可插入的位置
 119:         pfind = voidNode.next;    //从头节点开始找
 120:         while (pfind != p && compare(pfind->data , p->data)) {
 121:             //pfind不是p,且符合compare
 122:             pfind = pfind->next;    //走到下一个
 123:         }
 124:  
 125:         //temp要么等于p结束循环,要么不符合compare结束循环
 126:         ptemp = p->next;    //p的后继。在外面赋值是防止没有进入if语句,ptemp是野指针
 127:         if (pfind != p) {
 128:             std::cout << pfind->data << "<--->" << p->data << std::endl;
 129:             //将p插入到pfind所指节点前
 130:             //将p从链表取下
 131:             ptemp->prev = p->prev;    //p的下一个的前驱指向p的前驱
 132:             p->prev->next = ptemp;    //p的前驱的后继指向p的后继
 133:             //将p插入到pfind所指节点前
 134:             p->next = pfind;        //p的后继指向pfind
 135:             p->prev = pfind->prev;    //p的前驱指向pfind的前驱
 136:             p->prev->next = p;        //p(pfind)的前驱的后继是p
 137:             pfind->prev = p;        //pfind的前驱指向p
 138:         }
 139:         p = ptemp;
 140:     }
 141:     return *this;
 142: }
 143:  
 144: //#######################################################################
 145:  
 146: template<typename T>
 147: void  list<T>::show()const
 148: {
 149:     //正向遍历
 150:     listNode<T>* p = voidNode.next;    //头节点指针
 151:     while (p != &voidNode) {//没有走回到空节点
 152:         std::cout << p->data << " <==> ";
 153:         p = p->next;    //下一个
 154:     }
 155:     std::cout << "\tvoidNode" << std::endl;
 156:  
 157:     //反向遍历
 158:     p = voidNode.prev;    //尾节点指针
 159:     while (p != &voidNode) {//没有走回到空节点
 160:         std::cout << p->data << " <==> ";
 161:         p = p->prev;    //前驱
 162:     }
 163:     std::cout << "\tvoidNode" << std::endl;
 164: }
 165: //#######################################################################
 166:  
 167: template<typename T>
 168: const listNode<T>* list<T>::findValue(const T t)const
 169: {
 170:     listNode<T>* p = voidNode.next;    //头节点指针
 171:     while (p != &voidNode && p->data != t) {//没有走回到空节点
 172:         p = p->next;    //下一个
 173:     }
 174:     if (p == &voidNode) {
 175:         p = nullptr;
 176:     }
 177:     return p;
 178: }
 179: //#######################################################################
 180:  
 181: template<typename T>
 182: bool list<T>::update(int index , const T t)
 183: {
 184:     if (index > size) {
 185:         return false;
 186:     }
 187:  
 188:     listNode<T>* p = voidNode.next;    //头节点指针
 189:     while (--index) {
 190:         p = p->next;
 191:     }
 192:     p->data = t;
 193:     return true;
 194: }
 195: //#######################################################################
 196:  
 197: template<typename T>
 198: list<T>& list<T>::remove(const T t)
 199: {
 200:     listNode<T> temp;
 201:     listNode<T>* p = voidNode.next;    //头节点指针
 202:     while (p != &voidNode) {//没有走回到空节点
 203:         if (p->data != t) {
 204:             p = p->next;    //下一个
 205:             continue;
 206:         }
 207:         //移除节点
 208:         temp = *p;
 209:         temp.prev->next = temp.next;    //前驱的后继是本节点的后继
 210:         temp.next->prev = temp.prev;    //后继的前驱是本节点的前驱
 211:         delete p;    //删除节点
 212:         p = temp.next;    //p指向下一个
 213:     }
 214:     return *this;
 215: }
 216:  
 217: //#######################################################################
 218: //逆置链表
 219: template<typename T>
 220: list<T>& list<T>::reverse()
 221: {
 222:     listNode<T>* temp=nullptr;    //临时节点指针
 223:     listNode<T>* p = voidNode.next;    //头节点指针
 224:     
 225:     while (p != &voidNode) {//没有走回到空节点
 226:         //前驱=后继,后继=前驱
 227:         temp = p->next;    //保存下一个节点
 228:         p->next = p->prev;    //后继变前驱
 229:         p->prev = temp;    //前驱变后继
 230:         p = temp;    //下一个
 231:     }
 232:     //voidNode的反转
 233:     temp = voidNode.next;    //保存下一个节点
 234:     voidNode.next = voidNode.prev;    //后继变前驱
 235:     voidNode.prev = temp;    //前驱变后继
 236:     
 237:     return *this;
 238: }
 239:  
 240:  
 241: #endif // !_17_LIST_JDFZ_H__
 242:  
 243:  
 244:  

main.cpp

   1: #include <stdlib.h>
   2: #include "17-List 简单封装.h"
   3:  
   4: int main()
   5: {
   6: /**
   7:     list<char> hello;
   8:     hello.insertHead('l');
   9:     hello.insertHead('e');
  10:     hello.insertHead('h');
  11:     hello.insertTail('l');
  12:     hello.insertTail('o');
  13: 
  14:     hello.show();
  15: 
  16: 
  17:     list<char> world;
  18:     world.insertTail('r');
  19:     world.insertTail('l');
  20:     world.insertTail('d');
  21:     world.insertHead('o');
  22:     world.insertHead('w');
  23: 
  24:     world.show();
  25: 
  26:     hello.merge(world);
  27:     hello.show();
  28: 
  29:     hello.reverse();
  30:     hello.show();
  31: 
  32:     std::cout<<hello.findValue('o')->data << std::endl;
  33: 
  34:     hello.update(3 , 'X');
  35:     hello.update(13 , 'Y');
  36:     hello.show();
  37: 
  38: 
  39:     hello.remove('o');
  40:     hello.remove('h');
  41:     hello.remove('l');
  42:     hello.remove('e');
  43:     hello.remove('d');
  44:     hello.remove('w');
  45:     hello.remove('X');
  46:     hello.show();
  47: 
  48: */
  49:     list<char> shuzi;
  50:     shuzi.insertHead('1');
  51:     shuzi.insertHead('7');
  52:     shuzi.insertHead('5');
  53:     shuzi.insertHead('5');
  54:     shuzi.insertHead('4');
  55:     shuzi.insertHead('3');
  56:     shuzi.insertHead('6');
  57:     shuzi.show();
  58:     shuzi.sort([](char t1 , char t2)->bool{return t1 <= t2; });
  59:     shuzi.show();
  60:     system("pause");
  61:     return 0;
  62: }

你可能感兴趣的:(C++封装链表list的简单实现(双向))