#include<iostream>
using namespace std;
#define 新节点指针q q
#define 数据成员 num
#define 指针域 next
#define 找被删除的节点的指针 p1
#define 找被删除节点的上一个节点的指针 p2
#define 遍历指针 i
//这个是为了更好理解代码,将变量名字换成了汉字来增强可读性
- 以下是在main前声明 结构体定义 和 一个动态创建链表的函数
struct node
{
int num;
node* next;
};
int x;
node* creat()
{
node* head = new node;
node* p = NULL;
node* 新节点指针q(NULL);
cin >> x;
while (x != -1)
{
新节点指针q = new node;//开辟一段内存大小为一个节点的内存,
//让 新节点指针 等于新内存的头地址
新节点指针q->数据成员 = x;//新节点存的数据为x
新节点指针q->指针域 = p;//使新节点指向p指向的东西,p一般指向上一个结点,
//只不过创建第一个节点的时候p一开始为NULL.
p = 新节点指针q;//p指向新节点
cin >> x;//输入x
}
//当x=-1时,循环结束,不会有节点的数据成员被赋为-1,
//所以链表的有效节点一直到-1前的那个节点,且p也指向那个最后的有效节点,于是就让head等于p就行了
head = p;
return (head);
}
因为题干要求反向遍历,而链表的遍历只能遵循指针指向,所以选择头插法来创建动态链表
(即使新生成节点的指针指向旧生成的节点)
以下为创建链表函数中函数体的逐步讲解
node* 新节点指针q(NULL); cin >> x; while (x != -1) { 新节点指针q = new node;//开辟一段内存大小为一个节点的内存, //让 新节点指针 等于新内存的头地址 新节点指针q->数据成员 = x;//新节点存的数据为x 新节点指针q->指针域 = p;//使新节点指向p指向的东西,p一般指向上一个结点, //只不过创建第一个节点的时候p一开始为NULL. p = 新节点指针q;//p指向新节点 cin >> x;//输入x }
以下为图解
第一次循环的初始化(上图)
第一次循环的 p = 新节点指针q; 语句进行完后(上图)
在new之后,第二轮语句进行完后(上图)
创建完成
- 接下来在main中调用creat()
- 以及进行 查找删除操作 和 遍历输出
int main()
{
node* head = creat();//调用创建链表的函数,返回这个链表的首地址
node* 找被删除的节点的指针 = head;
node* 找被删除节点的上一个节点的指针(NULL);
int k;
cin >> k;
if (head->数据成员 == k)
{
head = head->指针域;
}
else
do
{
找被删除节点的上一个节点的指针 = 找被删除的节点的指针;
找被删除的节点的指针 = 找被删除的节点的指针->指针域;
if (找被删除的节点的指针->数据成员 == k)//找的了
{
break;
}
} while (找被删除的节点的指针 != NULL);
找被删除节点的上一个节点的指针->指针域 = 找被删除的节点的指针->指针域;
//删前节点的指针域指向删后的节点
node *遍历指针 = head;
do
{
cout << 遍历指针->数据成员 << " ";
遍历指针 = 遍历指针->指针域;
} while (遍历指针 != NULL);
return 0;
}
删除图解
被删除的节点的上一个节点的指针指向被删除的节点的下一个节点,即:
找被删除节点的上一个节点的指针->指针域 = 找被删除的节点的指针->指针域;
拓展:
假如不需要反向输出,即使用尾插法创建链表
以下为头插法和尾插法的各两种方法