单链表的模板类(C++)
/*header.h*/
#pragma once
#include<iostream>
using namespace std;
template<class T>
struct LinkNode //节点类定义
{
T data; //数据域
LinkNode<T> *next; //链指针域
LinkNode(LinkNode<T> *ptr = NULL){this->next = ptr;} //初始化指针域的构造函数
LinkNode(const T& item, LinkNode<T> *ptr = NULL)//初始化数据成员和指针成员和指针的构造函数
{
this->data = item;
this->next = ptr;
}
}; template<class T>
class List //用头结点的数据域表示链表元素数量
{
protected:
LinkNode<T> *first;
public:
List(){first = new LinkNode<T>;first->data = 0;}//无参数构造
List(const T& x)
{
this->first = new LinkNode<T>;
//first->data = 1;
this->inputHead(x);
}//含有参数的构造函数
List(List<T>& L);//拷贝构造
~List(){makeEmpty();}//析构函数
void makeEmpty();//将链表置空的函数
int Length()const{return this->first->data;}//计算链表长度的函数
LinkNode<T>* getHead()const{return this->first;}//返回附加头结点地址
LinkNode<T>* getRear()const;//返回尾部指针
void inputHead(T head);//头插
void inputRear(T rear);//尾插
void output();//将链表打印出来
bool IsEmpty()const{return !this->first->data;}
void Sort();//排序
bool Insert(int i, T& x);//在第i个位置插入x
bool Remove(int i, T& x);//删除第i个元素,将第i个元素的data赋值给x
T *getData(int i);//返回第i个元素的data地址
void setData(int i, T& x);//将第i个元素的data值更改为x
LinkNode<T> *Search(T x);//查找链表中第一个含有data为x的元素,返回x节点指针
LinkNode<T> *Locate(int i);//返回第i个元素的指针
List<T>& operator=(List<T>& L);//符号重载,赋值 };
template<class T>
List<T>& List<T>::operator=(List<T>& L)
{
if(!L.IsEmpty())
{
LinkNode<T> *srcptr = L.first, *desptr = this->first;
while(srcptr->next != NULL)
{
desptr->data = srcptr->data;
desptr->next = new LinkNode<T>;
srcptr = srcptr->next;
desptr = desptr->next;
}
desptr->data = srcptr->data;
}
return *this;
}
template<class T>
LinkNode<T>* List<T>::Locate(int i)//找第i个元素,找到返回地址,找不到返回头结点地址
{
if(i>0 && i<this->first->data)
{
int j = 0;
LinkNode<T> *tmp = this->first;
while(j!=i)
{
tmp = tmp->next;
++j;
}
return tmp;
}
return this->first;
}
template<class T>
LinkNode<T>* List<T>::Search(T x)
{
if(!this->IsEmpty())
{
LinkNode<T> *tmp = this->first->next;
while(tmp->data!=x && tmp->next!=NULL)
{
tmp = tmp->next;
}
if(tmp->data==x)
return tmp;
}
return this->first;
}
template<class T>
void List<T>::setData(int i, T& x)
{
if(i>0 && i<=this->first->data)
{
int j = 0;
LinkNode<T> *tmp = this->first;
while(j!=i)
{
tmp = tmp->next;
++j;
}
tmp->data = x;
}
}
template<class T>
T* List<T>::getData(int i)
{
if(i>0 && i<=this->first->data)
{
LinkNode<T> *tmp = this->first;
int j = 0;
while(j!=i)
{
tmp = tmp->next;
++j;
}
return &tmp->data;
}
}
template<class T>
bool List<T>::Remove(int i, T& x)
{
if(i>0 && i<=this->first->data)
{
LinkNode<T> *tmp = this->first, *p;
if(i!=1)
{
int j = 0;
while(j!=i-1)
{
tmp = tmp->next;
++j;
}
p = tmp->next;
tmp->next = p->next;
x = p->data;
delete p;
}
else
{
p = tmp->next;
x = p->data;
tmp->next = p->next;
delete p;
}
--this->first->data;
return true;
}
return false;
}
template<class T>
bool List<T>::Insert(int i, T& x)
{
if(i>0 && i<this->first->data+2)
{
if(i == this->first->data+1)
{
this->inputRear(x);
return true;
}
else if(i == 1)
{
this->inputHead(x);
return true;
}
int j = i-1;
LinkNode<T> *tmp = new LinkNode<T>, *p = this->first;
tmp->data = x;
while(j)
{
p = p->next;
--j;
}
tmp->next = p->next;
p->next = tmp;
++this->first->data;
return true;
}
else
return false; }
template<class T>
void List<T>::Sort()//排序有两类方法,一种是改变指针指向的,一种是仅为元素data排序,而不改变指针指向
{
if(this->first->data > 1)
{
int i = this->first->data, j;
LinkNode<T> *p = this->first, *q;
while(i)
{
p = p->next;
q = p->next;
j = i - 1;
while(j)
{
if(p->data > q->data)
{
p->data = p->data + q->data;
q->data = p->data - q->data;
p->data = p->data - q->data;
q = q->next;
}
--j;
}
--i;
}
}
}
template<class T>
void List<T>::inputHead(T head)
{
LinkNode<T> *tmp = new LinkNode<T>;
if(tmp == NULL)
{
cerr<<"内存分配错误!\n"<<endl;
exit(-1);
} if(this->first->next != NULL)
{
tmp->next = this->first->next;
this->first->next = tmp;
}
else
{
this->first->next = tmp;
tmp->next = NULL;
}
tmp->data = head;
++this->first->data; }
template<class T>
void List<T>::inputRear(T rear)
{
LinkNode<T> *tmp = new LinkNode<T>;
if(tmp == NULL)
{
cerr<<"内存分配错误!\n"<<endl;
exit(-1);
} LinkNode<T> *p = this->getRear();
p->next = tmp;
tmp->data = rear;
++this->first->data; }
template<class T>
void List<T>::output()
{
LinkNode<T> *p = this->first->next;
while(p!=NULL)
{
cout<<p->data<<"—>";
p = p->next;
}
cout<<"over"<<endl;
}
template<class T>
List<T>::List(List<T>& L)
{
T value;
LinkNode<T> *srcptr = L.getHead();
LinkNode<T> *desptr = this->first = new LinkNode<T>;
this->first->data = srcptr->data;
while(srcptr->next != NULL)
{
value = srcptr->next->data;
desptr->next = new LinkNode<T>(value);
desptr = desptr->next;
srcptr = srcptr->next;
}
desptr->next = NULL;
}
template<class T>
void List<T>::makeEmpty()
{
LinkNode<T> *p, *q = this->first->next;
this->first->data = 0;
while(q != NULL)
{
p = q;
q = q->next;
delete p;
}
}
template<class T>
LinkNode<T>* List<T>::getRear()const
{
LinkNode<T> *p = this->first;
while(p->next!=NULL)
p = p->next;
return p; }
/*
template<class T>
int List<T>::Length()const
{
LinkNode<T> *p = this->first->next;
int count = 0;
while(p != NULL)
{
++count;
p = p->next;
} };*/
一个含有头结点的单链表,链表头节点的数据与保存链表长度。
顺序表适合随机读,链表适合随机写,随机删除。
/*main.cpp*/
#include"header.h"
int main()
{
const int o = 10;
List<int> L(0),M;
for(int i=100; i<=110; ++i)
L.inputHead(i); //for(int i=0; i<=10; ++i)
// L.inputRear(i);
L.output();
int i = 2111;
L.Insert(1, i);
L.output();
L.Sort();
L.output();
L.Remove(1, i);
cout<<i<<endl;
L.output();
cout<<*L.getData(1)<<endl;i = 1;
L.setData(12, i);
L.output();
cout<<L.Search(100)<<endl;
M = L;
M.output();
return 0;
}
运行结果如下

单链表的模板类(C++)的更多相关文章
- 数据结构:DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)
单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果) 时间限制: 1S类别: DS:线性表->线性表应用 题目描述: 输入范例: -5345646757684654765867 ...
- 单链表的C++实现(采用模板类)
采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作. 链表结构定义 定义单链表 ...
- C++实现一个单例模板类
单例模式在项目开发中使用得比较多,一个单例的模板类显得很有必要,避免每次都要重复定义一个单例类型 //非多线程模式下的一个单例模板类的实现 // template_singleton.h #inclu ...
- 用c#实现单链表(程序代码已经验证,完全正确)
1.程序的大致结构如下图: 2.下面依次列出各个类的代码 ①ILISTDs.cs 这是一个接口类,列出单链表的方法 using System; using System.Collections.Ge ...
- C++泛化单链表
泛型单链表 单链表将每个数据分为节点,每个节点存储数据和指向下一个节点的指针.这样数据就不用在内存中使用连续的存储空间,有更大的灵活性. 这里将单链表分为节点类(Node)和链表类(singleLin ...
- C++ 单链表模板类实现
单链表的C语言描述 基本运算的算法——置空表.求表的长度.取结点.定位运算.插入运算.删除运算.建立不带头结点的单链表(头插入法建表).建立带头结点的单链表(尾插入法建表),输出带头结点的单链表 #i ...
- 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- 数据结构-单链表-类定义2-C++
上一次的C++链表实现两个单链表的连接不太理想,此次听了一些视频课,自己补了个尾插法,很好的实现了两个链表的连接,当然了,我也是刚接触,可能是C++的一些语法还不太清楚,不过硬是花了一些时间尽量在数据 ...
- C++中的链表节点用模板类和用普通类来实现的区别
C++中的链表节点通常情况下类型都是一致的.因此我们可以用模板来实现. #include <iostream> using namespace std; template<typen ...
随机推荐
- 升级npm后版本依然没有变 原来是全局npm设置的锅
最近准备给家里的老爷机打一个 react 的环境 win7系统还不算老~ 不过!由于很多年以前装的node了版本很低,所以赶紧去官网 下了一个 最新的稳定版本的. 卸载和安装都费了老大力了. 以为光明 ...
- 使用 @Transactional 时常犯的N种错误
@Transactional是我们在用Spring时候几乎逃不掉的一个注解,该注解主要用来声明事务.它的实现原理是通过Spring AOP在注解修饰方法的前后织入事务管理的实现语句,所以开发者只需要通 ...
- 菜鸡的Java笔记 第三十五 接口定义增强
接口定义增强 在java从一开始到现在接口之中的核心组成部分:抽象方法与全局常量,但是随着技术的不断发展,用户在使用过程之中发现了有一些问题 如果说现在有一个接口经过了长年 ...
- SpringCloud微服务实战——搭建企业级开发框架(十九):Gateway使用knife4j聚合微服务文档
本章介绍Spring Cloud Gateway网关如何集成knife4j,通过网关聚合所有的Swagger微服务文档 1.gitegg-gateway中引入knife4j依赖,如果没有后端代码编 ...
- [atAGC052C]Nondivisible Prefix Sums
当1为$a_{i}$中出现次数最多的元素(之一),则有以下结论-- 结论:$a_{i}$合法当且仅当$P\not\mid \sum_{i=1}^{n}a_{i}$且$\sum_{i=1}^{n}[a_ ...
- [hdu4582]DFS spanning tree
考虑每一条非树边都连接了祖先和儿子,类似于序列上的问题,从底往上算,当发现如果走到某个环的祖先,且这个环中还没有被选到,那么就将最浅的那条边贪心选择即可具体实现可以使用bitset维护当前子树的询问, ...
- Python 3 快速入门 1 —— 数据类型与变量
本文假设你已经有一门面向对象编程语言基础,如Java等,且希望快速了解并使用Python语言.本文对重点语法和数据结构以及用法进行详细说明,同时对一些难以理解的点进行了图解,以便大家快速入门.一些较偏 ...
- “微信小程序从分享卡片进入,第一次获取不到用户uid、第二次能获取到用户uid”解决方法
用uniapp开发微信小程序时,有一个需求是分享罐表详情页面给其它用户,其它用户(在已经登录的状态下)点击分享卡片可以直接跳转到该罐表详情页,且能显示自己是否已经收藏该罐表(收藏状态由用户uid和罐表 ...
- SpringSecurity 小demo
SpringSecurity 首先搭建好springboot工程,然后引入springsecurity依赖. <dependency> <groupId>org.springf ...
- Codeforces 1383D - Rearrange(构造)
Codeforces 题面传送门 & 洛谷题面传送门 一道不算困难的构造,花了一节英语课把它搞出来了,题解简单写写吧( 考虑从大往小加数,显然第三个条件可以被翻译为,每次加入一个元素,如果它所 ...