双向链表 ( 数据结构 )

本文详细介绍了C++中双向链表的节点结构,包括proir指针,并展示了如何定义、创建、插入、删除以及获取长度的模板类DoubleLinkedList。重点讲解了头尾插入、移除节点的方法,以及空判断和友元操作符重载。
摘要由CSDN通过智能技术生成

双向链表

定义

  1. 双向链表的节点
    比起单链表的next指针, 双链表多了一个proir指针指向前面的节点
template <class T>
class Node {
public:
	T val;
	Node<T>*proir, *next;
	Node() : val(0), proir(nullptr), next(nullptr) {}
	Node(T v, Node<T>* p = nullptr, Node<T>* n = nullptr) : val(v), proir(p), next(n) {}
	~Node() {
		proir = nullptr;
		next = nullptr;
	}
};

定义及实现

template <class T>
class DoubleLinkedList {
private:
	size_t size;
	Node<T>*head, *tail;

public:
	DoubleLinkedList() : size(0), head(nullptr), tail(nullptr) {}
	~DoubleLinkedList() {
		while (head != nullptr) {
			Node<T> p = head;
			head = head->next;
			delete p;
		}
		tail = nullptr;
	}
	size_t length() {
		return size;
	}
	void insertHead(const T& t) {
		Node<T>* node = new Node<T>(t);
		if (head == nullptr) {
			head = node;
			tail = node;
		}
		else {
			node->next = head;
			head->proir = node;
			node->proir = nullptr;
			head = node;
		}
		++size;
	}
	void insertTail(const T& t) {
		Node<T>* node = new Node<T>(t);
		if (tail == nullptr) {
			tail = node;
			head = node;
		}
		else {
			tail->next = node;
			node->proir = tail;
			node->next = nullptr;
			tail = node;
		}
		++size;
	}
	void insert(size_t index, const T& t) {
		if (index > size)
			throw "Index out of range";
		if (index == size)
			insertTail(t);
		if (index == 0)
			insertHead(t);
		Node<T>*p = head, *node = new Node<T>(t);
		for (int i = 1; i < index; ++i) {
			p = p->next;
		}
		p->next->proir = node;
		node->proir = p;
		node->next = p->next;
		p->next = node;
	}
	T removeHead() {
		if (size == 0)
			throw "Exception : Remove form an empty List :(";
		--size;
		Node<T>* p = head;
		head = head->next;
		if (head != nullptr)
			head->proir = nullptr;
		else { // 最后一个
			tail = nullptr;
		}
		T ret = std::move(p->val);
		delete p;

		return ret;
	}
	T removeTail() {
		if (size == 0)
			throw "Exception : Remove form an empty List :(";
		--size;
		if (size == 0) { // 只有一个
			T t = head->val;
			delete head;
			head = nullptr;
			tail = nullptr;
			return t;
		}
		Node<T>* p = head;
		for (Node<T>* i = head; i->next != nullptr; i = i->next)
			p = i;
		Node<T>* node = p->next;
		T ret = std::move(node->val);
		p->next = nullptr;
		tail = p;
		delete node;
		return ret;
	}
	bool remove(const T& t) {
		if (size == 0)
			throw "Exception : Remove form an empty List :(";
		Node<T>* p = head;
		Node<T>* i = head;
		for (; i != nullptr && i->val != t; i = i->next) {
			p = i;
		}
		if (i == nullptr) { // 没有
			return false;
		}
		if (p == head) { // 第一个
			removeHead();
			return true;
		}
		--size;
		if (size == 0) { // 最后一个
			delete head;
			head = nullptr;
			tail = nullptr;
			return true;
		}
		Node<T>* node = p->next;
		p->next = node->next;
		node->next->proir = p;
		delete node;
		return true;
	}
	bool empty() {
		return size == 0 ? true : false;
	}
	friend std::ostream& operator<<(std::ostream& os, const DoubleLinkedList& l) {
		if (l.head != nullptr)
			for (Node<T>* i = l.head; i != nullptr; i = i->next) {
				os << i->val << " ";
			}
		else
			os << "null ";
		return os;
	}
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SVIP_Quanw

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

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

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

打赏作者

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

抵扣说明:

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

余额充值