这种基础例程,如之前所提,会有一个实现和一个简单的测试代码。

链表其实没什么可说的,其实包括后面的栈和队列也没什么可说的,直接放代码吧。

下面这个是测试代码

 #include <iostream>
#include "linklist.h"
using namespace std;
using namespace linklist;
template class List<int>;
int main(void)
{
List<int> number; //测试插入
cout << "/*additem()*/" << endl;
number.additem();
number.additem();
number.additem();
number.additem();
number.additem();
number.traverse();
cout << "\n/*end*/\n\n"<< flush; //测试获取长度
cout << "/*length()*/" << endl;
cout << number.size() << endl;
cout << "/*end*/\n\n" << flush; //测试获得头元素
cout << "/*getfirst()*/" << endl;
cout << number.getfirst() << endl;
cout << "/*end*/\n\n" << flush; //测试删除存在的元素
cout << "/*remove()*/" << endl;
number.remove();
number.traverse();
cout << "\n/*end*/\n\n" << flush; //测试删除不存在的元素
cout << "/*remove()*/" << endl;
number.remove();
cout << "/*end*/\n\n" << flush; //测试清空,并测试从空表中删除元素
cout << "/*clear(),remove()*/" << endl;
number.clear();
number.remove();
cout << "/*end*/\n\n" << flush; system("pause");
}

主体

 #ifndef LINKLIST
#define LINKLIST #include <iostream>
using namespace std; namespace linklist
{ //链表节点模板
template <typename T> struct Node
{
Node<T>() : next(nullptr){}
Node<T>(const T &item, Node<T>* ptr = nullptr) : data(item), next(ptr){}
T data;
Node<T>* next;
};
//头节点及链表主体操作
template <typename T> class List
{
//构造函数
public:
List<T>() : length(), front(nullptr){}
//接口
public:
//返回长度
unsigned int size()const{ return length; }
//返回头指针
Node<T>* begin()const{ return front; }
//判断是否为空
bool empty()const{ return length == ; }
//获得头元素
T getfirst()const{ return front->data; }
//#查找元素所在地址
Node<T>* find(const T &item)const;
//#尾部加入新元素
bool additem(const T &item);
//#删除指定元素
bool remove(const T &item);
//#遍历并输出链表元素
void traverse()const;
//清空链表
void clear(); //辅助函数
private:
//#查找元素前驱
Node<T>* find_prev(const T& item)const;
//数据
private:
unsigned int length;
Node<T>* front;
}; //如果元素为头元素或元素不存在则返回nullptr,否则返回前驱
template <typename T> Node<T>* List<T>::find_prev(const T& item)const
{
if (length == )
return nullptr;
if (front->data == item)
return nullptr;
for (Node<T>* iter = front; iter->next != nullptr; iter = iter->next)
{
if (iter->next->data == item)
return iter;
}
return nullptr;
}
//调用find_prev,如果元素存在则返回地址,不存在则返回nullptr
template <typename T> Node<T>* List<T>::find(const T &item)const
{
Node<T>* iter = find_prev(item);
if (length == )
return nullptr;
if (front->data == item)
return front;
return iter->next;
}
template <typename T> bool List<T>::additem(const T &item)
{
Node<T>* pnew = new Node<T>(item);
if (length == )
front = pnew;
else
{
Node<T>* iter = front;
while (iter->next != nullptr)
iter = iter->next;
iter->next = pnew;
}
++length;
return true;
}
template <typename T> bool List<T>::remove(const T &item)
{
if (length == ) //先判断链表是否空避免front->data未定义
{
cout << "No data!" << endl;
return false;
}
Node<T>* iter = find_prev(item);
if (iter == nullptr && front->data != item)
{
cout << "Can not find!" << endl;
return false;
}
Node<T>* save;
if (front->data == item)
{
save = front;
front = front->next;
free(save);
}
else
{
save = iter->next;
iter->next = iter->next->next;
free(save);
}
--length;
return true;
}
template <typename T> void List<T>::traverse()const
{
if (length != )
{
for (Node<T>* iter = front; iter != nullptr; iter = iter->next)
cout << iter->data << ends;
}
}
template <typename T> void List<T>::clear()
{
Node<T>* iter;
while (front != nullptr)
{
iter = front;
front = front->next;
delete iter;
}
front = nullptr;
length = ;
}
}
#endif

【Weiss】【第03章】链表例程的更多相关文章

  1. 【Weiss】【第03章】链表例程的一些修改

    主要是,感觉原来的链表例程通过Node的分配形成了链表,但是没有自动消除Node的办法比较危险,一旦在clear()之前把链表赋了其它值就内存泄漏了. 所以改了析构函数,自动清理分配出来的内存.既然改 ...

  2. 【Weiss】【第03章】练习3.6:有序多项式相加

    [练习3.6] 编写将两个多项式相加的函数.不要毁坏输入数据.用一个链表实现. 如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少? 两个按幂次升序的多项式链表,分别维护一个指针. 幂较小 ...

  3. 【Weiss】【第03章】练习3.2

    [练习3.2] 给你一个链表L和另一个链表P,它们包含以升序排列的整数.操作printlots(L,P)将打印L中那些由P所指定的位置上的元素. 例如,如果p=1,3,4,6,那么,L的第一.第三.第 ...

  4. 第03章 AOP前奏

    第03章 AOP前奏 提出问题 ●情景:数学计算器 ●要求 ①执行加减乘除运算 ②日志:在程序执行期间追踪正在发生的活动 ③验证:希望计算器只能处理正数的运算 ●常规实现 ●问题 ○代码混乱:越来越多 ...

  5. 第03章_基本的SELECT语句

    第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖 ...

  6. suse 12 二进制部署 Kubernetets 1.19.7 - 第03章 - 部署flannel插件

    文章目录 1.3.部署flannel网络 1.3.0.下载flannel二进制文件 1.3.1.创建flannel证书和私钥 1.3.2.生成flannel证书和私钥 1.3.3.将pod网段写入et ...

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

    双链表因为多了个前向指针,需要考虑的特殊因素多了一倍 所以中间插入(这儿没写)和中间删除会比较复杂. 其它倒没什么特别的,代码如下. 测试代码 #include <iostream> #i ...

  8. 【Weiss】【第03章】练习3.3:通过交换指针交换单/双链表元素

    [练习3.3] 通过之调整指针(而不是数据)来交换两个相邻的元素,使用 a.单链表 b.双链表 Answer: 先放测试代码,折叠标题可以看到分别是哪种链表的测试. 实测可满足题意,但单链表和双链表的 ...

  9. 【Weiss】【第03章】队列例程

    前几个例程还是相当简单的,把链表即时改了一下就是队列了. 还有想了一下,决定这种例程的代码放法是:先把测试代码默认折叠放在前面,然后把实现代码默认展开放在后面. 测试代码如下: #include &l ...

随机推荐

  1. 公式化学习requests(第二卷)

    请求浏览器分为两种一种是不需要用户登录验证直接请求 另一种是需要用户登陆验证请求,现在说一下利用COOKIE实现,COOKIE在前端开发时有很多的作用,要熟练使用, 直接上代码了: 第一步:访问页面, ...

  2. python实现经典冒泡算法

    利用for循环,完成a=[1,7,4,89,34,2]的冒泡排序 冒泡排序:小的排在前,大的排在后面

  3. Nginx笔记总结九:Nginx日志配置

    ngx_http_log_module用来定义请求日志格式1. access_log指令 语法:   access_log path [format [buffer=size [flush=time] ...

  4. iPhoneSE2要在印度独家生产真得没戏?

    现在,关于iPhone SE2的消息层出不穷,总的来说,它是一款真实存在的手机,整体性能和iPhone5X/SE相似,大概可能差不多会加上一些"无线充电"之类的无聊功能.普通消费者 ...

  5. TCP-IP-part7-IP协议相关技术(一)

    仅凭IP是无法完成通信的,需要一些IP的辅助技术.这些技术的包格式可能不一样,但它们都是基于IP地址进行的,都是通过匹配路由表来进行的,只是功能不一样.例如DHCP分配IP地址,它只管通知这条信息,具 ...

  6. Myeclipse 错误An internal error has occurred 解决办法

    1. 给MyEclipse的快捷方式加个参数再重新启动一次.      步骤如下:右键选中快捷方式属性选项,在快捷方式页,目标一项最后加上-clean选项,如"C:\MyEclipse6\e ...

  7. 安装NSQ

    安装文档 https://nsq.io/deployment/installing.html 打开连接后,根据系统找到对应的二进制包 一般都是linux则下载 https://s3.amazonaws ...

  8. 快速入门和查询Python

    评分: 4.5 作者: Ryan Lu 类别:Python 时间: 1. 注释 三种方式: 单行注释以 # 开头 多行注释用三个单引号 ''' 将注释括起来 多行注释用三个双引号 "&quo ...

  9. SpringBoot图文教程8 — SpringBoot集成MBG「代码生成器」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

  10. go微服务框架kratos学习笔记十(熔断器)

    目录 go微服务框架kratos学习笔记十(熔断器) 什么是熔断 熔断器逻辑 kratos Breaker kratos 熔断逻辑 kratos熔断器使用说明 bladmaster client br ...