主要实现思想参考与王红梅、胡明、王涛编著的《数据结构c++》(第二版)
以及参考与博客:https://blog.csdn.net/qq_37934101/article/details/80747366
有什么不正确的地方或者不合适的地方欢迎指出
邮箱:22494749@qq.com
yx.telstudy.xyz
#include <bits/stdc++.h>
#define REP(i, a, b) for(int i = a; i < b; i++)
#define REP_(i, a, b) for(int i = a; i <= b; i++)
#define sl(n) scanf("%lld", &n);
#define si(n) scanf("%d", &n);
#define RepAll(a) for(auto x: a)
#define cout(ans) cout << ans << endl;
typedef long long ll;
/**
* This code has been written by YueGuang, feel free to ask me question. Blog: http://www.yx.telstudy.xyz
* created:2019.9.16
* crested:2019.9.18
* crested:2019.9.19
* crested:2019.9.21
* crested:2019.9.22
* crested:2019.9.23
* LinkList 链表学习
*/
using namespace std;
template<class T> class LinkList;
template<class T>
class node {
public:
//对结点进行初始化
node(const T rdata, node<T> *rnext = NULL):data(rdata),next(rnext) {};
//前面已经有节点了,新增节点后面直接连接空指针
node(node<T> * rnext = NULL):next(rnext) {};
//析构函数
~node() {}
//将链表定义为链表的友原函数便于链表要使用节点
friend class LinkList<T>;
private:
//数据域
T data;
//指针域
node<T> *next;
};
// T是数据 LinkList 指向自己
template<class T>
class LinkList {
public:
//无变量赋值,空表生成函数
LinkList();
//链表的复制函数
LinkList(LinkList<T> &rlist);
//使用一维数组初始化
LinkList(T a[], int n);
//将数据item插入到第i个位置上,原i包括i后数据后移一位
void Insert(int i, T item);
//删除链表中i位置的值,i位置后所有值向前移动一个位置,函数返回删除的值
T Delete(int i);
//按位查找
T Findplace(int i);
//按值查找
int Finddata(T fdata);
//返回链表长度
int length () const;
//返回item的后继;
T Next(T item)const;
//返回item的前驱;
T Prior(T item)const;
//判空
bool Empty() const;
//判满
bool Full()const;
bool IsIn(T)const;
//重载赋值运算符
LinkList<T>& operator=(const LinkList<T> &alist);
//按位查找,返回第i个元素的值;
T operator[](int i)const;
//将表置为空表;
void MakeEmpty();
//打印链表所有的值
void printLinkList();
//析构函数
~LinkList();
private:
//表头指针
node<T> * first;
};
//无参的构造函数
template<class T>
LinkList<T>::LinkList() {
LinkList first = new node<T>;
if(!first) {
throw "分配失败";
} else {
cout << "初始化成功" << '
';
first->next = NULL;
}
}
template<class T>
LinkList<T>::LinkList(T a[], int n) {
first = new node<T>;//头结点
if(!first) {
throw "空间分配失败";
}
node<T> *s;
first->next = NULL;//对指针域进行初始化
REP(i, 0, n) {
s = new node<T>;
if(!s) {
throw"空间分配失败";
}
s->data = a[i];
s->next = first->next;
first->next = s;
}
}
//不带头结点的插入
template<class T>
void LinkList<T>::Insert(int i, T x) {
node<T>*p, *s;
p = first;
int cnt = 0;
while(p && cnt < i-1) {
p = p->next;
cnt++;
}
if(p == NULL) {
throw "位置非法";
} else {
s = new node<T>;
s->data = x;
s->next = p->next;
p->next = s;
}
}
template<class T>
T LinkList<T>::Delete(int i) {
//删除i位置上的数据
node<T> *p = first;
int cnt = 0;
while(p && cnt < i - 1) {
p = p->next;
cnt++;
}
if(p == NULL || p->next == NULL) {
throw "位置";
} else {
node<T> *q = p->next;
T x = q->data;
p->next = q->next;
delete q;
return x;
}
}
template <class T>
int LinkList<T>::Finddata(T fdata) {
//按数据查找
int cnt = 1;
node<T> *p = first->next;//工作指针
while(p) {
if(p->data == fdata){
return cnt;
}
cnt++;
p = p->next;
}
if(p == NULL) {
throw "未查找到";
} else {
return cnt;
}
}
template <class T>
T LinkList<T>::Findplace(int i) {
//按位置查找
int cnt = 0;
node<T> *p = first->next;
while(cnt < i && p) {
p = p->next;
cnt++;
}
if(p == NULL) {
throw "超出";
} else {
return p->data;
}
}
template <class T>
void LinkList<T>::printLinkList() {
node<T> *p = first->next;
if(Empty()) {
cout << "链表为空,没有可用元素输出" << '
';
}
while(p) {
cout << p->data << '
';
p = p->next;
}
cout << '
';
return ;
}
template <class T>
int LinkList<T>::length()const {
int cnt = 0;
node<T> *p = first->next;
while(p) {
p = p->next;
cnt++;
}
return cnt;
}
template <class T>
LinkList<T>::~LinkList() {
node<T> *p;
while(first != NULL) {
p = first;
first = first->next;
delete p;
}
cout << "析构完成" << '
';
}
template <class T>
bool LinkList<T>::IsIn(T item) const {
node<T> *p = first->next;//工作指针
while(p) {
if(p->data == item)
return true;
p = p->next;
}
return false;
}
template <class T>
bool LinkList<T>::Full() const {
return false;
//判断空间是否已满
}
//重载赋值运算符
template<class T>
LinkList<T>& LinkList<T>::operator = (const LinkList & rlist) {
if(first == rlist.first) {
cout << "同一个链表" ;
return *this;
}
MakeEmpty();
cout << "开始复制" << '
';
node<T> *p , *q;//工作指针
q = first->next;
p = rlist.first->next;
REP(i, 0, rlist.length()) {
T x = p->data;
Insert(i+1, x);
p = p->next;
}
return *this;
}
//重载中括号运算符实现按位查找
template<class T>
T LinkList<T>::operator[](int t) const {
node<T> *p;
p = first->next;
int cnt = 1;
while(p && cnt < t) {
p = p->next;
cnt++;
}
if(p == NULL) {
return 0;
} else {
return p->data;
}
}
template<class T>
void LinkList<T>::MakeEmpty() {
node<T> *p, *q;
p = first->next;
while(p) {
q = p->next;
delete p;
p = q;
}
first->next = NULL;
}
template<class T>
bool LinkList<T>:: Empty() const { //判空
if(first->next == NULL)
return true;
else
return false;
}
int main() {
printf("链表功能测试,请输入 n = ");
int n;
cin >> n;
int *a = new int [n];
sort(a, a+n);
cout << "请输入n个数字";
for(int i = 0; i < n; i++) {
cin >> a[i];
}
cout << "---------测试一: 用数组对链表进行初始化---------" << '
';
LinkList<int> l(a, n);
l.printLinkList();
cout << "---------测试一结束---------" << '
';
cout << "---------测试二:在x位置差入数字 item
请输入x" << endl;
int x;
cin >> x;
cout << "请输入item__" ;
int item;
cin >> item;
l.Insert(x, item);
l.printLinkList();
cout << "---------测试二结束---------" << '
';
cout << "---------测试三:测试按位查找以及按值查找 ---------" << '
';
l.printLinkList();
int i;
cout << "请输入位置i";
cin >> i;
cout << " 查找结果:" << l[i] << endl;
int fdata;
cout << "请输入数据fdata" << '
';
cin >> fdata;
cout << fdata << "所在位置查找结果为 " << l.Finddata(fdata) << endl;
cout << "---------测试三结束---------" << '
';
}