CircularSingleLinkList.h
#pragma once
template <class DataType>
struct Node
{
DataType data;
Node<DataType> *next;
};
template <class DataType>
class CircularSingleLinkList
{
public:
CircularSingleLinkList();//无参数构造函数
CircularSingleLinkList(int n, DataType a[]);//有参数构造函数:用含n个元素的数组采用尾接法初始化循环单链表【尾接法】
~CircularSingleLinkList();//析构函数
int GetLength();//获得循环单链表长度
bool IsEmpty();//判断循环单链表是否为空
DataType GetValueByLocation(int i);//从头结点的下一结点起,按位查找返回循环单链表的第i个元素
DataType DeleteByLocation(int i);//从头结点的下一结点起,删除循环单链表的第i个元素并返回删除的值
DataType DeleteAtHead();//删除头部元素并返回删除的值
DataType DeleteAtTail();//删除尾部元素并返回删除的值
DataType GetMaxElement();//获得循环单链表的最大元素
DataType GetMinElement();//获得循环单链表的最小元素
Node<DataType> *GetFirst();//获得循环单链表的头结点指针
void Insert(int i, DataType x);//从头结点的下一结点起,按位插入元素
void InsertAtHead(DataType x);//在头部插入元素
void InsertAtTail(DataType x);//在尾部插入元素
void PrintSingleLinkList();//遍历循环单链表
void ClearSingleLinkList();//清空循环单链表
void SetValueAtLocation_iBy_x(int i, DataType x);//从头结点的下一结点起,设置位置i的元素的值为x
void SortSingleLinkList();//把循环单链表从小到大排序
private:
Node<DataType> *first;
};
CircularSingleLinkList.cpp
#include"CircularSingleLinkList.h"
template<class DataType>
CircularSingleLinkList<DataType>::CircularSingleLinkList()
{
first = new Node<DataType>;
first->next = first;
first->data = 0;
}
template<class DataType>
CircularSingleLinkList<DataType>::CircularSingleLinkList(int n, DataType a[])
{
first = new Node<DataType>;
Node<DataType> *temp = first;//temp作为尾指针
Node<DataType> *s;
for (int i = 0; i < n; i++) {
s = new Node<DataType>;
s->data = a[i];
temp->next = s;
temp = s;
}
temp->next = first;
first->data = n;
}
template<class DataType>
CircularSingleLinkList<DataType>::~CircularSingleLinkList()
{
Node<DataType> *p = first->next;
while (p != first)
{//先删去除了头结点的所有结点
Node<DataType> *q = p;
p = p->next;
delete q;
}
delete first;//最后删去头结点
}
template<class DataType>
int CircularSingleLinkList<DataType>::GetLength()
{
return first->data;
}
template<class DataType>
bool CircularSingleLinkList<DataType>::IsEmpty()
{
if (first->data == 0 || first->next == first)
return true;
else return false;
}
template<class DataType>
DataType CircularSingleLinkList<DataType>::GetValueByLocation(int i)
{
if (i > first->data || IsEmpty()) {
cout << "delete error!" << endl;
return -1;
}
Node<DataType> *p = first->next;
for (int j = 1; j < i; p = p->next) {
j++;
}
return p->data;
}
template<class DataType>
DataType CircularSingleLinkList<DataType>::DeleteByLocation(int i)
{
if (i > first->data || IsEmpty()) {
cout << "delete error!" << endl;
return -1;
}
int j = 1;
Node<DataType> *q = first;
Node<DataType> *p = first->next;
while (j < i)
{
q = p;
p = p->next;
j++;
}
q->next = p->next;
DataType temp = p->data;
first->data--;
delete p;
return temp;
}
template<class DataType>
DataType CircularSingleLinkList<DataType>::DeleteAtHead()
{
if (first->data ==0 || IsEmpty()) {
return -1;
}
Node<DataType> *p = first->next;
first->next = p->next;
DataType temp = p->data;
first->data--;
delete p;
return temp;
}
template<class DataType>
DataType CircularSingleLinkList<DataType>::DeleteAtTail()
{
if (first->data == 0 || IsEmpty()) {
return -1;
}
Node<DataType> *p = first;
Node<DataType> *q = first->next;
while (q->next != first)
{
p = q;
q = q->next;
}
p->next = first;
DataType temp = q->data;
first->data--;
delete q;
return temp;
}
template<class DataType>
DataType CircularSingleLinkList<DataType>::GetMaxElement()
{
if (first->data == 0 || IsEmpty()) {
cout << "get error!" << endl;
return -1;
}
Node<DataType> *p = first->next;
DataType max = p->data;
for (p = p->next; p != first; p = p->next) {
if (p->data > max) {
max = p->data;
}
}
return max;
}
template<class DataType>
DataType CircularSingleLinkList<DataType>::GetMinElement()
{
if (first->data == 0 || IsEmpty()) {
cout << "get error!" << endl;
return -1;
}
Node<DataType> *p = first->next;
DataType min = p->data;
for (p = p->next; p != first; p = p->next) {
if (p->data < min) {
min = p->data;
}
}
return min;
}
template<class DataType>
Node<DataType>* CircularSingleLinkList<DataType>::GetFirst()
{
if (first->data == 0 || IsEmpty()) {
cout << "get error!" << endl;
return nullptr;
}
return first;
}
template<class DataType>
void CircularSingleLinkList<DataType>::Insert(int i, DataType x)
{
if (first->data == 0 || IsEmpty() || i > first->data+1) {
cout << "insert error!" << endl;
return;
}
int j = 1;
Node<DataType> *q = first;
Node<DataType> *p = first->next;
while (j < i)
{
q = p;
p = p->next;
j++;
}
Node<DataType> *temp = new Node<DataType>;
temp->data = x;
q->next = temp;
temp->next = p;
first->data++;
}
template<class DataType>
void CircularSingleLinkList<DataType>::InsertAtHead(DataType x)
{
Node<DataType> *temp = new Node<DataType>;
temp->data = x;
temp->next = first->next;
first->next = temp;
first->data++;
}
template<class DataType>
void CircularSingleLinkList<DataType>::InsertAtTail(DataType x)
{
Node<DataType> *q = first;
while (q->next != first)
{
q = q->next;
}
Node<DataType> *temp = new Node<DataType>;
q->next = temp;
temp->next = first;
temp->data = x;
first->data++;
}
template<class DataType>
void CircularSingleLinkList<DataType>::PrintSingleLinkList()
{
if (first->data == 0 || IsEmpty()) {
cout << "print error!" << endl;
return;
}
int j = 0;
Node<DataType> *q = first->next;
while (q != first)
{
cout << q->data << " ";
q = q->next;
j++;
if (j % 50 == 0)
cout << endl;
}
cout << endl;
}
template<class DataType>
void CircularSingleLinkList<DataType>::ClearSingleLinkList()
{
Node<DataType> *p;
Node<DataType> *q = first->next;
while (q != first)
{
p = q;
q = q->next;
delete p;
}
first->next = first;
first->data = 0;
}
template<class DataType>
void CircularSingleLinkList<DataType>::SetValueAtLocation_iBy_x(int i, DataType x)
{
if (i > first->data || IsEmpty()) {
cout << "set error!" << endl;
return;
}
int j = 1;
Node<DataType> *p = first->next;
while (j < i)
{
p = p->next;
j++;
}
p->data = x;
}
template<class DataType>
void CircularSingleLinkList<DataType>::SortSingleLinkList()
{
if (first->data == 0 || IsEmpty()) {
cout << "sort error!" << endl;
return;
}
int i;
int N = first->data;
DataType *arr = new DataType[N];
Node<DataType> *p = first->next;
for (i = 0; p != first; p = p->next, i++) {//先把所有结点的数据提取到一个数组arr中存储
arr[i] = p->data;
}
DataType temp;
for (i = 1; i < N; i++) { //选用插入排序对数组arr从小到大排序
for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
for (i = 0, p = first->next; p != first; p = p->next, i++) {//为每个结点从小到大赋值
p->data = arr[i];
}
delete[] arr;
}
CircularSingleLinkListTest.cpp
#include<iostream>
#include"CircularSingleLinkList.cpp"
using namespace std;
void main()
{
float a[] = { -0.1, 2.5, 56, 4, 6.7, 8, -5.22, 23.4, -31.8, 9.999, 5.20, 37, -33.33 };
//float b[] = { 1, 6.6, 8.8, -7.5, -0.91, 52.033, 3.3, 3.20, 1.5, -4.4 };
CircularSingleLinkList<float> Test1(sizeof(a)/sizeof(a[0]), a);
cout << "打印尾接法初始化的循环单链表:";
Test1.PrintSingleLinkList();
cout << " 获得循环单链表1的长度:" << Test1.GetLength() << endl;
cout << " 获得循环单链表1的最大值:" << Test1.GetMaxElement() << endl;
cout << " 获得循环单链表1的最小值:" << Test1.GetMinElement() << endl;
cout << " 循环单链表1删除头部元素:" << Test1.DeleteAtHead() << endl;
cout << " 循环单链表1删除尾部元素:" << Test1.DeleteAtTail() << endl;
cout << " 打印循环单链表1:";
Test1.PrintSingleLinkList();
cout << " 获得循环单链表1的长度:" << Test1.GetLength() << endl;
cout << "循环单链表1位置为6的元素的值:" << Test1.GetValueByLocation(6) << endl;
cout << "循环单链表1删除位置为8的元素:" << Test1.DeleteByLocation(8) << endl;
cout << " 打印循环单链表2:";
Test1.PrintSingleLinkList();
cout << " 获得循环单链表1的长度:" << Test1.GetLength() << endl;
cout << "循环单链表1在头部插入元素1.21:" << endl;
Test1.InsertAtHead(1.21);
cout << " 循环单链表1在尾部插入元素-1:" << endl;
Test1.InsertAtTail(-1);
cout << " 打印循环单链表1:";
Test1.PrintSingleLinkList();
cout << " 获得循环单链表1的长度:" << Test1.GetLength() << endl;
cout << "设置循环单链表1中位置为8的元素为888:" << endl;
Test1.SetValueAtLocation_iBy_x(8,888);
cout << " 打印单链表1:";
Test1.PrintSingleLinkList();
cout << " 获得循环单链表1的长度:" << Test1.GetLength() << endl;
cout << " 循环单链表由小到大排序:" << endl;
Test1.SortSingleLinkList();
cout << " 打印循环单链表1:";
Test1.PrintSingleLinkList();
cout << " 判断循环单链表1是否为空表:" << Test1.IsEmpty() << endl;
cout << " 清空循环单链表1:" << endl;
Test1.ClearSingleLinkList();
cout << " 判断循环单链表1是否为空表:" << Test1.IsEmpty() << endl;
cout << "循环单链表1删除位置为5的元素:";
Test1.DeleteByLocation(5);
}
运行结果: