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

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

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

测试代码

 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

【Weiss】【第03章】双链表例程相关推荐

  1. 数据结构思维 第五章 双链表

    第五章 双链表 原文:Chapter 5 Doubly-linked list 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 本章回顾了上一个练习的结果,并介绍了List接口的 ...

  2. 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点...

    题目 在单链表和双链表中删除倒数第K个节点 java代码 /*** @Description:在单链表和双链表中删除倒数第K个节点* @Author: lizhouwei* @CreateDate: ...

  3. (王道408考研数据结构)第二章线性表-第三节3:循环单链表和循环双链表

    文章目录 一:循环链表定义 二:循环单链表 三:循环双链表 一:循环链表定义 循环链表:规定好头尾结点的指向形成成环状 循环单链表:其尾节点的next指针由原本的空改为指向头结点 循环双链表:其尾节点 ...

  4. (王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)

    文章目录 一:双链表的定义 二:双链表代码描述 三:双链表的初始化 四:双链表的插入 五:双链表的删除 一:双链表的定义 双链表:双链表在单链表的基础上再增加一个指针域,用于指向它的前驱结点 二:双链 ...

  5. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第03章 加工原料文本

    第03章 加工原料文本 3.1 从网络和硬盘访问文本 电子书 处理的HTML 处理搜索引擎的结果 处理RSS 订阅 读取本地文件 从PDF.MS Word 及其他二进制格式中提取文本 捕获用户输入 N ...

  6. 链表问题2——在双链表中删除倒数第K个节点

    题目 实现一个函数,可以删除双链表中倒数第K个节点. 要求 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 思路 双链表的思路与前一篇文章单链表的思路基本一致,注意last指针 ...

  7. Java数据结构和算法:数组、单链表、双链表

    1. 概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的 ...

  8. C语言实现-双链表练习

    1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef int ElemType; 5 6 //定义双链表结点类型 7 8 ...

  9. c语言双链表排序交换节点_图解:单链表翻转的三种方式!

    当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转. 单链表反转,反转后的效果如下: 看起来很简单,只需要将单链表所有结点的 nex ...

  10. c语言单字符输入和输出函数分别为,第03章单元总练习-实训-知识拓展.doc

    第03章单元总练习-实训-知识拓展 <C语言程序设计> 单元总结单元练习 实训指导知识拓展 第三章 最简单的C程序设计 --顺序结构设计 班级: 姓名: 学号: 单元总结提升 本单元中,核 ...

最新文章

  1. 最全 Neo4j 可视化图形数据库的工具!
  2. 初识遗传算法 蚁群算法
  3. 超级计算机预测降雪,南方九省即将大雪纷飞?超级计算机:可能性增加,但还没有确定...
  4. html布局overflow,overflow的中文意思
  5. 信息收集——Web目录扫描
  6. Cocos2d-x之Log输出机制
  7. 转——深度学习之BN算法(Batch Normailization)
  8. day33 java的注解
  9. suse linux运行asp,Linux Supervisor的安装与使用入门---SuSE
  10. asp.net mvc(八)
  11. apache2.4 php5.5 配置,求助,apache2.4+php5.5,配置好不能运行,错误信息如下
  12. Spring 中的 bean 生命周期(代码实现)
  13. rsync用法详细解释
  14. 【Arch】Android 7 Nougat源码目录结构分析
  15. win7时间同步出错
  16. Scala基础(四)
  17. FileZilla 下载
  18. 好用免费的电脑摄像头录视频软件分享!
  19. 蓝牙耳机单次续航排名,续航最久的蓝牙耳机推荐
  20. 践行数字化工厂,用友网络助力宝舜实现智能制造

热门文章

  1. select标签multiple属性的使用方法
  2. SAX方式解析XML文档
  3. potplayer播放器没有声音的解决方案
  4. Address already in use: bind 端口被占用的解决办法
  5. jQuery点击文本框复制其内容到剪贴板上
  6. JS设为首页、添加到收藏夹
  7. 服务器支持raid2,服务器做RAID,如何选择RAID?
  8. pandas之combine_first() 合并重叠数据(修补)
  9. Python排序算法---冒泡排序
  10. mybatis-plus主键生成策略