单链表习题之删除指定元素

题目描述

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;
}

运行情况:

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值