【Weiss】【第03章】双链表例程

双链表因为多了个前向指针,需要考虑的特殊因素多了一倍

所以中间插入(这儿没写)和中间删除会比较复杂。

其它倒没什么特别的,代码如下。

 

测试代码

 1 #include <iostream>
 2 #include "double_linklist.h"
 3 using namespace std;
 4 using namespace doublelinklist;
 5 template class DList<int>;
 6 int main(void)
 7 {
 8     DList<int> number;
 9 
10     //测试插入
11     cout << "/*additem()*/" << endl;
12     number.additem(2);
13     number.additem(3);
14     number.additem(5);
15     number.additem(7);
16     number.additem(11);
17     number.additem(13);
18     number.additem(17);
19     number.traverse();
20     cout << "\n" << flush;
21     number.reverse();
22     cout << "\n/*end*/\n\n" << flush;
23 
24     //测试获取长度
25     cout << "/*length()*/" << endl;
26     cout << number.size() << endl;
27     cout << "/*end*/\n\n" << flush;
28 
29     //测试获得头元素
30     cout << "/*getfirst()*/" << endl;
31     cout << number.getfirst() << endl;
32     cout << "/*end*/\n\n" << flush;
33 
34     //测试删除存在的元素(头尾及中间元素各一)
35     cout << "/*remove()*/" << endl;
36     number.remove(2);
37     number.remove(5);
38     number.remove(17);
39     number.traverse();
40     cout << "\n" << flush;;
41     number.reverse();
42     cout << "\n/*end*/\n\n" << flush;
43 
44     //测试删除不存在的元素
45     cout << "/*remove()*/" << endl;
46     number.remove(19);
47     cout << "/*end*/\n\n" << flush;
48 
49     //测试清空,并测试从空表中删除元素
50     cout << "/*clear(),remove()*/" << endl;
51     number.clear();
52     number.remove(2);
53     cout << "/*end*/\n\n" << flush;
54 
55     system("pause");
56 }
57 
58 double_linklist_driver
View Code

实现代码

  1 #ifndef DOUBLELINKLIST
  2 #define DOUBLELINKLIST
  3 #include <iostream>  4 using namespace std;
  5 
  6 namespace doublelinklist
  7 {
  8 
  9 //链表节点模板
 10 template <typename T> struct Node
 11 {
 12     Node<T>() : next(nullptr),prev(nullptr){}
 13     Node<T>(const T &item, Node<T>* ptrn = nullptr, Node<T>* ptrp = nullptr) : data(item), next(ptrn), prev(ptrp){}
 14     T data;
 15     Node<T>* next;
 16     Node<T>* prev;
 17 };
 18 //头节点及链表主体操作
 19 template <typename T> class DList
 20 {
 21 //构造函数
 22 public:
 23     DList<T>() : length(0), front(nullptr){}
 24 //接口
 25 public:
 26     //返回长度
 27     unsigned int size()const{ return length; }
 28     //返回头指针
 29     Node<T>* begin()const{ return front; }
 30     //判断是否为空
 31     bool empty()const{ return length == 0; }
 32     //获得头元素
 33     T getfirst()const{ return front->data; }
 34     //获得尾元素
 35     T getlast()const{ return rear->data; }
 36     //#查找元素所在地址
 37     Node<T>* find(const T &item)const;
 38     //#尾部加入新元素
 39     bool additem(const T &item);
 40     //#删除指定元素
 41     bool remove(const T &item);
 42     //#遍历顺序输出链表元素
 43     void traverse()const;
 44     //#遍历倒序输出链表元素
 45     void reverse()const;
 46     //清空链表
 47     void clear();
 48 
 49 //辅助函数
 50 private:
 51     //#查找元素前驱
 52     Node<T>* find_prev(const T& item)const;
 53 //数据
 54 private:
 55     unsigned int length;
 56     Node<T>* front;
 57     Node<T>* rear;
 58 };
 59 
 60 //如果元素为头元素或元素不存在则返回nullptr,否则返回前驱
 61 template <typename T> Node<T>* DList<T>::find_prev(const T& item)const
 62 {
 63     if (length == 0)
 64         return nullptr;
 65     if (front->data == item)
 66         return nullptr;
 67     for (Node<T>* iter = front; iter->next != nullptr; iter = iter->next)
 68     {
 69         if (iter->next->data == item)
 70             return iter;
 71     }
 72     return nullptr;
 73 }
 74 //调用find_prev,如果元素存在则返回地址,不存在则返回nullptr
 75 template <typename T> Node<T>* DList<T>::find(const T &item)const
 76 {
 77     Node<T>* iter = find_prev(item);
 78     if (length == 0)
 79         return nullptr;
 80     if (front->data == item)
 81         return front;
 82     return iter->next;
 83 }
 84 template <typename T> bool DList<T>::additem(const T &item)
 85 {
 86     Node<T>* pnew = new Node<T>(item);
 87     //原链表无元素
 88     //头尾指针均指向新节点,且新节点前后指针默认为nullptr
 89     if (length == 0)
 90         front = rear = pnew;
 91     else
 92     {
 93         rear->next = pnew;
 94         pnew->prev = rear;
 95         rear = pnew;
 96     }
 97     ++length;
 98     return true;
 99 }
100 //删除操作相对复杂
101 template <typename T> bool DList<T>::remove(const T &item)
102 {
103     //先判断链表是否空避免front->data未定义
104     if (length == 0)                    
105     {
106         cout << "No data!" << endl;
107         return false;
108     }
109     Node<T>* iter = find_prev(item);
110     //find_prev返回nullptr,且首元素不等,说明链表中无此元素
111     if (iter == nullptr && front->data != item)    
112     {
113         cout << "Can not find!" << endl;
114         return false;
115     }
116     Node<T>* save;
117     //如果元素是首元素
118     //则仅需将save后继(如果存在)的前向指针改为nullptr
119     //如果save无后继,说明链表删除后为空,将rear置空
120     if (front->data == item)
121     {
122         save = front;
123         front = front->next;
124         if (save != rear)
125             save->next->prev = nullptr;
126         else
127             rear = nullptr;
128     }
129     //如果元素不是首元素
130     //则save的前驱iter的后向指针需改指向save后继
131     //同时,save后继(如果存在)的前向指针改为指向save的前驱iter
132     //如果save无后继,则rear要指向新的尾节点
133     else
134     {
135         save = iter->next;
136         iter->next = save->next;
137         if (save != rear)
138             save->next->prev = iter;
139         else
140             rear = iter;
141     }
142     delete save;
143     --length;
144     return true;
145 }
146 template <typename T> void DList<T>::traverse()const
147 {
148     if (length != 0)
149     {
150         for (Node<T>* iter = front; iter != nullptr; iter = iter->next)
151             cout << iter->data << ends;
152     }
153 }
154 template <typename T> void DList<T>::reverse()const
155 {
156     if (length != 0)
157     {
158         for (Node<T>* iter = rear; iter != nullptr; iter = iter->prev)
159             cout << iter->data << ends;
160     }
161 }
162 template <typename T> void DList<T>::clear()
163 {
164     Node<T>* iter;
165     while (front != nullptr)
166     {
167         iter = front;
168         front = front->next;
169         delete iter;
170     }
171     front = rear = nullptr;
172     length = 0;
173 }
174 }
175 #endif

 

转载于:https://www.cnblogs.com/catnip/p/4328897.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值