对单链表中重复的元素进行删除【C语言】【可直接运行】

算法思想:

1、创建一个单链表并输入数据
2、双重遍历链表
  • 判断链表是否为空,若为空,则返回(在36行已经行进行判断)
  • 如果第一层遍历时,有值与之相同,则删除该值并释放空间,再继续遍历
  • s的作用:作为一个前驱,主要是前驱是为了确保在删除最后一个结点的时候,前一个结点指向的是空值(体现在43行)
3、打印输出最后的链表

具体代码

#include<stdio.h>
#include<stdlib.h>

typedef  int  Elemtype;//定义数据类型为int类型 
typedef struct LNode{
    
    //定义结构体 
	Elemtype data;
	struct LNode *next;
}LNode,*Linklist;

void Init_Linklist(Linklist *L)//初始化链表 
{
    
    
	*L=(Linklist)malloc(sizeof(LNode));//定义头结点 
	(*L)->next=NULL;//置结束标记NULL 
}

void Create_Linklist(Linklist *L, int LEN)//创建链表(有头结点) 
{
    
    
	LNode *p,*q;
	p = *L;//p指向头结点 
	printf("请输入单链表:\n");
	for(int i=0;i<LEN;i++)
	{
    
    
		q=(Linklist)malloc(sizeof(LNode));//定义q结点 
		scanf("%d",&q->data);
		p->next=q;
		p=q;//p挪向下一个结点q(循环输入data值) 
	}
	p->next=NULL;
}

void DeleteSame(Linklist *L)//删除值相同的结点 
{
    
    
	LNode *p,*q,*s;
	p = (*L)->next;//此时p为链表的第一个元素 

	for(p;p!=NULL;p=p->next)//p遍历整个链表,当p不等于空时,p指向它的下一个结点 
	{
    
    
		s=p;                    //s指向要删除结点的前驱 
		for(q=p->next;q!=NULL; )
		{
    
    
			if(q->data==p->data)//当q的值与p的值相同时 
			{
    
    
				s->next=q->next;//q指向原来q的下一个结点 
				free(q);//释放q的内存空间 
				q=s->next;
			}
			else
			{
    
    
				s=q;//s指向下一个结点q
				q=q->next;//q指向q的下一个结点 
			}
		}
	}
	
}
void Print_Linklist(Linklist *L)//打印链表的值 
{
    
    
	LNode *p;
	p = *L;
	while(p->next)//当p->next不为空时 
	{
    
    
		p=p->next;//遍历 
		printf("%d ",p->data);
	}
	printf("\n");
}

int main()
{
    
    
	
	int LEN;
	printf("请输入单链表的长度:\n");
	scanf("%d", &LEN);
	
	Linklist L;
	Init_Linklist(&L);
	Create_Linklist(&L,LEN);
	
	printf("原始链表为:\n");
	Print_Linklist(&L);
	
	DeleteSame(&L);
	
	printf("删除后链表为:\n");
	Print_Linklist(&L);
	
	return 0;
}

最后运行结果

在这里插入图片描述

讲解视频【粗糙风格】

B站小视频

猜你喜欢

转载自blog.csdn.net/weixin_42198265/article/details/122315262