题目描述
Title Description
Enter n integers, establish a single linked list of header nodes according to the input order, and then enter a data m to delete all nodes with a value of m in the single linked list. Output the initial single linked list and the deleted single linked list respectively
中文翻译:
输入n个整数,根据输入顺序建立标头节点的单链接列表,然后输入数据m以删除单链接列表中值为m的所有节点。分别输出初始单链表和删除的单链表
input
Number of input data n in the first row;
Input n integers in the second line;
In the third line, enter the data to be deleted m;
output
The first row outputs the length of the original single linked list;
The second row outputs the data of the original single linked list in turn;
The third row outputs the length of the single linked list after deletion;
The fourth row successively outputs the deleted single linked list data
sample input
10
56 25 12 33 66 54 7 12 33 12
12
sample output
10
56 25 12 33 66 54 7 12 33 12
7
56 25 33 66 54 7 33
分析
一、考虑为在移动整张表的过程中删除数据
错误分析:
上面这种分析:
第一个重复代码太多,数据的删除操作重复两次
第二个循环重复,通过for循环的判定,又在内部进行数据移动,没必要
下面进行代码改进,直接通过p_cur进行判定移动
完整代码:
#include <stdio.h>
#include <stdlib.h>
typedef int elem_type;
typedef struct _node node;
//定义结点
struct _node
{
elem_type data;
node *next;
};
typedef struct _t_node
{
int length;
node *next;
}t_node;
//创建
t_node* create_list()
{
t_node* p_head = (t_node*)malloc(sizeof(t_node));
if(p_head != NULL) {
p_head->length = 0;
p_head->next = NULL;
}
return p_head;
}
//插入,这里直接尾插
int insert_list(t_node *p_head,elem_type data)
{
int res = (p_head != NULL);
node *data_node = NULL;
if(res) {
data_node = (node*)malloc(sizeof(node));
if(data_node != NULL) {
data_node->data = data;
data_node->next = NULL;
}
}
res = (res && data_node != NULL);
if(res) {
node *p_node = p_head->next;
//直接让指针干到最后一个结点
while(p_node != NULL && p_node->next != NULL) {
p_node = p_node->next;
}
if(p_node == NULL) {
data_node->next = p_head->next;
p_head->next = data_node;
} else {
data_node->next = p_node->next;
p_node->next = data_node;
}
p_head->length++;
}
return res;
}
//打印表
void print_list(t_node *p_head)
{
if(p_head != NULL && p_head->length != 0){
node *p_node = p_head->next;
for(int i = 0;i < p_head->length;i++) {
printf("%d ",p_node->data);
p_node = p_node->next;
}
}
}
//利用两个指针进行删除操作
void delete_elem(t_node *p_head,elem_type value)
{
node *p_cur = NULL;
node *p_previous = NULL;
int len = 0;
if(p_head != NULL) {
p_cur = p_head->next;//你的p_head复合类型要与他内存结构关联
p_previous =(node*)p_head;//类型必须一致
len = p_head->length;
}
for(;p_cur != NULL;p_cur=p_cur->next) {
//先判定在循环
if(p_cur->data != value) {
//p_previous的移动是在正常没有删除的情况下移动
p_previous = p_previous->next;
} else if(p_cur->data == value) {
//删除操作
p_previous->next = p_cur->next;
p_head->length--;
}
}
}
int main()
{
t_node *p_head = create_list();
insert_list(p_head,56);
insert_list(p_head,12);
insert_list(p_head,33);
insert_list(p_head,12);
insert_list(p_head,12);
insert_list(p_head,36);
print_list(p_head);
delete_elem(p_head,12);
printf("\n------\n");
print_list(p_head);
return 0;
}
二、考虑为按照结点地址和序号删除数据
下面简单说一下两个操作:
按照节点序号删除分析:
按照节点地址删除分析:
具体代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct _link_list_node link_list_node;
struct _link_list_node{
int data;
link_list_node *next;
};
//创建头节点
link_list_node *create_list()
{
link_list_node *p_head = (link_list_node*)malloc(sizeof(link_list_node));
if(p_head != NULL) {
p_head->data = 0;
p_head->next = NULL;
}
return p_head;
}
//数据插入,全部实现尾部插入
int insert_data(link_list_node *p_head,int data)
{
int res = p_head != NULL;
if(res) {
link_list_node *node = (link_list_node*)malloc(sizeof(link_list_node));
link_list_node *p_cur = p_head;
if(node != NULL) {
node->data = data;
while(p_cur->next != NULL) {
p_cur = p_cur->next;
}
node->next = p_cur->next;
p_cur->next = node;
p_head->data++;
}
}
return res;
}
//打印链表
void print_list(link_list_node *p_head)
{
if(p_head != NULL) {
link_list_node *p_cur = p_head->next;
while(p_cur != NULL) {
printf("%d ",p_cur->data);
p_cur = p_cur->next;
}
printf("\n");
}
}
//删除节点
//根据节点地址删除数据
void delete_data(link_list_node *p_head,link_list_node *p_del)
{
if(p_head != NULL && p_del != NULL) {
link_list_node *p_cur = p_head;
while(p_cur->next != p_del) {
p_cur = p_cur->next;
}
p_cur->next = p_del->next;
p_head->data--;
}
}
//根据序号来删除数据
void delete_data_by_pos(link_list_node *p_head,int pos)
{
if(p_head != NULL && pos >= 0 && pos < p_head->data) {
link_list_node *p_cur = p_head;
int i;
for(i = 0;i < pos;i++) {
p_cur = p_cur->next;
}
link_list_node *p_del = p_cur->next;
p_cur->next = p_del->next;
p_head->data--;
}
}
int main() {
link_list_node *p_head = create_list();
int num;
scanf("%d",&num);
int i;
int data;
int del_data;
for(i = 0;i < num;i++) {
scanf("%d",&data);//输入num个数据
//数据全部插入链表
insert_data(p_head,data);
}
scanf("%d",&del_data);
printf("%d\n",p_head->data);
print_list(p_head);
//具体业务逻辑代码
link_list_node *p_cur = p_head->next;
while(p_cur != NULL) {
//当前位置如果是删除值
if(p_cur->data == del_data) {
delete_data(p_head,p_cur);//删除这个节点
}
p_cur = p_cur->next;
}
/*
link_list_node *p_cur = p_head->next;
for(pos = 0;pos < p_head->data;pos++) {
if(p_cur->data == del_data) {
delete_data_by_pos(p_head,pos--);
}
p_cur = p_cur->next;
}
*/
printf("%d\n",p_head->data);
print_list(p_head);
return 0;
}
运行情况: