单向链表的基本操作【下】(多种方法+测试代码+图像展示)
👨💻 博主正在持续更新关于数据结构的博客中。
❤️ 如果你觉得内容还不错,请多多点赞。
⭐️ 如果你觉得对你有帮助,请多多收藏。(防止以后找不到了)
👨👩👧👦如果你想阅读更多的关于数据结构的博客,请多多关注博主。
前情提要:
如果你之前没有看过博主写的:
单向链表的基本操作【上】
,为了保证你的阅读体验,请先观看:
链接: 单向链表的基本操作【上】
单向链表节点的插入
引言:单向链表节点的插入
单向链表节点的插入可以分为以下两大形式:
- 头插法
- 尾插法
- 任意插
任意插
:将头插法
和尾插法
相结合的插入方法。
方法一:头插法
//单向链表节点的插入——头插法
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
总结:单向链表节点的删除-按位删除
按位删除的迭代法的这两种形式:
无哑节点的形式
和带哑节点的形式
的主要区别在于
- 两者对于当
要删除的节点是头节点
时的应对策略不同:
- 无哑节点的形式:需要使用if(position==1) 单独处理这个特殊的情况。
- 带哑节点的形式:不需要特意的去处理这种情况,哑节点的使用使得position==1的情况和position>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;
}
😮你既然看完了,太厉害了👍。哈哈😄 恭喜你,单向链表的基本操作你已经学完了,为你鼓掌👏 。咳咳…… ,别急着走,😭 你是不是忘了什么东西呀~ 。虽然【下】鸽了很久,但是博主真的有好好准备,能不能点个❤️ 🌟 再走吗?😽