链表的删除和清除

链表的删除和清除,第1张

链表的删除--

这个代码实现的是查找指定的值并删除后输出所有数,如果要实现删除第几个之类 的代码也差不多。

--main.h--

#ifndef _MAIN_H_
#define _MAIN_H_

#include 
#include 

typedef struct node{
	int value;
	struct node *next;
}node;

#endif
--main.c--

#include "main.h"
 
//typedef struct node{
//	int value;
//	struct node *next;
//}node;
 
void add(node** head,node** tail,int number);
void printff(node *head);
void search(node *head);
void cut(node **head);
int main(int argc,char const *argv[]){
	int number=0;
	node *head;
	node *tail;
	head=tail=NULL;
	while(number!=-1)
	{
		scanf("%d",&number);
		if (number!=-1)
		{
			add(&head,&tail,number);
		}
	}  
	cut(&head);
	printff(head);
	return 0;
}
 
void add(node** head,node** tail,int number)
{
	node *p=(node*)malloc(sizeof(node));
	p->next=NULL;
	p->value=number;
	node *k=*head;
	if (k==NULL)
	{
		*head=p;
		*tail=p;
	}
	else
	{
		(*tail)->next=p;
		*tail=p;
	}	
}
void printff(node *head)
{
	node *p=head;
	for (p=head;p;p=p->next)
	{
		printf("%d ",p->value); 
	}
}

void search(node *head)
{
	node *p=head;
	int nu=0;
	printf("\n请输入你要查找的值\n");
	int x;
	scanf("%d",&x);
	for (p=head;p;p=p->next)
	{
		if (p->value==x)
		{
			nu=1;
			break;
		}
	}
	if (nu==0)
	{
		printf("notfound");
	}
	else
	{
		printf("found成功");
	}
}
void cut(node **head)
{
	node *p,*former;
	int x;
	printf("\n请输入你要删除的数据\n");
	scanf("%d",&x);
	for (p=*head,former=NULL;p;former=p,p=p->next)
	{
		if (p->value==x)
		{
			if (p==*head)
			{
				*head=p->next;
				free(p);
				break;
			}
			else
			{
				former->next=p->next;
				free(p);
				break;	
			}			
		}
	} 
}

来看这个程序的关键点首先删除肯定是传地址进函数然后用二级指针接收,然后最关键的就是那个for循环的使用,前面有两个条件,一个是用来遍历的p,一个是用来保存上一个结点地址的former,条件就是p!=NULL,最关键的来了,这里将former放在这里,因为删除第一个结点的时候是特殊情况,用不到前结点,所以刚开始的时候former是等于NULL,在第一次结束后former先=p,再进行p=p->next,保证了former等于第一个结点,接下来p再次循环时就是第二个结点,依此类推,很巧妙!那个王嘉昀上课讲过?管她呢。

接下来就是恺哥讲的关于链表的技巧,如果我们自己来想,可能很容易就写成下面的样子,

如果我们空间逻辑能力不是很强,我个人感觉画图会好一点,但是这里的话对于这类题有个方法, 即p->value,访问一个结构的结构变量,那么前面必不能为空,然后看这个图上,因为for循环的条件是p!=NULL,所以p保证了,然而q并没能保证,即可能出现q为空的情况,反应到链表即删除第一个结点的时候。

主干程序就是这样,当然还有比如没有找到就输出notfound这些自行添加。

链表的清除--

--main.c--

#include "main.h"
 
//typedef struct node{
//	int value;
//	struct node *next;
//}node;
 
void add(node** head,node** tail,int number);
void printff(node *head);
void search(node *head);
void cut(node **head);
void clear(node **head);
int main(int argc,char const *argv[]){
	int number=0;
	node *head;
	node *tail;
	head=tail=NULL;
	while(number!=-1)
	{
		scanf("%d",&number);
		if (number!=-1)
		{
			add(&head,&tail,number);
		}
	}  
	cut(&head);
	printff(head);
	clear(&head);
	return 0;
}
 
void add(node** head,node** tail,int number)
{
	node *p=(node*)malloc(sizeof(node));
	p->next=NULL;
	p->value=number;
	node *k=*head;
	if (k==NULL)
	{
		*head=p;
		*tail=p;
	}
	else
	{
		(*tail)->next=p;
		*tail=p;
	}	
}
void printff(node *head)
{
	node *p=head;
	for (p=head;p;p=p->next)
	{
		printf("%d ",p->value); 
	}
}

void search(node *head)
{
	node *p=head;
	int nu=0;
	printf("\n请输入你要查找的值\n");
	int x;
	scanf("%d",&x);
	for (p=head;p;p=p->next)
	{
		if (p->value==x)
		{
			nu=1;
			break;
		}
	}
	if (nu==0)
	{
		printf("notfound");
	}
	else
	{
		printf("found成功");
	}
}
void cut(node **head)
{
	node *p,*former;
	int x;
	printf("\n请输入你要删除的数据\n");
	scanf("%d",&x);
	for (p=*head,former=NULL;p;former=p,p=p->next)
	{
		if (p->value==x)
		{
			if (p==*head)
			{
				*head=p->next;
				free(p);
				break;
			}
			else
			{
				former->next=p->next;
				free(p);
				break;	
			}			
		}
	} 
}
void clear(node **head)
{
	node *p,*q;
	for (p=*head;p;p=q)
	{
		q=p->next;
		free(p);
	}
}

依然是for循环里的妙用。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/676141.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存