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


👨‍💻 博主正在持续更新关于数据结构的博客中。

❤️ 如果你觉得内容还不错,请多多点赞。

⭐️ 如果你觉得对你有帮助,请多多收藏。(防止以后找不到了)

👨‍👩‍👧‍👦如果你想阅读更多的关于数据结构的博客,请多多关注博主。


前情提要:

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


单向链表节点的插入

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

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

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

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

方法一:头插法

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

	return head;
}

完整代码测试

//单向链表节点的插入——头插法
#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

方法二:尾插法

//单向链表节点的插入——尾插法
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;
	}
}

完整代码测试

//单向链表节点的插入——尾插法
#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

方法三:任意插

//单向链表节点的插入——任意插
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;
		}
	}
}

完整代码测试

//单向链表节点的插入——任意插
#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


单向链表节点的删除

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

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

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

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

//单向链表节点的删除——按位删除-迭代法(无哑节点的形式)
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;
		}
	}
}

原理图像展示

在这里插入图片描述

完整代码测试

//单向链表节点的删除——按位删除-迭代法(无哑节点的形式)
#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

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

//单向链表节点的删除——按位删除-迭代法(带哑节点的形式)
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;
	}
}

原理图像展示

在这里插入图片描述

完整代码测试

//单向链表节点的删除——按位删除-迭代法(带哑节点的形式)
#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的情况完美的融合统一。

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

//单向链表节点的删除——按值删除-迭代法
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;
}

原理图像展示

在这里插入图片描述

完整代码测试

//单向链表节点的删除——按值删除-迭代法
#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

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

//单向链表节点的删除——按值删除-递归法
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;
	}
}

原理图像展示

在这里插入图片描述

完整代码测试

//单向链表节点的删除——按值删除-递归法
#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


单向链表节点的查找

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

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

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

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

//单向链表节点的查找——由位查值-迭代法
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;
	}
}

原理图像展示

在这里插入图片描述

完整代码测试

//单向链表节点的查找——由位查值-迭代法
#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

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

//单向链表节点的查找——由位查值-递归法
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);
	}
}

图像原理展示

在这里插入图片描述

完整代码测试

//单向链表节点的查找——由位查值-递归法
#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

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

//单向链表节点的查找——由值查位-迭代法
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++;
	}
}

完整代码测试

//单向链表节点的查找——由值查位-迭代法
#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

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

//单向链表节点的查找——由值查位-递归法
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);
}

完整代码测试

//单向链表节点的查找——由值查位-递归法
#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


单向链表的求表长度

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

  • 迭代法
  • 递归法

方法一:迭代法

//单向链表的求长——迭代法
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;
}

完整代码测试

//单向链表的求长——迭代法
#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

方法二:递归法

//单向链表的求长——递归法
int lengthList(ListNode* head)
{
	ListNode* curr = head;

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

原理图像展示

在这里插入图片描述

完整代码测试

//单向链表的求长——递归法
#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


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

//单向链表节点的“插入+删除+查找+求表长”操作汇总小程序
#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;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

序属秋秋秋

😘

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

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

打赏作者

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

抵扣说明:

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

余额充值