循环链表

本文介绍了使用C++实现循环链表的两种方法,一种是单指针方式,另一种是双指针方式,详细展示了如何构建、添加、删除节点及遍历链表,适用于需要高效访问链表头尾节点的应用场景。

在某些情况下可能会用到循环链表,其中的节点组成一个环:链表的长度是有限的,每个节点都有后继节点。

在循环单向链表的实现中,即使对链表的操作需要访问尾部节点及其头部节点,也可以只固定一个固定指针 tail。

用 C++ 进行对单指针的循环链表进行构建为:

// linked_lists.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H

using std::ostream;
using std::cout;
using std::endl;

class Circular_linked_list_node
{
public:
	int info;
	Circular_linked_list_node *next;
public:
	Circular_linked_list_node()
	{
		info = 0;
		next = nullptr;
	}

	Circular_linked_list_node(int i = 0, Circular_linked_list_node *p = nullptr)
	{
		info = i;
		next = p;
	}

	~Circular_linked_list_node() {};
};

class Circular_linked_list
{
public:
	Circular_linked_list_node *tail;

public:
	Circular_linked_list()
	{
		tail = nullptr;
	}

	bool isempty()
	{
		return tail == nullptr;
	}

	bool inlist(int) const;            // 表明不能修改 this 指针指向的对象

	void addtohead(int);

	void addtotail(int);

	int deletefromhead();

	int deletefromtail();

	void deleteselect(int);

	friend ostream & operator<<(ostream &, const Circular_linked_list &);

	~Circular_linked_list();
};

#endif // !LINKED_LIST_H
// linked_lists.cpp
#include <iostream>
#include "linked_lists.h"

bool Circular_linked_list::inlist(int i) const
{
	Circular_linked_list_node *tmp;
	for (tmp = tail->next; tmp != tail && !(tmp->info == i); tmp = tmp->next);
	if (tmp == tail)
		return i == tail->info;
	else
		return true;
}

void Circular_linked_list::addtohead(int i)
{
	if (isempty())
		tail = new Circular_linked_list_node(i, nullptr), tail->next = tail;
	else
		tail->next = new Circular_linked_list_node(i, tail->next);
}

void Circular_linked_list::addtotail(int i)
{
	if (isempty())
		tail = new Circular_linked_list_node(i, nullptr), tail->next = tail;
	else
		tail->next = new Circular_linked_list_node(i, tail->next), tail = tail->next;
}

int Circular_linked_list::deletefromhead()
{
	if (isempty())
		return 0;
	else
	{
		int i = tail->next->info;
		tail->next = tail->next->next;
		return i;
	}
}

int Circular_linked_list::deletefromtail()
{
	if (isempty())
		return 0;
	else
	{
		int i = tail->next->info;
		Circular_linked_list_node *tmp;
		for (tmp = tail->next; tmp->next != tail; tmp = tmp->next);
		tmp->next = tail->next;
		tail = tmp;
		return i;
	}
}

void Circular_linked_list::deleteselect(int i)
{
	if (!isempty())
	{
		Circular_linked_list_node *tmp,*prev;
		for (prev = tail,tmp = tail->next; tmp != tail && !(tmp->info == i); prev = prev->next,tmp = tmp->next);
		if (tmp->info == i)
			prev->next = tmp->next;
	}		
}

ostream & operator<<(ostream & out, const Circular_linked_list & p)
{
	Circular_linked_list_node *tmp;
	for (tmp = p.tail->next; tmp != nullptr && tmp != p.tail; tmp = tmp->next)
		out << tmp->info << " ";
	return out << p.tail->info;
}

Circular_linked_list::~Circular_linked_list()
{
	for (Circular_linked_list_node *p; !isempty();)
	{
		p = tail->next;
		delete tail;
		tail = p;
	}
}
// create_list.cpp
#include <iostream>
#include "linked_lists.h"

int main()
{
	using namespace std;

	//*********此处是循环链表——单指针测试代码********
	Circular_linked_list list3;

	cout << list3.isempty() << endl;

	list3.addtohead(1);
	list3.addtohead(2);
	list3.addtohead(3);
	list3.addtohead(4);
	list3.addtotail(5);
	list3.addtotail(6);
	list3.addtotail(7);
	list3.addtotail(8);
	list3.deletefromhead();
	list3.deletefromhead();
	list3.deletefromtail();
	list3.deletefromtail();
	list3.deleteselect(5);
	list3.deleteselect(12);

	cout << list3.inlist(1) << endl;
	cout << list3.inlist(10) << endl;
	cout << list3.isempty() << endl;
	cout << list3 << endl;
	//***********************************/

	system("pause");
	return 0;
}

同样的如果要删除最后一个元素,也需要通过循环进行遍历,对于这样的问题,可以设置两个指针 head 和 tail。

用 C++ 进行对双指针的循环链表进行构建为:

// linked_lists.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H

using std::ostream;
using std::cout;
using std::endl;

class Circular_linked_list_tnodes
{
public:
	int info;
	Circular_linked_list_tnodes *prev, *next;
public:
	Circular_linked_list_tnodes()
	{
		info = 0;
		prev = next = nullptr;
	}

	Circular_linked_list_tnodes(int i = 0, Circular_linked_list_tnodes *p = nullptr, Circular_linked_list_tnodes *q = nullptr)
	{
		info = i;
		prev = p;
		next = q;
	}

	~Circular_linked_list_tnodes() {};
};

class Circular_tnodes_linked_list
{
public:
	Circular_linked_list_tnodes *head, *tail;

public:
	Circular_tnodes_linked_list()
	{
		head = tail = nullptr;
	}

	bool isempty()
	{
		return tail == nullptr;
	}

	bool inlist(int) const;            // 表明不能修改 this 指针指向的对象

	void addtohead(int);

	void addtotail(int);

	int deletefromhead();

	int deletefromtail();

	void deleteselect(int);

	friend ostream & operator<<(ostream &, const Circular_tnodes_linked_list &);

	~Circular_tnodes_linked_list();
};

#endif // !LINKED_LIST_H
// linked_lists.cpp
#include <iostream>
#include "linked_lists.h"

bool Circular_tnodes_linked_list::inlist(int i) const
{
	Circular_linked_list_tnodes *tmp;
	for (tmp = head; tmp != tail && !(tmp->info == i); tmp = tmp->next);
	if (tmp == tail)
		return i == tail->info;
	else
		return true;
}

void Circular_tnodes_linked_list::addtohead(int i)
{
	if (isempty())
	{
		head = tail = new Circular_linked_list_tnodes(i, nullptr, nullptr);
		tail->next = head->prev = tail, tail->prev = head->next = head;
	}
	else
	{
		head = new Circular_linked_list_tnodes(i, tail, head);
		head->next->prev = head, head->prev->next = head;
	}
		
}

void Circular_tnodes_linked_list::addtotail(int i)
{
	if (isempty())
	{
		head = tail = new Circular_linked_list_tnodes(i, nullptr, nullptr);
		tail->next = head->prev = tail, tail->prev = head->next = head;
	}
	else
	{
		tail = new Circular_linked_list_tnodes(i, tail, head);
		tail->next->prev = tail, tail->prev->next = tail;
	}
		
}

int Circular_tnodes_linked_list::deletefromhead()
{
	if (isempty())
		return 0;
	else
	{
		int i = head->info;
		Circular_linked_list_tnodes *tmp = head;
		head = head->next;
		head->prev = tail, tail->next = head, delete tmp;
		return i;
	}
}

int Circular_tnodes_linked_list::deletefromtail()
{
	if (isempty())
		return 0;
	else
	{
		int i = head->info;
		Circular_linked_list_tnodes *tmp = tail;
		tail = tail->prev;
		head->prev = tail, tail->next = head, delete tmp;
		return i;
	}
}

void Circular_tnodes_linked_list::deleteselect(int i)
{
	if (!isempty())
	{
		Circular_linked_list_tnodes *tmp;
		for (tmp = head; tmp != tail && !(tmp->info == i); tmp = tmp->next);
		if (tmp->info == i)
			tmp->prev->next = tmp->next, tmp->next->prev = tmp->prev;
	}
}

ostream & operator<<(ostream & out, const Circular_tnodes_linked_list & p)
{
	Circular_linked_list_tnodes *tmp;
	for (tmp = p.head; tmp != nullptr && tmp != p.tail; tmp = tmp->next)
		out << tmp->info << " ";
	return out << p.tail->info;
}

Circular_tnodes_linked_list::~Circular_tnodes_linked_list()
{
	for (Circular_linked_list_tnodes *p; !isempty();)
	{
		p = head->next;
		delete head;
		head = p;
	}
}
// create_list.cpp
#include <iostream>
#include "linked_lists.h"

int main()
{
	using namespace std;

	//*********此处是循环链表——单节点测试代码********
	Circular_tnodes_linked_list list4;

	cout << list4.isempty() << endl;

	list4.addtohead(1);
	list4.addtohead(2);
	list4.addtohead(3);
	list4.addtohead(4);
	list4.addtotail(5);
	list4.addtotail(6);
	list4.addtotail(7);
	list4.addtotail(8);
	list4.deletefromhead();
	list4.deletefromhead();
	list4.deletefromtail();
	list4.deletefromtail();
	list4.deleteselect(5);
	list4.deleteselect(12);

	cout << list4.inlist(1) << endl;
	cout << list4.inlist(10) << endl;
	cout << list4.isempty() << endl;
	cout << list4 << endl;
	//***********************************/
	system("pause");
	return 0;
}

参考资料:

1. C++数据结构与算法:https://item.jd.com/29739898993.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值