剑指offer-18-删除链表中的节点(改)(C语言)
由于先前对链表存在误解,所以操作对象为数组,以下为重做
C语言实现“删除链表的节点”
实现目标:
输入
head:>
1 1 1 2 2 3 -1
val:>
2
输出
out:>
1 1 1 3
实现删除所有输入的某个值
代码(编译器:vs2022)
#define _CRT_SECURE_NO_WARNINGS
#define cahr char
#define LinkNOde LinkNode
//个人常有的输入错误,所以直接定义宏
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//创建结构体
typedef struct LinkNode
{
int Input;
LinkNode* next;
}LinkNode;
//录入数据
LinkNOde* Init_LinkList()
{
puts("head:>");
int i = 0;
scanf("%d", &i);
LinkNode* header = //头节点
(LinkNode*)malloc(sizeof(LinkNode));
LinkNode* node = //作为变化的节点
(LinkNode*)malloc(sizeof(LinkNode));
header->Input = i;
node = header;
do
{
int i = 0;
scanf("%d", &i);
if (i == -1)//跳出录入过程的标志
{
node->next = NULL;
break;
}
LinkNode* p = //因为i的地址是int*类型,所以不能直接传入node,要用p作为中介
(LinkNode*)malloc(sizeof(LinkNode));
p->Input = i;
node->next = p;
node = p;
//注意,因为把p的地址传入node后,值依旧在该地址处,所以不能free(p)
} while (1);
return header;
}
//删除节点
LinkNode* DelNode(LinkNOde* header)
{
assert(header);
int m = 0;
puts("val:>");
scanf("%d", &m);
//判断头节点为m的情况
while (header)
{
if (header->Input == m)
{
LinkNode* Del = header;
header = header->next;//header指向后移
free(Del);//释放原节点
}
else break;
}
//判断是否将所有数据删除
if (!header) return header;
LinkNOde* node = header->next;//当前判断节点
//因为前面已经判断header为非m,所以从下一个节点开始判断
LinkNode* prev = header;//指向该节点结构体的指针
//判断非头结点为m的情况
while (node)
{
if (node->Input == m)
{
LinkNode* Del = node;
prev->next = node->next;//将该处指向的地址赋值给指向该处的指针
node = prev;//节点前移重新判断该节点
free(Del);
}
else
{
prev = node;//指针后移
node = node->next;//节点后移
}
}
return header;
}
//销毁结构体
void DelLinkList(LinkNOde* header)
{
while(header)
{
LinkNode* Del = header;
header = header->next;
free(Del);
}
}
int main(int argc, char** argv)
{
LinkNode* header = Init_LinkList();
header = DelNode(header);
LinkNode* node = header;
if (!header)
{
printf("已经全部删除");
return 0;//如果已经全部删除,则不需要打印
}
puts("out:>");
while (node->next)
{
printf("%d\t", node->Input);
node = node->next;
}
printf("%d\n", node->Input);//最后一处指向的地址为空,但该处依旧有值
DelLinkList(header);
return 0;
}
其他问题:
#define _CRT_SECURE_NO_WARNINGS 这是因为在vs2022中一些原本C语言的函数例如scanf()会被任务存在风险,在最开始加人该语句使得程序得以运行,当然,如果不加这句话也可以运行,可以使用自带的函数,例如scanf_s(),这种写法可以保证在该编译器中得以无风险运行,但是相同代码无法保证在其他编译器中运行。 另外,不止vs2022,其他的编译器可能也存在相关问题
瑕疵:
1、依旧无法同时实现任意类型的操作
2、依旧无法不同类型混合使用
3、更加冗长了
#剑指offer##C语言##初学者#