单向循环链表的实现C++封装

单向循环链表的实现,用C++封装,先简单给出单项循环链表的算法(具体请参考本人的另一篇博文——单链表的实现),最后给出链表C++实现的代码并测试。单循环链表和单链表的实现大部分都相同,仅遍历条件等需要修改。

单链表的实现

定义单循环链表的节点类

//定义节点
class Node
{
public:
	//数据域
	double data;
	//指针域
	class Node *next;
};
在构造函数中使用尾插法生成单循环链表,也可以将初始化和生成链表的操作另写成一个函数。首先将类的私有数据节点(头结点)初始化;生成两个局部变量用于操作节点;使p指针始终指向尾节点;没生成一个新节点便将它连接到尾节点后并重新使p指向新的尾节点。

定义链表类,并申明私有数据成员。成员函数如下。

	//构建循环链表(尾插法)
	List(double a[], int n){
		Node *p, *s;
		int i;
		L = (Node *)malloc(sizeof(Node));
		p = L;//使p始终指向尾节点
		for (i = 0; i < n; i++){
			s = (Node *)malloc(sizeof(Node));
			//读入数据
			s->data = a[i];
			//链接
			p->next = s;
			//p指向新的尾节点
			p = s;
		}
		//将最后的尾节点的指针域赋值成空
		p->next = L;
	}
判断是否为空,若为空则头结点的指针域的值应为空

	//是否为空
	bool isEmpty(){
		return (L->next == NULL);
	}
在析构函数中释放单循环链表,注意判断条件与单链表的区别
	//析构
	~List(){
		//pre和p起始位置没有限制
		Node *pre = L->next, *p = pre->next;
		Node *s = L->next;//第一个数据节点
		while (p->next!=s){
			free(pre);
			pre = p;
			p = p->next;
		}
		free(pre);
	}
输出链表中的所有数据

	//输出
	void DisplayList(){
		//讨论不同情况
		if (isEmpty()){
			cout << "Empty." << endl;
		}
		else{
			//指向头第一个数据结点
			Node *p = L->next, *s = L->next;
			//自身地址(非遍历指针)不等于自身地址(遍历指针)
			while (p->next != s){
				cout << p->data << ends;
				p = p->next;
			}
			cout << endl;
		}
	}
在某一位置插入

	//插入
	bool NodeInsert(int i, double elem){
		//讨论两种情况
		if (isEmpty()){
			return false;
		}
		else{
			i--;//找到前一节点
			Node *p = L, *s = L, *pn;
			int j = 0;
			//找到位置
			while (i != j&&p->next != s){
				j++;
				p = p->next;
			}
			if (i != j&&p->next == s){
				return false;
			}
			//插入
			else{
				pn = (Node *)malloc(sizeof(Node));
				pn->data = elem;
				pn->next = p->next;
				p->next = pn;
				return true;
			}
		}
	}
查找对应序号下的值并取出该值

	//按序号查找并返回值
	bool GetElem(int i, double &elem){
		Node *p = L, *s = L;
		int j = 0;
		if (isEmpty()){
			return false;
		}
		else{
			//找到位置
			while (i!=j&&p->next != s){
				j++;
				p = p->next;
			}
			if (i != j&&p->next == s){
				return false;
			}
			else{
				//赋值结果
				elem = p->data;
				return true;
			}
		}
	}
判断单向循环链表中是否存在某一值,存在则返回第一个与之匹配的序号

	//按值查找并返回序号
	bool LocatElem(int &i, double elem){
		if (isEmpty()){
			return false;
		}
		else{
			Node *p = L, *s = L;
			int j = 0;
			//遍历搜索
			while (elem!=p->data&&p->next != s){
				j++;
				p = p->next;
			}
			if (elem != p->data&&p->next == s){
				return false;
			}
			else{
				//找到位置并传出值
				i = j;
				return true;
			}
		}
	}
删除指定节点

	//删除节点
	bool DeleteNode(int i){
		if (isEmpty()){
			return false;
		}
		else{
			i--;
			Node *p, *s = L, *pn = L;
			int j = 0;
			//遍历搜索
			while (i!=j&&pn->next != s){
				j++;
				pn = pn->next;
			}
			if (i!=j&&pn->next == s){
				return false;
			}
			else{
				//释放空间
				p = pn->next;
				pn->next = pn->next->next;
				free(p);
				return true;
			}
		}
	}

C++封装的完整代码如下:

/*
单循环链表
*/

#include<iostream>
using namespace std;
const int MAX_N = 100;
//定义节点
class Node
{
public:
	//数据域
	double data;
	//指针域
	class Node *next;
};

class List
{
public:
	//构建循环链表(尾插法)
	List(double a[], int n){
		Node *p, *s;
		int i;
		L = (Node *)malloc(sizeof(Node));
		p = L;//使p始终指向尾节点
		for (i = 0; i < n; i++){
			s = (Node *)malloc(sizeof(Node));
			//读入数据
			s->data = a[i];
			//链接
			p->next = s;
			//p指向新的尾节点
			p = s;
		}
		//将最后的尾节点的指针域赋值成空
		p->next = L;
	}
	//是否为空
	bool isEmpty(){
		return (L->next == NULL);
	}
	//析构
	~List(){
		//pre和p起始位置没有限制
		Node *pre = L->next, *p = pre->next;
		Node *s = L->next;//第一个数据节点
		while (p->next!=s){
			free(pre);
			pre = p;
			p = p->next;
		}
		free(pre);
	}
	//输出
	void DisplayList(){
		//讨论不同情况
		if (isEmpty()){
			cout << "Empty." << endl;
		}
		else{
			//指向头第一个数据结点
			Node *p = L->next, *s = L->next;
			//自身地址(非遍历指针)不等于自身地址(遍历指针)
			while (p->next != s){
				cout << p->data << ends;
				p = p->next;
			}
			cout << endl;
		}
	}
	//插入
	bool NodeInsert(int i, double elem){
		//讨论两种情况
		if (isEmpty()){
			return false;
		}
		else{
			i--;//找到前一节点
			Node *p = L, *s = L, *pn;
			int j = 0;
			//找到位置
			while (i != j&&p->next != s){
				j++;
				p = p->next;
			}
			if (i != j&&p->next == s){
				return false;
			}
			//插入
			else{
				pn = (Node *)malloc(sizeof(Node));
				pn->data = elem;
				pn->next = p->next;
				p->next = pn;
				return true;
			}
		}
	}
	//按序号查找并返回值
	bool GetElem(int i, double &elem){
		Node *p = L, *s = L;
		int j = 0;
		if (isEmpty()){
			return false;
		}
		else{
			//找到位置
			while (i!=j&&p->next != s){
				j++;
				p = p->next;
			}
			if (i != j&&p->next == s){
				return false;
			}
			else{
				//赋值结果
				elem = p->data;
				return true;
			}
		}
	}
	//按值查找并返回序号
	bool LocatElem(int &i, double elem){
		if (isEmpty()){
			return false;
		}
		else{
			Node *p = L, *s = L;
			int j = 0;
			//遍历搜索
			while (elem!=p->data&&p->next != s){
				j++;
				p = p->next;
			}
			if (elem != p->data&&p->next == s){
				return false;
			}
			else{
				//找到位置并传出值
				i = j;
				return true;
			}
		}
	}
	//删除节点
	bool DeleteNode(int i){
		if (isEmpty()){
			return false;
		}
		else{
			i--;
			Node *p, *s = L, *pn = L;
			int j = 0;
			//遍历搜索
			while (i!=j&&pn->next != s){
				j++;
				pn = pn->next;
			}
			if (i!=j&&pn->next == s){
				return false;
			}
			else{
				//释放空间
				p = pn->next;
				pn->next = pn->next->next;
				free(p);
				return true;
			}
		}
	}
private:
	Node *L;
};
int main()
{
	double a[MAX_N], res = 0;
	int n,i = 0;
	cout << "Input n:";
	cin >> n;
	for (i = 0; i < n; i++){
		cin >> a[i];
	}
	List m_list(a,n);
	m_list.DisplayList();
	cout << "Input i,element:";
	cin >> i >> res;
	m_list.NodeInsert(i,res);
	m_list.DisplayList();
	cout << "Input i:";
	cin >> i;
	if (m_list.GetElem(i, res)){
		cout << "Location " << i << " , element: ";
		cout << res << endl;
	}
	else{
		cout << "error." << endl;
	}
	cout << "Input element:";
	cin >> res;
	if (m_list.LocatElem(i, res)){
		cout << "element: " << res << " , location: ";
		cout << i << endl;
	}
	else{
		cout << "error." << endl;
	}
	cout << "Input Location i for delete:";
	cin >> i;
	if (m_list.DeleteNode(i)){
		cout << "Location " << i << " is deleted." << endl;
		m_list.DisplayList();
	}
	else{
		cout << "error." << endl;
	}
	return 0;
}
测试运行:














  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值