NO.41十六届蓝桥杯备战|使⽤指针实现链表|打印|头插|头删|尾插|尾删|销毁|面向对象实现链表(C++)

什么是数据结构

数据结构是计算机的内存中存储和组织数据的⽅式。
数据结构关注如何以最有效的⽅式组织和存储数据,以便于在计算机程序中进⾏操作和处理

为什么需要数据结构

程序中如果不对数据进⾏管理,可能会导致数据丢失、操作数据困难、野指针等情况。
通过数据结构,能够有效将数据组织和管理在⼀起。
按照我们的⽅式任意对数据进⾏增、删、改、查等操作

常⻅的数据结构分类

数据结构⼀般根据组织形式,分为:线性数据结构和⾮线性数据结构。
线性的数据结构有:数组(顺序表)、链表、栈和队列等。
⾮线性的数据结构有:树、散列表、堆、图等。

链表的概念

链表是⼀种线性数据结构,由⼀系列节点组成,每个节点包含数据和指向下⼀个节点的指针。
链表中的元素在内存中不必顺序排列,⽽是通过指针相互连接。
![[Pasted image 20250315094633.png]]

链表的结构

链表的基本结构由节点组成,每个节点包含数据和指向下⼀个节点的指针

//链表节点类型的声明  
struct Node  
{  
	int data;  
	Node* next;  
};
链表的分类

链表可以分为单向链表、双向链表和循环链表。

  • 单向链表:每个节点只有⼀个指针指向下⼀个节点。
  • 双向链表:每个节点有两个指针,分别指向前⼀个节点和后⼀个节点
  • 循环链表:尾节点指向头节点。
    链表的结构⾮常多样,以下情况组合起来就有8种(2x2x2)链表结构:
    ![[Pasted image 20250315094856.png]]

动态申请链表节点和链表构建

动态申请节点并初始化

Node* createNode(int data)  
{  
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	
	return newNode;  
}

单链表元素的打印

打印链表的所有节点数据

void printList(Node* cur)  
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;  
}
#include <iostream>  
using namespace std;  
struct Node  
{  
	int data;  
	Node* next;  
};  

Node* createNode(int data)  
{  
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	return newNode;  
}  
void printList(Node* cur)  
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;
}

int main()  
{  
	Node* p1 = createNode(1);  
	Node* p2 = createNode(2);  
	Node* p3 = createNode(3);  
	Node* p4 = createNode(4);  
	p1->next = p2;  
	p2->next = p3;  
	p3->next = p4;  
	printList(p1);  
	
	return 0;  
}

单链表的头部插⼊元素

在链表的头部插⼊节点

void PushFront(Node*& ph, int data)  
{  
	Node* newNode = createNode(data);  
	newNode->next = ph;  
	ph = newNode;  
}
#include <iostream>  
using namespace std;  
struct Node  
{  
	int data;  
	Node* next;  
};  

Node* createNode(int data)  
{
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	return newNode;  
}  
void printList(Node* cur)  
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;  
}  
void PushFront(Node*& ph, int data)  
{  
	Node* newNode = createNode(data);  
	newNode->next = pn;  
	ph = newNode;  
}  
int main()  
{  
	Node* phead = nullptr;  
	PushFront(phead, 1);  
	PushFront(phead, 2);  
	PushFront(phead, 3);  
	PushFront(phead, 4);  
	printList(phead);  
	return 0;  
}

![[Pasted image 20250315100632.png]]

单链表的尾部插⼊元素

在链表的尾部插⼊节点

void PushBack(Node*& phead, int x)  
{  
	Node* newnode = createNode(x);  
	// 1、空链表  
	// 2、⾮空链表  
	if (phead == nullptr)  
	{  
		phead = newnode;  
	}  
	else  
	{  
		Node* tail = phead;  
		while (tail->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		tail->next = newnode;  
	}  
}
#include <iostream>  
using namespace std;  
struct Node  
{  
	int data;  
	Node* next;  
};  

Node* createNode(int data)  
{  
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	return newNode;  
}  
void printList(Node* cur)
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;  
}  

void PushBack(Node*& phead, int x)  
{  
	Node* newnode = createNode(x);  
	// 1、空链表  
	// 2、⾮空链表  
	if (phead == nullptr)  
	{  
		phead = newnode;  
	}  
	else  
	{  
		Node* tail = phead;  
		while (tail->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		tail->next = newnode;  
	}  
}  
int main()  
{  
	Node* phead = nullptr;  
	PushBack(phead, 1);  
	PushBack(phead, 2);  
	PushBack(phead, 3);  
	PushBack(phead, 4);  
	printList(phead);  
	return 0;  
}

单链表头部删除元素

void PopFront(Node*& phead)
{  
	// 空  
	if (phead == nullptr)  
	{  
		cout << "链表为空,没有元素可以删除了" << endl;  
		return;  
	}  
	//⾮空  
	Node* tmp = phead;  
	phead = phead->next;  
	delete tmp;  
	tmp = nullptr;  
}
#include <iostream>  
using namespace std;  
struct Node  
{  
	int data;  
	Node* next;  
};  

Node* createNode(int data)  
{  
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	return newNode;  
}  

void printList(Node* cur)  
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;  
}

void PushBack(Node*& phead, int x)  
{  
	Node* newnode = createNode(x);  
	// 1、空链表  
	// 2、⾮空链表  
	if (phead == nullptr)  
	{  
		phead = newnode;  
	}  
	else  
	{  
		Node* tail = phead;  
		while (tail->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		tail->next = newnode;  
	}  
}  

void PopFront(Node*& phead)  
{  
	// 空  
	if (phead == nullptr)  
	{  
		cout << "链表为空,没有元素可以删除了" << endl;  
		return;  
	}  
	//⾮空  
	Node* tmp = phead;  
	phead = phead->next;  
	delete tmp;  
	tmp = nullptr;  
}  

int main()  
{  
	Node* phead = nullptr;  
	PushBack(phead, 1);  
	PushBack(phead, 2);  
	PushBack(phead, 3);  
	PushBack(phead, 4);  
	printList(phead);  
	//头部删除并打印  
	PopFront(phead);
	printList(phead);  
	PopFront(phead);  
	printList(phead);  
	PopFront(phead);  
	printList(phead);  
	PopFront(phead);  
	printList(phead);  
	PopFront(phead);  
	printList(phead);  
	return 0;  
}

单链表尾部删除元素

void PopBack(Node*& phead)  
{  
	//空链表  
	if (phead == nullptr)  
	{  
		cout << "链表为空,没有元素可以删除了" << endl;  
		return;  
	}  
	// 1、⼀个节点  
	// 2、⼀个以上节点  
	if (phead->next == nullptr)  
	{  
		free(phead);  
		phead = nullptr;  
	}  
	else  
	{  
		// 找尾  
		Node* tail = phead;  
		while (tail->next->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		free(tail->next);  
		tail->next = nullptr;
	}  
}
#include <iostream>  
using namespace std;  
struct Node  
{  
	int data;  
	Node* next;  
};  
Node* createNode(int data)  
{  
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	return newNode;  
}  
void printList(Node* cur)  
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;  
}  
void PushBack(Node*& phead, int x)  
{  
	Node* newnode = createNode(x);  
	// 1、空链表  
	// 2、⾮空链表  
	if (phead == nullptr)  
	{  
		phead = newnode;  
	}  
	else  
	{  
		Node* tail = phead;
		while (tail->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		tail->next = newnode;  
	}  
}  
void PopBack(Node*& phead)  
{  
	//空链表  
	if (phead == nullptr)  
	{  
		cout << "链表为空,没有元素可以删除了" << endl;  
		return;  
	}  
	// 1、⼀个节点  
	// 2、⼀个以上节点  
	if ((phead)->next == nullptr)  
	{  
		delete phead;  
		phead = nullptr;  
	}  
	else  
	{  
		// 找尾  
		Node* tail = phead;  
		while (tail->next->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		delete tail->next;  
		tail->next = nullptr;  
	}  
}  
int main()  
{  
	Node* phead = nullptr;  
	PushBack(phead, 1);  
	PushBack(phead, 2);  
	PushBack(phead, 3);  
	PushBack(phead, 4);  
	printList(phead);
	//头部删除并打印  
	PopBack(phead);  
	printList(phead);  
	PopBack(phead);  
	printList(phead);  
	PopBack(phead);  
	printList(phead);  
	PopBack(phead);  
	printList(phead);  
	PopBack(phead);  
	printList(phead);  
	return 0;  
}

释放链表的所有节点

当链表不再需要的时候,申请的节点资源最好能释放掉,否则可能带来内存泄漏的⻛险。所有我们再提供⼀个函数,释放链表的所有节点。其实这个就很简单了,我们调⽤⼀个删除元素的函数,直到把链表删除为空链表就释放了所有的节点。

void PopFront(Node* & ph)  
{  
	// 空  
	if (ph == nullptr)  
	{  
		cout << "链表为空,没有元素可以删除了" << endl;  
		return;  
	}  
	//⾮空  
	Node* tmp = ph;  
	ph = ph->next;  
	delete tmp;  
	tmp = nullptr;  
}  

void DestropList(Node* & ph)  
{
	while(ph)  
	{  
		PopFront(ph);  
	}  
}
#include <iostream>  
using namespace std;  
struct Node  
{  
	int data;  
	Node* next;  
};  

Node* createNode(int data)  
{  
	Node* newNode = new Node;  
	newNode->data = data;  
	newNode->next = nullptr;  
	return newNode;  
}  
void printList(Node* cur)  
{  
	while (cur != nullptr)  
	{  
		cout << cur->data << "-->";  
		cur = cur->next;  
	}  
	cout << "nullptr" << endl;  
	cout << endl;  
}  
void PushBack(Node*& phead, int x)  
{  
	Node* newnode = createNode(x);  
	// 1、空链表  
	// 2、⾮空链表  
	if (phead == nullptr)  
	{  
		phead = newnode;  
	}
	else  
	{  
		Node* tail = phead;  
		while (tail->next != nullptr)  
		{  
			tail = tail->next;  
		}  
		tail->next = newnode;  
	}  
}  
void PopFront(Node*& ph)  
{  
	// 空  
	if (ph == nullptr)  
	{  
		cout << "链表为空,没有元素可以删除了" << endl;  
		return;  
	}  
	//⾮空  
	Node* tmp = ph;  
	ph = ph->next;  
	delete tmp;  
	tmp = nullptr;  
}  
void DestropList(Node*& ph)  
{  
	while(ph)  
	{  
		PopFront(ph);  
	}  
}  
int main()  
{  
	Node* phead = nullptr;  
	PushBack(phead, 1);  
	PushBack(phead, 2);  
	PushBack(phead, 3);  
	PushBack(phead, 4);  
	printList(phead);  
	//释放链表  
	DestroyList(phead);
	return 0;  
}

⾯向对象的⽅式实现链表

#include <iostream>  
using namespace std;  
//节点类型声明  
struct Node  
{  
	int data;  
	Node* next;  
};  

struct List  
{  
	//指向头节点的指针  
	Node* phead;  
	//成员函数  
	
	//构造函数  
	List()  
	{  
		cout << "构造函数调⽤" << endl;  
		phead = nullptr;  
	}  
	
	//析构函数 - 在结束时释放所有剩余节点  
	~List()  
	{  
		cout << "析构函数" << endl;  
		while (phead)  
		{  
			PopFront();  
		}  
	}  
	
	//创建节点  
	Node* createNode(int data)  
	{  
		Node* newNode = new Node;  
		newNode->data = data;
		newNode->next = nullptr;  
		return newNode;  
	}  
	
	//打印链表  
	void printList()  
	{  
		Node* cur = phead;  
		while (cur != nullptr)  
		{  
			cout << cur->data << "-->";  
			cur = cur->next;  
		}  
		cout << "nullptr" << endl;  
		cout << endl;  
	}  
	//头部添加元素  
	void PushFront(int data)  
	{  
		Node* newNode = createNode(data);  
		newNode->next = phead;  
		phead = newNode;  
	}  
	
	//头部删除元素  
	void PopFront()  
	{  
		// 空  
		if (phead == nullptr)  
		{  
			cout << "链表为空,没有元素可以删除了" << endl;  
			return;  
		}  
		//⾮空  
		Node* tmp = phead;  
		phead = phead->next;  
		delete tmp;  
		tmp = nullptr;  
	}  
	
	//尾部添加元素  
	void PushBack(int x)  
	{  
		Node* newnode = createNode(x);  
		// 1、空链表
		// 2、⾮空链表  
		if (phead == nullptr)  
		{  
			phead = newnode;  
		}  
		else  
		{  
			Node* tail = phead;  
			while (tail->next != nullptr)  
			{  
				tail = tail->next;  
			}  
			tail->next = newnode;  
		}  
	}  
	//尾部删除元素  
	void PopBack()  
	{  
		//空链表  
		if (phead == nullptr)  
		{  
			cout << "链表为空,没有元素可以删除了" << endl;  
			return;  
		}  
		// 1、⼀个节点  
		// 2、⼀个以上节点  
		if ((phead)->next == nullptr)  
		{  
			delete phead;  
			phead = nullptr;  
		}  
		else  
		{  
			// 找尾  
			Node* tail = phead;  
			while (tail->next->next != nullptr)  
			{  
				tail = tail->next;  
			}  
			delete tail->next;  
			tail->next = nullptr;  
		}  
	}
	void DestropList()  
	{  
		while(phead)  
		{  
			PopFront();  
		}  
	}  
};  

int main()  
{  
	List list;  
	list.PushBack(1);  
	list.PushBack(2);  
	list.PushBack(3);  
	list.PushBack(4);  
	list.printList();  
	//头部删除并打印  
	list.PopBack();  
	list.printList();  
	list.PopBack();  
	list.printList();  
	list.PopBack();  
	list.printList();  
	list.PopBack();  
	list.printList();  
	list.PopBack();  
	list.printList();  
	//头部添加元素  
	list.PushFront(1);  
	list.PushFront(2);  
	list.PushFront(3);  
	list.PushFront(4);  
	list.printList();  
	//头部删除  
	list.PopFront();  
	list.printList();  
	list.PopFront();
	list.printList();  
	return 0;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值