循环链表 ( 数据结构 )

本文介绍了循环链表的定义,提供了一个模板类`CircularLinkedList`的实现,包括头插法插入元素、删除指定元素、检查是否为空、获取链表长度以及合并两个链表的方法。同时,提供了测试用例展示其功能,如插入字符串元素并进行删除及合并操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

  1. 头节点
    和单链表一样, 只是最后一个节点的指针指向了头节点而不是nullptr
template <class T>
class Node {
public:
	T val;
	Node* next;
	Node() = default;
	Node(const T& t, Node* nxt = nullptr) : val(t), next(nxt) {}
};

定义及实现

template <typename T>
class CircularLinkedList {
private:
	Node<T>* head;
	size_t size;

public:
	CircularLinkedList() : size{ 0 }, head{ nullptr } {}
	~CircularLinkedList() {
		while (head != nullptr) {
			Node<T> p = head;
			head = head->next;
			delete p;
		}
	}
	/* 头插 */
	void insert(const T& t) {
		Node<T>* node = new Node<T>(t);
		if (head == nullptr) {
			head = node;
			head->next = head;
		}
		else {
			node->next = head->next;
			head->next = node;
		}
		++size;
	}
	bool remove(const T& t) {
		if (size == 0)
			throw "Exception : Remove form an empty List :(";
		Node<T>* p = head;
		Node<T>* i = head->next;

		// 要删的前一个
		for (; i->val != t && i != head; i = i->next) {
			p = i;
		}
		if (i == nullptr) { // 没有
			return false;
		}
		--size;
		if (size == 0) { // 只有一个
			delete head;
			head = nullptr;
		}
		else {
			Node<T>* node = p->next;
			p->next = node->next;
			head = p;
			delete node;
		}
		return true;
	}
	bool empty() { return size == 0 ? true : false; }
	unsigned length() const { return size; }
	Node<T>* getHead() const { return head; }
	void merge(CircularLinkedList<T>& l) {
		this->size += l.length();
		Node<T>*lhead = l.getHead(), *ltail = lhead, *tail = head;
		for (; ltail->next != lhead; ltail = ltail->next)
			;
		for (; tail->next != head; tail = tail->next)
			;
		tail->next = l.getHead();
		ltail->next = head;
	}
	friend std::ostream& operator<<(std::ostream& os, const CircularLinkedList& l) {
		if (l.head != nullptr) {
			for (Node<T>* i = l.head->next; i != l.head; i = i->next) {
				os << i->val << " ";
			}
			os << l.head->val;
		}
		else
			os << "null ";
		return os;
	}
};

测试

int main(int argc, char const* argv[]) {
	CircularLinkedList<string>* cl = new CircularLinkedList<string>();
	cl->insert("sda");
	cl->insert("sda1");
	cl->insert("sd2");
	cl->insert("sda3");
	cl->insert("sda4");
	cl->remove("sda");
	cout << *cl << "\n";
	CircularLinkedList<string>* cl1 = new CircularLinkedList<string>();
	cl1->insert("sda");
	cl1->insert("sda1");
	cl1->insert("sd2");
	cl1->insert("sda3");
	cl1->insert("sda4");
	cl1->remove("sda");
	cout << *cl1 << "\n";
	cl->merge(*cl1);
	cout << *cl << "\n";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SVIP_Quanw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值