【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
【Weiss】【第03章】双链表例程相关推荐
- 数据结构思维 第五章 双链表
第五章 双链表 原文:Chapter 5 Doubly-linked list 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 本章回顾了上一个练习的结果,并介绍了List接口的 ...
- 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点...
题目 在单链表和双链表中删除倒数第K个节点 java代码 /*** @Description:在单链表和双链表中删除倒数第K个节点* @Author: lizhouwei* @CreateDate: ...
- (王道408考研数据结构)第二章线性表-第三节3:循环单链表和循环双链表
文章目录 一:循环链表定义 二:循环单链表 三:循环双链表 一:循环链表定义 循环链表:规定好头尾结点的指向形成成环状 循环单链表:其尾节点的next指针由原本的空改为指向头结点 循环双链表:其尾节点 ...
- (王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)
文章目录 一:双链表的定义 二:双链表代码描述 三:双链表的初始化 四:双链表的插入 五:双链表的删除 一:双链表的定义 双链表:双链表在单链表的基础上再增加一个指针域,用于指向它的前驱结点 二:双链 ...
- 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第03章 加工原料文本
第03章 加工原料文本 3.1 从网络和硬盘访问文本 电子书 处理的HTML 处理搜索引擎的结果 处理RSS 订阅 读取本地文件 从PDF.MS Word 及其他二进制格式中提取文本 捕获用户输入 N ...
- 链表问题2——在双链表中删除倒数第K个节点
题目 实现一个函数,可以删除双链表中倒数第K个节点. 要求 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 思路 双链表的思路与前一篇文章单链表的思路基本一致,注意last指针 ...
- Java数据结构和算法:数组、单链表、双链表
1. 概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的 ...
- C语言实现-双链表练习
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef int ElemType; 5 6 //定义双链表结点类型 7 8 ...
- c语言双链表排序交换节点_图解:单链表翻转的三种方式!
当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转. 单链表反转,反转后的效果如下: 看起来很简单,只需要将单链表所有结点的 nex ...
- c语言单字符输入和输出函数分别为,第03章单元总练习-实训-知识拓展.doc
第03章单元总练习-实训-知识拓展 <C语言程序设计> 单元总结单元练习 实训指导知识拓展 第三章 最简单的C程序设计 --顺序结构设计 班级: 姓名: 学号: 单元总结提升 本单元中,核 ...
最新文章
- 最全 Neo4j 可视化图形数据库的工具!
- 初识遗传算法 蚁群算法
- 超级计算机预测降雪,南方九省即将大雪纷飞?超级计算机:可能性增加,但还没有确定...
- html布局overflow,overflow的中文意思
- 信息收集——Web目录扫描
- Cocos2d-x之Log输出机制
- 转——深度学习之BN算法(Batch Normailization)
- day33 java的注解
- suse linux运行asp,Linux Supervisor的安装与使用入门---SuSE
- asp.net mvc(八)
- apache2.4 php5.5 配置,求助,apache2.4+php5.5,配置好不能运行,错误信息如下
- Spring 中的 bean 生命周期(代码实现)
- rsync用法详细解释
- 【Arch】Android 7 Nougat源码目录结构分析
- win7时间同步出错
- Scala基础(四)
- FileZilla 下载
- 好用免费的电脑摄像头录视频软件分享!
- 蓝牙耳机单次续航排名,续航最久的蓝牙耳机推荐
- 践行数字化工厂,用友网络助力宝舜实现智能制造