链表的创建与删除某一个结点

目录

1 创建链表和打印

2 链表某一结点删除

2.1使用双指针定位

2.2 使用单指针

3 创建链表与删除某个结点


1 创建链表和打印

 创建链表的图为下图:

 利用结构体,创建一个单向链表。这里的使用和柔性数组类似,把数组换成了指针。具体的过程如下代码所示:

typedef struct node
{
	int data;
	struct node* next;
}NODE;
NODE* creat()
{
	NODE* head, * p, * q;       //创建头指针
	int t;
	head = malloc(sizeof(NODE));
	if(!head)                   //判断是否在堆上开辟出空间
		return NULL;
	p = head;                   //记录头指针的地址
	while (1)
	{
		printf("输入一个正整数(以负数结束):");
		scanf_s("%d", &t);
		if (t < 0)              //链表结点值不为负数
			break;
		q = malloc(sizeof(NODE));
		if (!q)
			return NULL;
		q->data = t;            //利用指针连接两个指针
		p->next = q;
		p = q;
	}
	p->next = NULL;
	return head;
}
void print(NODE* head)  //利用传值调用打印链表
{
	
	NODE* p=NULL;
	p = head->next;
	if (!p)            //保证链表不为空
		printf("该链表为空!\n");
	else
	{
		printf("链表中的数据为:\n");
		while (p != NULL)  //指针指向最后的空指针时,跳出循环
		{
			printf("->%d", p->data);
			p = p->next;	
		}
		printf("\n");     //全部打印完之后进行换行
	}
}
int main()
{
	NODE* h;
	int data=0;
	h = creat();    //将链表创建出来
	print(h);       //打印显示链表
	return 0;
}

2 链表某一结点删除

2.1使用双指针定位

具体的过程代码已注释:

void dele(NODE* head, int t)    //将链表的头指针和需要删除的值拷贝一份进来
{
	NODE* p=NULL, * q=NULL;
	q = head;                   //使用q代替head指针
	p = head->next;             //使用p指向下一个节点
	while (p!= NULL)            //保证第一个结点有值,只需看指针是否为空即可
	{
		if (p->data == t) {         //当第一个结点为要删除的值时
			q->next = p->next;      //找到那个值后,将下一个结构体地址赋值给上一个结构体指针
			free(p);                //把要删除的值对应的结构体指针释放
			break;
		}
		else                   //设置两个指针在链表中挨着移动,访问链表中的每一个值
		{
			q = p;
			p = p->next;
		}
	}
	if (!p)                    //找不到对应要删除的值时
		printf("无符合条件的结点!!!\n");
}

2.2 使用单指针

我们要特别注意函数  h ead 是一 指针,由于结点的删除涉及到链表的修改。所以,想到使用二级指针的函数来删除链表的某一个结点。
代码过程如下,必要的代码后面附有必要的注释,提高了代码的可读性:
void dele(NODE** head, int value)
{
	if (!head || !(*head))                //保证传进来指针不为空指针
		return;
	NODE* pToBeDeleted = NULL;            //使用一个指针记录对应值的结构体地址
	if ((*head)->next->data == value)     //第一个结点是否为删除的值
	{
		pToBeDeleted = (*head)->next;
		(*head)->next = (*head)->next->next;
	}
	else
	{
		NODE* pNode = (*head)->next;      //[注意]这里代码若为NODE* pNode = *head;的话,会改变链表的数据。 这里使用的是传址调用。
		while (pNode->next != NULL && pNode->next->data != value)  //使用一个指针不断移动寻找所要删除的值,找不到则跳出此循环
		{
			pNode = pNode->next;
			
		}			
		if (pNode->next != NULL && pNode->next->data == value)
		{
			pToBeDeleted = pNode->next;            //记录要删除的结点地址
			pNode->next = pNode->next->next;        //找到那个值后,将下一个结构体地址赋值给上一个结构体指针,将链表串联起来
		}
        if (pNode->next==NULL)            //注意此指针的起始位置 不要盲目不断的尝试,多看内存
			printf("此链表无此值!!!\n");//如果找不到,打印输出
    }

	if (pToBeDeleted != NULL)           //释放要删除的结点地址,防止内存泄漏
		free(pToBeDeleted);
}

3 创建链表与删除某个结点

  这里想到在VS控制台输出时,输入一系列值创建一个链表并打印出来,同时可以删除链表中的值。于是将上面代码进行合并。

主函数:

int main()
{
	NODE* head;
	head=Creat(); 
	print(head);    //打印函数
	int value = 0;
	while (1)
	{
		printf("请输入需要删除的值为(以负数为结束标志):");   //使用负数为结束输入标志
		scanf_s("%d", &value);
		if (value<0)                                        //使用负数为结束输入标志
			break;
		dele(&head, value);                                 //传入头函数的地址和要删除的值
		print(head);
	}
	return 0;
}

调用的函数代码:

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
	int data;
	struct node* next;
}NODE;

NODE* Creat()
{
	NODE* pone, * ptwo;
	pone = NULL;
	ptwo = NULL;
	NODE* head = malloc(sizeof(NODE));
	if (!head)
		return NULL;
	pone = head;
	int data=0;
	while (1)
	{
		ptwo = malloc(sizeof(NODE));
		if (!ptwo)
			return NULL;
		printf("请输入链表中结点的值(以负数为结束标志):");
		scanf_s("%d", &data);
		if (data<0)
			break;
		ptwo->data = data;
		pone->next = ptwo;
		pone = ptwo;
	}
	pone->next = NULL;
	return head;
}
void print(NODE* head)
{
	NODE* p ;
	p= NULL;
	p = head->next;
	if (!p)
		printf("该链表中的数据为空!!!\n");
	else
	{
		printf("该链表中的数据为:\n");
		while(p!= NULL)                    //全部打印完
		{
			printf("->%d", p->data);
			p = p->next;
		}
		printf("\n");
	}
}
void dele(NODE** head, int value)
{
	if (!head || !(*head))
		return;
	NODE* pToBeDeleted = NULL;
	if ((*head)->next->data == value)     //第一个结点是否为所要的真值
	{
		pToBeDeleted = (*head)->next;
		(*head)->next = (*head)->next->next;
	}
	else
	{
		NODE* pNode = (*head)->next;      //[注意]这里代码若为NODE* pNode = *head;的话,会改变链表的数据。 
		while (pNode->next != NULL && pNode->next->data != value)
		{
			pNode = pNode->next;
			
		}			
		if (pNode->next != NULL && pNode->next->data == value)
		{
			pToBeDeleted = pNode->next;
			pNode->next = pNode->next->next;
		}
		if (pNode->next==NULL)            //注意此指针的起始位置 不要盲目不断的尝试,多看内存
			printf("此链表无此值!!!\n");
	}
	
	if (pToBeDeleted != NULL)
		free(pToBeDeleted);
}

结果如下:


 


以上代码均已调试,若有其他问题,请在评论区打出。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天是蓝的嘛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值