关键词:
北京中关村;海淀黄庄;北京大学;清华大学。少儿编程;中小学编程;信息学竞赛;计算机竞赛;NOIP;NOIP竞赛;CSP-J/S竞赛;NOI竞赛。信息学奥林匹克;东坝;北京中学。面向6-18岁中小学生,做最专业的中小学编程教育。信息学研讨会;家长;学生;关心问题;少儿编程问题解答。
/*
思想:链表解题思路
1、生成链表结构
2、生成链表:条件,通过循环创建,我们的条件是:输入为0结束。
3、循环到最后为NULL,打印。
4、删除结点分为3种情况:
A、删除头结点 删除头结点的话:只需要头指针后移
B、删除尾结点 删除尾结点的话:要定位到倒数第二个,删除最后一个,倒数第二个为NULL,不能定位到最后一个,那样找不到前一个了。
C、删除中间结点 定位到删除结点的前一个结点,保存删除结点的后一个结点,让前一个结点和后一个结点连接起来。删除要删除的。
*/
#include <iostream>
using namespace std;
//一个链表至少包含一个数据域,和一个地址域,是下一个结点的地址。
struct Node
{
int num; //数据域
Node *next; //地址域
};
//创建链表
Node *Create()
{
Node *head,*p1,*p2; //head 头永远不懂, p1循环创建,赋值 p2就是连接上,然后追上p1。大家可以自己画图
head = p2 = p1 = new Node(); //先开辟第一个结点
cin>>p1->num; //输入值
if(p1->num == 0)//如果第一个结点为0 ,等于链表不创建
{
delete head; //为0了,就删除头了。
return NULL; //然后返回空
}
while(true)//死循环
{
p1 = new Node(); //开辟结点
cin>>p1->num; //输入值
if(p1->num == 0)//为0时间结束
{
delete p1; //为0 结束删除刚才创建的
break;
}
p2->next = p1;//p2是前一个结点,前一个结点的next域要和新创建的结点连接起来。
p2 = p1; //p2要追上p1
}
p2->next = NULL;//最后结点的next域为空
return head; //返回头结点
}
//就是循环到最后一个结点,最有一个结点为NULL。说白了就是循环。要保存好头结点。如果不保存,打印后,头结点找不到了。
void Disp(Node *head)
{
Node *temp = head;
while(temp!=NULL)//一直循环到最后打印
{
cout<<temp->num<<"\t";
temp = temp->next; //如果少了这一句,将会是死循环。
}
cout<<endl;
}
//删除结点 如果删除的在第一个结点。 删除情况1
// 如果删除的是最后一个结点。 删除情况2
// 如果删除的是中间结点 删除情况3
//先判断是否是删除情况1、删除情况3、最后判断是否是删除情况2. 因为删除情况2最复杂。我们本着先简单,后复杂的原则进行。
Node* Delete(Node *head)
{
cout<<"请输入要删除的数据"<<endl;
int id ;
cin>>id;
//对应上面的:temp1--->删除情况1时间的头结点 temp2:删除情况2时间的头结点 temp3:删除情况3时间的头结点
Node *temp1,*temp2,*temp3;
//都指向头
temp1 = temp2 = temp3 = head;
//1111111111111111111111111111111111111111111111111111111111111
if(temp1->num == id) //如果是第一个结点
{
head = head->next;//上面已经保存了,所以head后移
delete temp1; //删除头结点
return head; //返回链表当前头结点
}
//33333333333333333333333333333333333333333333333333333333333
//判断是否是第三种情况。 循环到倒数第二个结点
while(temp2->next->next!=NULL)
{
temp2 = temp2->next;
}
//判断如果要删除的是最后一个结点,则删除最后一个结点。倒数第二个的next域为空
if(temp2->next->num == id)
{
delete temp2->next; //删除最后一个结点
temp2->next = NULL; //倒数第二个结点的next域为空
}
//2222222222222222222222222222222222222222
//收否是第二种情况。如果删除的是中间的结点, 也要定位到要删除结点的前一个结点。所以两个next
//有很多个中间结点,所以,一个一个进行判断。就是不断循环
while(temp3->next->next!=NULL)
{
if(temp3->next->num == id)//发现有相等
{
Node *temp4 = temp3->next->next;//保存要删除结点的next域
delete temp3->next;//删除中间结点
temp3->next = temp4;//让中间结点的next域指向删除结点的next
break;//找到相等的了,直接退出。
}
temp3 = temp3->next;//判断下一个
}
return head;
}
int main()
{
Node *head = Create();//创建链表
Disp(head); //打印链表
head = Delete(head); //删除结点
Disp(head); //打印删除后的情况。
}
A、官方网址:
B、微信公众号:
添加微信,获取资料。
关注公众号,获取动态。