首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >单向链表的基本操作【下】(多种方法+测试代码+图像展示)

单向链表的基本操作【下】(多种方法+测试代码+图像展示)

作者头像
序属秋秋秋
发布2025-12-18 14:57:20
发布2025-12-18 14:57:20
520
举报
单向链表的基本操作【下】(多种方法+测试代码+图像展示)


👨‍💻 博主正在持续更新关于数据结构的博客中。 ❤️ 如果你觉得内容还不错,请多多点赞。 ⭐️ 如果你觉得对你有帮助,请多多收藏。(防止以后找不到了) 👨‍👩‍👧‍👦如果你想阅读更多的关于数据结构的博客,请多多关注博主。


前情提要:

如果你之前没有看过博主写的:单向链表的基本操作【上】,为了保证你的阅读体验,请先观看: 链接: 单向链表的基本操作【上】


单向链表节点的插入

引言:单向链表节点的插入

单向链表节点的插入可以分为以下两大形式:

  • 头插法
  • 尾插法
  • 任意插

任意插:将头插法尾插法相结合的插入方法。

方法一:头插法

代码语言:javascript
复制
//单向链表节点的插入——头插法
ListNode* insertListNode(ListNode*& head, int value)
{
	ListNode* newNode = new ListNode(value);
	newNode->next = head;
	head = newNode;

	return head;
}
完整代码测试
代码语言:javascript
复制
//单向链表节点的插入——头插法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的插入
	ListNode* insertListNode(ListNode*& head, int value)
	{
		ListNode* newNode = new ListNode(value);
		newNode->next = head;
		head = newNode;

		return head;
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(1);
	head->next = new ListNode(2);
	head->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的插入
	int value;
	cout << "请输入你要插入的节点的值" << endl;
	cin >> value;
	cout << "插入节点"<<value<<"后的单向链表为:" << endl;
	list.insertListNode(head, value);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 1 2 3 请输入你要插入的节点的值 8 插入节点8后的单向链表为: 8 1 2 3

方法二:尾插法

代码语言:javascript
复制
//单向链表节点的插入——尾插法
ListNode* insertListNode(ListNode*& head, int value)
{
	ListNode* curr = head;

	if (head == nullptr)
	{
		head = new ListNode(value);
		return head;
	}
	else
	{
		while (curr->next != nullptr)
		{
			curr = curr->next;
		}

		curr->next = new ListNode(value);
        return head;
	}
}
完整代码测试
代码语言:javascript
复制
//单向链表节点的插入——尾插法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的插入
	ListNode* insertListNode(ListNode*& head, int value)
	{
		ListNode* curr = head;

		if (head == nullptr)
		{
			head = new ListNode(value);
			return head;
		}
		else
		{
			while (curr->next != nullptr)
			{
				curr = curr->next;
			}

			curr->next = new ListNode(value);
            return head;
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(1);
	head->next = new ListNode(2);
	head->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的插入
	int value;
	cout << "请输入你要插入的节点的值" << endl;
	cin >> value;
	cout << "插入节点" << value << "后的单向链表为:" << endl;
	list.insertListNode(head, value);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 1 2 3 请输入你要插入的节点的值 8 插入节点8后的单向链表为: 1 2 3 8

方法三:任意插

代码语言:javascript
复制
//单向链表节点的插入——任意插
ListNode* insertListNode(ListNode*& head, int position, int value)
{
	int currSite = 1;
	ListNode* curr = head;

	if (position == 1)
	{
		ListNode* newNode = new ListNode(value);
		newNode->next = head;
		head = newNode;

		return head;
	}
	else
	{
		while (curr != nullptr && currSite < position - 1)
		{
			curr = curr->next;
			currSite++;
		}

		if (curr == nullptr || position < 0)
		{
			return nullptr;
		}
		else
		{
			ListNode* newNode = new ListNode(value);
			newNode->next = curr->next;
			curr->next = newNode;
            
            return head;
		}
	}
}
完整代码测试
代码语言:javascript
复制
//单向链表节点的插入——任意插
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的插入
	ListNode* insertListNode(ListNode*& head, int position, int value)
	{
		int currSite = 1;
		ListNode* curr = head;
        
		if (position == 1)
		{
			ListNode* newNode = new ListNode(value);
			newNode->next = head;
			head = newNode;

			return head;
		}
		else
		{
			while (curr != nullptr && currSite < position - 1)
			{
				curr = curr->next;
				currSite++;
			}
            
			if (curr == nullptr || position < 0)
			{
				return nullptr;
			}
			else
			{
				ListNode* newNode = new ListNode(value);
				newNode->next = curr->next;
				curr->next = newNode;
                
                return head;
			}
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(1);
	head->next = new ListNode(2);
	head->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的插入
	int position, value;
	cout << "请输入你要插入的节点的位置" << endl;
	cin >> position;
	cout << "请输入你要插入的节点的值" << endl;
	cin >> value;
	cout << "在位置" << position << "插入节点" << value << "后的单向链表为:" << endl;
	list.insertListNode(head, position, value);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 1 2 3 请输入你要插入的节点的位置 3 请输入你要插入的节点的值 8 在位置3插入节点8后的单向链表为: 1 2 8 3


单向链表节点的删除

引言:单向链表节点的删除

单向链表节点的删除可以分为以下两大形式:

  • 按位删除
    • 无哑节点的形式
    • 带哑节点的形式
  • 按值删除
    • 迭代法
    • 递归法

方法一:按位删除-迭代法(无哑节点的形式)

代码语言:javascript
复制
//单向链表节点的删除——按位删除-迭代法(无哑节点的形式)
ListNode* deleteListNode(ListNode*& head, int position)
{
	int currSite = 1;
	ListNode* curr = head;

	if (head == nullptr || position <= 0)
	{
		return nullptr;
	}
	else if (position == 1)
	{
		head = head->next;
		delete curr;

		return head;
	}
	else
	{
		while (curr->next != nullptr && currSite < position - 1)
		{
			curr = curr->next;
			currSite++;
		}

		if (curr->next == nullptr)
		{
			return nullptr;
		}
		else
		{
			ListNode* delNode = curr->next;
			curr->next = curr->next->next;
			delete delNode;
            
            return head;
		}
	}
}
原理图像展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表节点的删除——按位删除-迭代法(无哑节点的形式)
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的删除
	ListNode* deleteListNode(ListNode*& head, int position)
	{
		int currSite = 1;
		ListNode* curr = head;

		if (head == nullptr || position <= 0)
		{
			return nullptr;
		}
		else if (position == 1)
		{
			head = head->next;
			delete curr;

			return head;
		}
		else
		{
			while (curr->next != nullptr && currSite < position - 1)
			{
				curr = curr->next;
				currSite++;
			}

			if (curr->next == nullptr)
			{
				return nullptr;
			}
			else
			{
				ListNode* delNode = curr->next;
				curr->next = curr->next->next;
				delete delNode;

				return head;
			}
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
    head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的删除
	int position;
	cout << "请输入你要删除的节点的位置" << endl;
	cin >> position;
	cout << "删除位置" << position << "上的节点后的单向链表为:" << endl;
	list.deleteListNode(head, position);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要删除的节点的位置 3 删除位置3上的节点后的单向链表为: 3 2 3

方法二:按位删除-迭代法(带哑节点的形式)

代码语言:javascript
复制
//单向链表节点的删除——按位删除-迭代法(带哑节点的形式)
ListNode* deleteListNode(ListNode*& head, int position)
{
	int currSite = 1;
	ListNode* dummy = new ListNode(-1);
	ListNode* curr = dummy;
	dummy->next = head;

	if (position <= 0)
	{
		return nullptr;
	}
	else
	{
		while (curr->next != nullptr && currSite < position)
		{
			curr = curr->next;
			currSite++;
		}

		if (curr->next == nullptr)
		{
			return nullptr;
		}
		else
		{
			ListNode* delNode = curr->next;
			curr->next = curr->next->next;
			delete delNode;
		}
        
		head = dummy->next;
		delete dummy;
		return head;
	}
}
原理图像展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表节点的删除——按位删除-迭代法(带哑节点的形式)
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的删除
	ListNode* deleteListNode(ListNode*& head, int position)
	{
		int currSite = 1;
		ListNode* dummy = new ListNode(-1);
		ListNode* curr = dummy;
		dummy->next = head;

		if (position <= 0)
		{
			return nullptr;
		}
		else
		{
			while (curr->next != nullptr && currSite < position)
			{
				curr = curr->next;
				currSite++;
			}

			if (curr->next == nullptr)
			{
				return nullptr;
			}
			else
			{
				ListNode* delNode = curr->next;
				curr->next = curr->next->next;
				delete delNode;
			}
                    
			head = dummy->next;
			delete dummy;
			return head;
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的删除
	int position;
	cout << "请输入你要删除的节点的位置" << endl;
	cin >> position;
	cout << "删除位置" << position << "上的节点后的单向链表为:" << endl;
	list.deleteListNode(head, position);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要删除的节点的位置 3 删除位置3上的节点后的单向链表为: 3 2 3


总结:单向链表节点的删除-按位删除

按位删除的迭代法的这两种形式:无哑节点的形式带哑节点的形式的主要区别在于

  1. 两者对于当要删除的节点是头节点时的应对策略不同:
  • 无哑节点的形式:需要使用if(position==1) 单独处理这个特殊的情况。
  • 带哑节点的形式:不需要特意的去处理这种情况,哑节点的使用使得position==1的情况和position>1的情况完美的融合统一。
  1. 两者对于当单向链表为空时的处理方式不同:
  • 无哑节点的形式:需要使用if(head==nullptr) 单独处理这个特殊的情况。
  • 带哑节点的形式:不需要特意的去处理这种情况,哑节点的使用使得head==nullptr与head!=nullptr的情况完美的融合统一。

方法三:按值删除-迭代法

代码语言:javascript
复制
//单向链表节点的删除——按值删除-迭代法
ListNode* deleteListNode(ListNode*& head, int value)
{
	ListNode* dummy = new ListNode(-1);
	dummy->next = head;
	ListNode* curr = dummy;

	while (curr->next != nullptr)
	{
		if (curr->next->data != value)
		{
			curr = curr->next;
		}
		else
		{
			ListNode* temp = curr->next;
			curr->next = curr->next->next;
			delete temp;
		}
	}
    
    head = dummy->next;
	delete dummy;
	return head;
}
原理图像展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表节点的删除——按值删除-迭代法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的删除
	ListNode* deleteListNode(ListNode*& head, int value)
	{
		ListNode* dummy = new ListNode(-1);
		dummy->next = head;
		ListNode* curr = dummy;

		while (curr->next != nullptr)
		{
			if (curr->next->data != value)
			{
				curr = curr->next;
			}
			else
			{
				ListNode* temp = curr->next;
				curr->next = curr->next->next;
				delete temp;
			}
		}
                        
        head = dummy->next;
		delete dummy;
		return head;
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的删除
	int value;
	cout << "请输入你要删除的节点的值" << endl;
	cin >> value;
	cout << "删除值为" << value << "的节点后的单向链表为:" << endl;
	list.deleteListNode(head, value);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要删除的节点的值 3 删除值为3的节点后的单向链表为: 2 1

方法四:按值删除-递归法

代码语言:javascript
复制
//单向链表节点的删除——按值删除-递归法
ListNode* deleteListNode(ListNode*& head, int value)
{
	if (head == nullptr)
	{
		return nullptr;
	}

	else if (head->data == value)
	{
		ListNode* curr = head;
		head = deleteListNode(head->next, value);
		delete curr;
		return head;
	}
	else
	{
		head->next = deleteListNode(head->next, value);
		return head;
	}
}
原理图像展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表节点的删除——按值删除-递归法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的删除
	ListNode* deleteListNode(ListNode*& head, int value)
	{
		if (head == nullptr)
		{
			return nullptr;
		}
        
		else if (head->data == value)
		{
			ListNode* curr = head;
			head = deleteListNode(head->next, value); 
			delete curr; 
			return head;
		}
		else
		{
			head->next = deleteListNode(head->next, value);
			return head; 
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的删除
	int value;
	cout << "请输入你要删除的节点的值" << endl;
	cin >> value;
	cout << "删除值为" << value << "的节点后的单向链表为:" << endl;
	list.deleteListNode(head, value);
	list.printList(head);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要删除的节点的值 3 删除值为3的节点后的单向链表为: 2 1


单向链表节点的查找

引言:单向链表节点的查找

单向链表节点的查找我认为可以分为以下两大形式:

  • 由位查值
    • 迭代法
    • 递归法
  • 由值查位
    • 迭代法
    • 递归法

方法一:由位查值-迭代法

代码语言:javascript
复制
//单向链表节点的查找——由位查值-迭代法
void findListNode(ListNode* head, int position)
{
	int currSite = 1;
	ListNode* curr = head;

	if (head == nullptr || position <= 0)
	{
		return;
	}

	while (curr != nullptr && currSite < position)
	{
		curr = curr->next;
		currSite++;
	}
	if (curr == nullptr)
	{
		return;
	}
	else
	{
		cout << "位置" << position << "上的节点的值为:" << curr->data << endl;
		return;
	}
}
原理图像展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表节点的查找——由位查值-迭代法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的查找
	void findListNode(ListNode* head, int position)
	{
		int currSite = 1;
		ListNode* curr = head;

		if (head == nullptr || position <= 0)
		{
			return;
		}
        
		while (curr != nullptr && currSite < position)
		{
			curr = curr->next;
			currSite++;
		}
		if (curr == nullptr)
		{
			return;
		}
		else
		{
			cout << "位置" << position << "上的节点的值为:" << curr->data << endl;
			return;
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的查找
	int position;
	cout << "请输入你要查找的位置" << endl;
	cin >> position;
	list.findListNode(head, position);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要查找的位置 3 位置3上的节点的值为:1

方法二:由位查值-递归法

代码语言:javascript
复制
//单向链表节点的查找——由位查值-递归法
void findListNode(ListNode* head, int position, int currSite)
{
	ListNode* curr = head;

	if (head == nullptr || position <= 0)
	{
		return;
	}
	else if (currSite == position)
	{
		cout << "位置" << position << "上的节点的值为:" << curr->data << endl;
		return;
	}
	else
	{
		findListNode(curr->next, position, currSite + 1);
	}
}
图像原理展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表节点的查找——由位查值-递归法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的查找
	void findListNode(ListNode* head, int position, int currSite)
	{
		ListNode* curr = head;

		if (head == nullptr || position <= 0)
		{
			return;
		}
		else if (currSite == position)
		{
			cout << "位置" << position << "上的节点的值为:" << curr->data << endl;
			return;
		}
		else
		{
			findListNode(curr->next, position, currSite + 1);
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的查找
	int currSite = 1;

	int position;
	cout << "请输入你要查找的位置" << endl;
	cin >> position;
	list.findListNode(head, position, currSite);

	list.destroyList(head);
	return 0;
}

交互方式: 创建好的单向链表为: 3 2 1 3 请输入你要查找的位置 3 位置3上的节点的值为:1

方法三:由值查位-迭代法

代码语言:javascript
复制
//单向链表节点的查找——由值查位-迭代法
void findListNode(ListNode* head, int value)
{
	int currSite = 1;
	ListNode* curr = head;

	while (curr != nullptr)
	{
		if (curr->data == value)
		{
			cout << "值为" << value << "的节点所在的位置为:" << currSite << endl;
		}

		curr = curr->next;
		currSite++;
	}
}
完整代码测试
代码语言:javascript
复制
//单向链表节点的查找——由值查位-迭代法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的查找
	void findListNode(ListNode* head, int value)
	{
		int currSite = 1;
		ListNode* curr = head;
        
		while (curr != nullptr) 
		{ 
			if (curr->data == value) 
			{ 
				cout << "值为" << value << "的节点所在的位置为:" << currSite << endl;
			}
            
			curr = curr->next; 
			currSite++;
		}
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的查找
	int value;
	cout << "请输入你要查找的节点的值" << endl;
	cin >> value;
	list.findListNode(head, value);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要查找的节点的值 3 值为3的节点所在的位置为:1 值为3的节点所在的位置为:4

方法四:由值查位-递归法

代码语言:javascript
复制
//单向链表节点的查找——由值查位-递归法
void findListNode(ListNode* head, int value, int currSite)
{
	ListNode* curr = head;

	if (head == nullptr)
	{
		return;
	}
	if (curr->data == value)
	{
		cout << "值为" << value << "的节点所在的位置为:" << currSite << endl;
	}

	findListNode(curr->next, value, currSite + 1);
}
完整代码测试
代码语言:javascript
复制
//单向链表节点的查找——由值查位-递归法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表节点的查找
	void findListNode(ListNode* head, int value, int currSite)
	{
		ListNode* curr = head;

		if (head == nullptr)
		{
			return;
		}
		if (curr->data == value)
		{
			cout << "值为" << value << "的节点所在的位置为:" << currSite << endl;
		}

		findListNode(curr->next, value, currSite + 1);
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表节点的查找
	int currSite = 1;

	int value;
	cout << "请输入你要查找的节点的值" << endl;
	cin >> value;
	list.findListNode(head, value, currSite);

	list.destroyList(head);
	return 0;
}

交互过程: 创建好的单向链表为: 3 2 1 3 请输入你要查找的节点的值 3 值为3的节点所在的位置为:1 值为3的节点所在的位置为:4


单向链表的求表长度

单向链表的求表长的方法主要有两种:

  • 迭代法
  • 递归法

方法一:迭代法

代码语言:javascript
复制
//单向链表的求长——迭代法
void lengthList(ListNode* head)
{
	int length = 0;
	ListNode* curr = head;

	if (head == nullptr)
	{
		cout << "该单向链表的长度为:" << length << endl;
        return;
	}

	while (curr != nullptr)
	{
		curr = curr->next;
		length++;
	}
	cout << "该单向链表的长度为:" << length << endl;
    return;
}
完整代码测试
代码语言:javascript
复制
//单向链表的求长——迭代法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表的求长
	void lengthList(ListNode* head)
	{
		int length = 0;
		ListNode* curr = head;

		if (head == nullptr)
		{
			cout << "该单向链表的长度为:" << length << endl;
            return;
		}

		while (curr != nullptr)
		{
			curr = curr->next;
			length++;
		}
		cout << "该单向链表的长度为:" << length << endl;
        return;
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表的求长
	list.lengthList(head);

	list.destroyList(head);
	return 0;
}

输出: 创建好的单向链表为: 3 2 1 3 该单向链表的长度为:4

方法二:递归法

代码语言:javascript
复制
//单向链表的求长——递归法
int lengthList(ListNode* head)
{
	ListNode* curr = head;

	if (head == nullptr)
	{
		return 0;
	}
	return lengthList(curr->next) + 1;
}
原理图像展示
在这里插入图片描述
在这里插入图片描述
完整代码测试
代码语言:javascript
复制
//单向链表的求长——递归法
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//单向链表的求长
	int lengthList(ListNode* head)
	{
		ListNode* curr = head;

		if (head == nullptr)
		{
			return 0;
		}
		return lengthList(curr->next) + 1;
	}

	//单向链表的打印
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
	//单向链表的销毁
	void destroyList(ListNode*& head)
	{
		while (head != nullptr)
		{
			ListNode* curr = head;
			head = head->next;
			delete curr;
		}
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);

	cout << "创建好的单向链表为:" << endl;
	list.printList(head);

	//单向链表的求长
	cout << "该单向链表的长度为:" << list.lengthList(head) << endl;

	list.destroyList(head);
	return 0;
}

输出: 创建好的单向链表为: 3 2 1 3 该单向链表的长度为:4


单向链表节点的“插入+删除+查找+求表长”操作汇总小程序

代码语言:javascript
复制
//单向链表节点的“插入+删除+查找+求表长”操作汇总小程序
#include<iostream>
using namespace std;

struct ListNode
{
	int data;
	ListNode* next;
	ListNode(int val) :data(val), next(nullptr) {}
};

class LinkList
{
public:
	//显示基本操作菜单界面
	void menuList()
	{
		cout << "*********************单向链表的基本操作**********************" << endl;
		cout << "--------------------1.插入单向链表的节点---------------------" << endl;
		cout << "--------------------2.按位删除单向链表的节点------------------" << endl;
		cout << "--------------------3.按值删除单向链表的节点------------------" << endl;
		cout << "--------------------4.由位查找单向链表的节点------------------" << endl;
		cout << "--------------------5.由值查找单向链表的节点------------------" << endl;
		cout << "--------------------6.求长单向链表--------------------------" << endl;
		cout << "--------------------0.退出该小程序--------------------------" << endl;
		cout << "**********************************************************" << endl;
	}

	//单向链表节点的插入——任意插
	ListNode* insertListNode(ListNode*& head, int position, int value)
	{
		int currSite = 1;
		ListNode* curr = head;

		if (position == 1)
		{
			ListNode* newNode = new ListNode(value);
			newNode->next = head;
			head = newNode;

			return head;
		}
		else
		{
			while (curr != nullptr && currSite < position - 1)
			{
				curr = curr->next;
				currSite++;
			}

			if (curr == nullptr || position < 0)
			{
				return nullptr;
			}
			else
			{
				ListNode* newNode = new ListNode(value);
				newNode->next = curr->next;
				curr->next = newNode;

				return head;
			}
		}
	}

	//单向链表节点的删除——按位删除-迭代法(带哑节点的形式)
	ListNode* deleteListNode_P(ListNode*& head, int position)
	{
		int currSite = 1;
		ListNode* dummy = new ListNode(-1);
		ListNode* curr = dummy;
		dummy->next = head;

		if (position <= 0)
		{
			return nullptr;
		}
		else
		{
			while (curr->next != nullptr && currSite < position)
			{
				curr = curr->next;
				currSite++;
			}

			if (curr->next == nullptr)
			{
				return nullptr;
			}
			else
			{
				ListNode* delNode = curr->next;
				curr->next = curr->next->next;
				delete delNode;
			}

			head = dummy->next;
			delete dummy;
			return head;
		}
	}

	//单向链表节点的删除——按值删除-迭代法
	ListNode* deleteListNode_V(ListNode*& head, int value)
	{
		ListNode* dummy = new ListNode(-1);
		dummy->next = head;
		ListNode* curr = dummy;

		while (curr->next != nullptr)
		{
			if (curr->next->data != value)
			{
				curr = curr->next;
			}
			else
			{
				ListNode* temp = curr->next;
				curr->next = curr->next->next;
				delete temp;
			}
		}

		head = dummy->next;
		delete dummy;
		return head;
	}

	//单向链表节点的查找——由位查值-迭代法
	void findListNode_P(ListNode* head, int position)
	{
		int currSite = 1;
		ListNode* curr = head;

		if (head == nullptr || position <= 0)
		{
			return;
		}

		while (curr != nullptr && currSite < position)
		{
			curr = curr->next;
			currSite++;
		}
		if (curr == nullptr)
		{
			return;
		}
		else
		{
			cout << "位置" << position << "上的节点的值为:" << curr->data << endl;
			return;
		}
	}

	//单向链表节点的查找——由值查位-迭代法
	void findListNode_V(ListNode* head, int value)
	{
		int currSite = 1;
		ListNode* curr = head;

		while (curr != nullptr)
		{
			if (curr->data == value)
			{
				cout << "值为" << value << "的节点所在的位置为:" << currSite << endl;
			}

			curr = curr->next;
			currSite++;
		}
	}

	//单向链表的求长——迭代法
	void lengthList(ListNode* head)
	{
		int length = 0;
		ListNode* curr = head;

		if (head == nullptr)
		{
			cout << "该单向链表的长度为:" << length << endl;
			return;
		}

		while (curr != nullptr)
		{
			curr = curr->next;
			length++;
		}
		cout << "该单向链表的长度为:" << length << endl;
		return;
	}

	//单向链表的打印——迭代
	void printList(ListNode* head)
	{
		ListNode* curr = head;
		while (curr != nullptr)
		{
			cout << curr->data << " ";
			curr = curr->next;
		}
		cout << endl;
	}
};

int main()
{
	LinkList list;

	//单向链表的创建
	ListNode* head = new ListNode(3);
	head->next = new ListNode(2);
	head->next->next = new ListNode(1);
	head->next->next->next = new ListNode(3);
    
	int n = INT_MAX;
	while (n != 0)
	{
		cout << "现在的单向链表为:" << endl;
		list.printList(head);

		list.menuList();
		cout << "请输入菜单号" << endl;
		cin >> n;

		int position, value;
		switch (n)
		{
		case 1:
			//单向链表节点的插入
			//int position, value;
			cout << "请输入你要插入的节点的位置" << endl;
			cin >> position;
			cout << "请输入你要插入的节点的值" << endl;
			cin >> value;

			cout << "已在位置" << position << "上插入值为" << value << "的节点" << endl;
			list.insertListNode(head, position, value);

			break;
		case 2:
			//单向链表节点的删除
			//int position;
			cout << "请输入你要删除的节点的位置" << endl;
			cin >> position;

			cout << "已将位置" << position << "上的节点删除" << endl;
			list.deleteListNode_P(head, position);

			break;
		case 3:
			//单向链表节点的删除
			//int value;
			cout << "请输入你要删除的节点的值" << endl;
			cin >> value;

			cout << "已将值为" << value << "的节点删除" << endl;
			list.deleteListNode_V(head, value);

			break;
		case 4:
			//单向链表节点的查找
			//int position;
			cout << "请输入你要查找的位置" << endl;
			cin >> position;

			list.findListNode_P(head, position);

			break;

		case 5:
			//单向链表节点的查找
			//int value;
			cout << "请输入你要查找的节点的值" << endl;
			cin >> value;

			list.findListNode_V(head, value);

			break;
		case 6:
			///单向链表的求长
			list.lengthList(head);

			break;
		}
	}
	return 0;
}

😮你既然看完了,太厉害了👍。哈哈😄 ​恭喜你,单向链表的基本操作你已经学完了,为你鼓掌👏 。咳咳…… ,别急着走,😭 你是不是忘了什么东西呀~ 。虽然【下】鸽了很久,但是博主真的有好好准备,能不能点个❤️ 🌟 再走吗?😽

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单向链表的基本操作【下】(多种方法+测试代码+图像展示)
  • 前情提要:
  • 单向链表节点的插入
    • 引言:单向链表节点的插入
    • 方法一:头插法
      • 完整代码测试
    • 方法二:尾插法
      • 完整代码测试
    • 方法三:任意插
      • 完整代码测试
  • 单向链表节点的删除
    • 引言:单向链表节点的删除
    • 方法一:按位删除-迭代法(无哑节点的形式)
      • 原理图像展示
      • 完整代码测试
    • 方法二:按位删除-迭代法(带哑节点的形式)
      • 原理图像展示
      • 完整代码测试
    • 总结:单向链表节点的删除-按位删除
    • 方法三:按值删除-迭代法
      • 原理图像展示
      • 完整代码测试
    • 方法四:按值删除-递归法
      • 原理图像展示
      • 完整代码测试
  • 单向链表节点的查找
    • 引言:单向链表节点的查找
    • 方法一:由位查值-迭代法
      • 原理图像展示
      • 完整代码测试
    • 方法二:由位查值-递归法
      • 图像原理展示
      • 完整代码测试
    • 方法三:由值查位-迭代法
      • 完整代码测试
    • 方法四:由值查位-递归法
      • 完整代码测试
  • 单向链表的求表长度
    • 方法一:迭代法
      • 完整代码测试
    • 方法二:递归法
      • 原理图像展示
      • 完整代码测试
  • 单向链表节点的“插入+删除+查找+求表长”操作汇总小程序
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档