/*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++)的更多相关文章

  1. 数据结构:DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)

    单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果) 时间限制: 1S类别: DS:线性表->线性表应用 题目描述: 输入范例: -5345646757684654765867 ...

  2. 单链表的C++实现(采用模板类)

    采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作.  链表结构定义 定义单链表 ...

  3. C++实现一个单例模板类

    单例模式在项目开发中使用得比较多,一个单例的模板类显得很有必要,避免每次都要重复定义一个单例类型 //非多线程模式下的一个单例模板类的实现 // template_singleton.h #inclu ...

  4. 用c#实现单链表(程序代码已经验证,完全正确)

    1.程序的大致结构如下图: 2.下面依次列出各个类的代码 ①ILISTDs.cs  这是一个接口类,列出单链表的方法 using System; using System.Collections.Ge ...

  5. C++泛化单链表

    泛型单链表 单链表将每个数据分为节点,每个节点存储数据和指向下一个节点的指针.这样数据就不用在内存中使用连续的存储空间,有更大的灵活性. 这里将单链表分为节点类(Node)和链表类(singleLin ...

  6. C++ 单链表模板类实现

    单链表的C语言描述 基本运算的算法——置空表.求表的长度.取结点.定位运算.插入运算.删除运算.建立不带头结点的单链表(头插入法建表).建立带头结点的单链表(尾插入法建表),输出带头结点的单链表 #i ...

  7. 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  8. 数据结构-单链表-类定义2-C++

    上一次的C++链表实现两个单链表的连接不太理想,此次听了一些视频课,自己补了个尾插法,很好的实现了两个链表的连接,当然了,我也是刚接触,可能是C++的一些语法还不太清楚,不过硬是花了一些时间尽量在数据 ...

  9. C++中的链表节点用模板类和用普通类来实现的区别

    C++中的链表节点通常情况下类型都是一致的.因此我们可以用模板来实现. #include <iostream> using namespace std; template<typen ...

随机推荐

  1. httprunner3源码解读(3)client.py

    源码目录结构 ApiResponse 这个类没啥好说的 class ApiResponse(Response): """ 继承了requests模块中的Response类 ...

  2. k8s中部署springcloud

    安装和配置数据存储仓库MySQL 1.MySQL简介 2.MySQL特点 3.安装和配置MySQL 4.在MySQL数据库导入数据 5.对MySQL数据库进行授权 1.MySQL简介 MySQL 是一 ...

  3. k8s入坑之路(11)kubernetes服务发现

    kubernetes访问场景 1.集群内部访问 2.集群内部访问外部 3.集群外部访问内部 1.集群内部访问 1.pod之间直接ip通讯(利用calico通过路由表经过三层将ip流量转发)由于容器之间 ...

  4. TestNG 参数化应用

    一.第一种参数化方式(testng.xml配置参数) 1.新建ParameterDemo04类 2.拷贝类的路径 3.testng.xml配置类地址及参数 <?xml version=" ...

  5. django improperly configured

    ImproperlyConfigured: You must either define the environment variable DJANGO_SETTINGS_MODULE or call ...

  6. Django笔记&教程 0-1 前言

    Django 自学笔记兼学习教程第0章第1节--前言 点击查看教程总目录 1 最初的想法 自学Django已经有一段时间了,自认收获不少,学的还算可以,然而实际去做项目写代码的时候,很多用法记得不清, ...

  7. [atAGC050F]NAND Tree

    当$n$为偶数,暴力$o(n)$枚举第一次操作,以下只考虑$n$为奇数的情况 此时,$n-1$即操作次数为偶数,找到最小的$i$(其中$1\le i\le \frac{n-1}{2}$),满足第$2i ...

  8. [atAGC049F]Happy Sequence

    定义$L=2\cdot 10^{5}$,$g(x)=\sum_{i=1}^{n}|b_{i}-x|-|a_{i}-x|$,则合法当且仅当$\forall 0\le x\le L,g(x)\ge 0$, ...

  9. [loj3347]有趣的旅途

    考虑求出重心,以0为根建树,求出第 $i$个点的子树大小$sz[i]$($a(0,i)$),则满足$n-sz[i]\le \lfloor\frac{n}{2}\rfloor$的$sz[i]$中的最小值 ...

  10. mybatis-批量操作数据(list对象 )

    在实际工作中老是忘记 传入的参数和数据库参数名称要一致还是与实体类型一致导致很多笑话发生. 那我还是做个记录吧! dao层: int addRemark(@Param("list" ...