题目的主要信息:
- 输入一个单向链表和一个节点的值,其中链表的值不重复。
- 我们需要从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。
方法一:
我们用链表结构来模拟整个过程,val表示节点的值,next指向下一个节点。
1、建立链表:首先建立头节点,然后从输入中建立要插入的节点NewNode,遍历一遍已创建的链表,找到值为pre的节点,将NewNode插在后面。
2、删除指定值的节点:遍历一遍链表找到值为n的节点即为要删除的节点。
3、输出链表
具体做法:
#include<iostream>
using namespace std;
struct node{//节点结构
int val;
struct node* next;
};
int main(){
int num,val;
int next,pre;
cin>>num>>val;//节点个数
node* head = new node();
head->val = val;//创建头节点
head->next = NULL;
num--;
//逐个插入
while(num--){
cin>>next>>pre;//next要插到值为pre的后面
node* newNode = new node();//创建要插入的节点
newNode->val = next;
newNode->next = NULL;
//查找值为pre的节点
node *p=head;
while(p){
if(p->val == pre){
break;
}
else{
p = p->next;
}
}
if(p){//把NewNode节点插到pre的后面
node* tmp = p->next;
p->next = newNode;
newNode->next = tmp;
}
}
int n;
cin>>n;//输入要删除的节点的值
node* p = head;
if(head){
node* q = head->next;
while(q){
if(q->val == n){
break;
}else{
p = p->next;
q = q->next;
}
}
if(q){
node* tmp = q->next;
p->next = tmp;
delete q;
}
}
p = head;
while(p){//输出整个链表
cout<<p->val<<' ';
p = p->next;
}
return 0;
}
复杂度分析:
- 时间复杂度:,每插入一个节点都需要遍历一遍链表。
- 空间复杂度:,只用了常数空间。
方法二:
用vector容器模拟链表。
1、find函数查找前节点,用insert函数插入节点。
2、erase函数删除节点。
具体做法:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
int main(){
int n, val;//n为节点个数
while(cin>>n>>val){
vector<int> list;//用vector模拟链表
list.push_back(val);//头节点
for(int i=0;i<n-1;i++){
int next,pre;
cin>>next>>pre;
vector<int>::iterator iter = find(list.begin(),list.end(),pre);//next插到pre的后面
if(iter!=list.end()){
list.insert(iter+1,next);
}else{//如果pre节点在最后,则直接push_back
list.push_back(next);
}
}
int num;
cin>>num;//输入要删除的值
list.erase(find(list.begin(),list.end(),num));
for(auto i: list){//输出整个链表
cout << i << " ";
}
cout << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,每插入一个节点都需要用时间复杂度为的find函数查找pre的位置。
- 空间复杂度:,list的长度为n。