LinkList的基本功能实现
LinkList的头文件
#pragma once
#include<iostream>
using namespace std;
template <typename DataType>
struct Node
{
DataType data; //数据域
Node* next; //指针域
};
template <typename DataType>
class LinkList
{
public:
LinkList(); //建立只有头结点的空链表
LinkList(DataType a[], int n); //建立n个元素的单链表
~LinkList(){delete first;}//析构函数
int Empty(); //判断线性表是否为空
int Length(); //求单链表的长度
DataType Get(int i); //按位查找 查找第i个节点的元素值
int Locate(DataType x); //按值查找 查找值为x的元素序号
void Insert(int i, DataType x); //插入操作 第i个位置插入值为x的结点
DataType Delete(int i); //删除操作 删除第i个结点
void PrintList(); //遍历操作 按序号依次输出各元素
void ReverseList(); //单链表逆置
void DeleteNode(LinkList& L, int mink, int maxk); //删除链表中大于mink且小于maxk的所有元素
private:
Node<DataType>* first; //单链表的头指针
Node<DataType>* rear;
};
template <typename DataType>
class JosephRing
{
public:
JosephRing();
JosephRing(int n);
~JosephRing();
void Joseph(int m);
private:
Node<DataType>* rear;
};
template <typename DataType>
LinkList<DataType>::LinkList()
{
first = new Node<DataType>; //生成头结点
first->next = nullptr; //头结点的指针区域置空
rear = first;
}
template <typename DataType>
int LinkList<DataType>::Empty() //判空操作
{
if (first->next == nullptr)
{
return 1;
}
else
{
return 0;
}
}
template <typename DataType>
int LinkList<DataType>::Length() //求单链表长度
{
Node<DataType>* p = first->next;
int count = 0;
while (p != nullptr)
{
p = p->next;
count++;
}
return count;
}
template <typename DataType>
DataType LinkList<DataType>::Get(int i)
{
Node<DataType>* p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr && count < i)
{
p = p->next; //指针p后移
count++;
}
if (p == nullptr)
{
cout << "* 查找位置错误";
}
else
{
return p->data;
}
}
template <typename DataType>
int LinkList<DataType>::Locate(DataType x)
{
Node<DataType>* p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr)
{
if (p->data == x)
{
return count; //查找成功返回序号
}
p = p->next;
count++;
}
return -1; //退出循环表表明查找失败
}
template <typename DataType>
void LinkList<DataType>::Insert(int i, DataType x)
{
Node<DataType>* p = first;
Node<DataType>* s = nullptr;
int count = 0;
while (p != nullptr && count < i - 1)
{
p = p->next; //工作指针p后移
count++;
}
if (p == nullptr)
{
cout << "* 插入位置错误" << endl; //没有找到第i个结点
}
else
{
s = new Node<DataType>; //申请结点s 值域
s->data = x;
s->next = p->next;
p->next = s; //将结点s插入到结点p之后
}
}
template <typename DataType>
DataType LinkList<DataType>::Delete(int i)
{
DataType x;
Node<DataType>* p = first;
Node<DataType>* q = nullptr;
int count = 0;
while (p != nullptr && count < i - 1) //结点不存在或者p的后继节点不存在
{
p = p->next;
count++;
}
if (p == nullptr || p->next == nullptr)
{
cout << "* 删除位置错误" << endl;
}
else
{
q = p->next; //暂存被删节点
x = q->data; //摘链
p->next = q->next;
return x;
}
}
template <typename DataType>
LinkList <DataType>::LinkList(DataType a[], int n) //头插法
{
first = new Node<DataType>;
first->next = nullptr; //初始化空链表
for (int i = 0; i < n; i++)
{
Node<DataType>* s = nullptr;
s = new Node<DataType>;
s->data = a[i];
s->next = first->next;
first->next = s; //将结点s插入头结点后
}
}
/*
template <typename DataType>
尾插法
LinkList<DataType>::LinkList(DataType a[], int n)
{
first = new Node<DataType>; //生成头结点
Node<DataType>* r = first;
Node<DataType>* s = nullptr; //尾指针初始化
for (int i = 0; i < n; i++)
{
s = new Node<DataType>;
s->data = a[i];
r->next = s;
r = s; //将结点s插入到终端结点之后
}
r->next = nullptr; //终端节点的指针域置空
}
*/
template <typename DataType>
void LinkList<DataType>::PrintList()
{
Node<DataType>* p = first->next;
while (p != nullptr)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
template <typename DataType>
void LinkList<DataType>::ReverseList() //逆置 将头结点后面的结点 依次通过指针指向 插入到head头结点之后
{
Node<DataType>* curr;
Node<DataType>* beh;
curr = first->next;
rear = first->next;
beh = curr->next;
while (beh != nullptr)
{
curr->next = first->next;
first->next = curr;
curr = beh;
beh = beh->next;
}
curr->next = first->next; //处理curr指向最后一个结点
first->next = curr;
rear->next = nullptr; //处理链表的尾部nullptr
}
template <typename DataType>
void LinkList<DataType>::DeleteNode(LinkList& L, int mink, int maxk) //删除链表中大于mink且小于maxk的所有元素
{
Node<DataType>* p = first->next;
Node<DataType>* q = first->next;
Node<DataType>* pre = first->next;
while (p != nullptr && p->data <= mink)
{
pre = p;
p = p->next;
}
if (p != nullptr)
{
while (p != nullptr && p->data < maxk)
{
p = p->next;
}
q = pre->next;
pre->next = p;
while (q != p)
{
Node<DataType>* s = first->next;
s = q->next;
delete q;
q = s;
}
}
}
template <typename DataType>
JosephRing<DataType>::JosephRing(){}
template <typename DataType>
JosephRing<DataType>::~JosephRing(){}
template <typename DataType>
JosephRing<DataType>::JosephRing(int n)
{
Node<DataType>* s = nullptr;
rear = new Node<DataType>;
rear->data = 1; //建立长度为1的循环单链表
rear->next = rear;
for (int i = 2; i <= n; i++) //依次插入数据域为2 3 4...n的结点
{
s = new Node<DataType>;
s->data = i;
s->next = rear->next;
rear->next = s;
rear = s;
}
}
template <typename DataType>
void JosephRing<DataType>::Joseph(int m)
{
Node<DataType>* pre = rear;
Node<DataType>* p = rear->next; //工作指针初始化
int count = 1;
cout << "* 出环的顺序为:";
while (p->next != p) //循环到链表中只剩一个结点
{
if (count < m) //计数器没有累加到key值(没到被杀编号
{
pre = p;
p = p->next;
count++;
}
else //到被杀编号
{
cout << p->data << " "; //输出被杀的人编号
pre->next = p->next; //将p摘链
delete p;
p = pre->next; //p后移 pre不动
count = 1; //计数器从1开始
}
}
cout << endl;
cout << "* 最后存活的人为:"<< p->data << " ";
cout << endl;
delete p; //释放最后一个结点
}
LinkList的main文件
#include<iostream>
#include "LinkList.h"
using namespace std;
int main()
{
int data[1000];
int n,i,x,nn;
int flag = 1;
int select;
int mink, maxk;
int key;
char ch;
cout << "***************************欢迎进入数据结构的世界****************************";
cout << endl;
cout << "* 这次进入的是单链表空间 *";
cout << endl;
cout << "* 首先需要建立单链表 *";
cout << endl;
cout << "* 请输入单链表长度:";
cin >> n;
cout << "* 请输入单链表数据:";
for (int j = 0; j < n; j++)
{
cin >> data[j];
}
LinkList<int>L(data, n);
cout << "*" << endl;
cout << "* 单链表为:";
L.PrintList();
while (flag)
{
cout << "* 请输入接下来所需要进行的操作序号:" << endl;
cout << "* 2、求单链表长度" << endl;
cout << "* 3、求单链表中第i个位置的数据元素的数值" << endl;
cout << "* 4、求数据元素x在单链表中的位置" << endl;
cout << "* 5、在第i个位置上插入一个数据元素" << endl;
cout << "* 6、删除单链表中第i个位置上的数据元素" << endl;
cout << "* 7、输出显示" << endl;
cout << "* 8、单链表逆置" << endl;
cout << "* 9、删除链表中大于mink且小于maxk的所有元素" << endl;
cout << "* 10、退出" << endl;
cout << "* 11、约瑟夫环" << endl;
cout << "*" << endl;
cout << "* 请选择:";
cin >> select;
cout << "*" << endl;
switch (select)
{
case 1:
case 2:
cout << "* 单链表长度为:" << L.Length() << endl;
break;
case 3:
cout << "* 请输入所需查找位置:";
cin >> i;
if (i > n)
{
cout << "* 查找位置错误" << endl;
cout << "*" << endl;
break;
}
else
{
cout << "* 第" << i << "个位置上的数值为:" << L.Get(i);
}
cout << endl << "*" << endl;
break;
case 4:
cout << "* 请输入数据元素x的值:";
cin >> x;
cout << "* 数据元素x在顺序表中的位置为:" << L.Locate(x);
cout << endl << "*" << endl;
break;
case 5:
cout << "* 请输入要插入的数据元素的位置:";
scanf_s("%d", &i);
cout << "* 请输入要插入的数据元素的值:";
scanf_s("%d", &x);
L.Insert(i, x);
cout << "*" << endl;
cout << "* 修改后顺序表为";
L.PrintList();
cout << "*" << endl;
break;
case 6:
cout << "* 请输入需要删除的第几个元素:";
cin >> i;
x = L.Delete(i);
if (x > 1e9)
{
cout << "* 无此节点" << endl;
}
else
{
cout << "* 删除的元素是:" << x << ",删除后数据为:";
}
L.PrintList();
break;
case 7:
cout << "* 当前顺序表为:";
L.PrintList();
cout << "*" << endl;
break;
case 8:
L.ReverseList();
cout << "* 逆置后的结果为:";
L.PrintList();
cout << "*" << endl;
break;
case 9:
cout << "* 请输入mink:";
scanf_s("%d", &mink);
cout << "* 请输入maxk:";
scanf_s("%d", &maxk);
L.DeleteNode(L, mink, maxk);
cout << "* 修改后链表为";
L.PrintList();
break;
case 10:
cout << "* 确定要退出该链表空间吗?" << endl;
cout << "* 残忍离开请输入Y 留下请输入N" << endl;
cout << "* ";
cin >> ch;
if (ch == 'Y')
{
cout << "* 期待下次与你再次相遇";
flag = 0;
break;
}
else if (ch == 'N')
{
cout << "* 继续在这个空间遨游吧" << endl;
cout << endl << "*" << endl;
break;
}
case 11:
cout << "* 请输入约瑟夫环长度:";
cin >> nn;
cout << "* 请输入密码:";
cin >> key;
JosephRing<int>R(nn);
R.Joseph(key);
break;
}
}
return 0;
}