线性表--循环单链表

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);
}

运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值