双向链表增删改查、遍历、倒置、销毁等——数据结构——day3

本文详细介绍了如何使用C语言创建链表,包括定义数据结构、创建节点、链表操作(如头插、尾插、遍历、查找和删除),以及链表的销毁和倒置功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,我先把我的头节点写出来,里面有整理好的结构体

#ifndef __DOULINK_H__
#define __DOULINK_H__

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

typedef struct student
{
	int id;
	char name[50];
	int score;
}DATA_TYPE;		//构造数据结构体

typedef struct node
{
	DATA_TYPE data;	//数据
	struct node *ppre;		//前驱节点指针
	struct node *pnext;		//后继节点指针
}DOULINK_NODE;	//构造节点结构体

typedef struct list
{
	DOULINK_NODE *phead;	//头节点指针
	int clen;				//计算个数
}DOULINK_LIST;	//构造链表结构体

extern DOULINK_LIST *CreatDouLinkList();	//创建链表
extern DOULINK_NODE *CreatNode(DATA_TYPE *data,int num);	//创建节点
extern int PushHeadDouLink(DOULINK_LIST *plist,DOULINK_NODE *pnode);	//头插
extern int PopHeadDouLink(DOULINK_LIST *plist);							//头删
extern int PushTailDouLink(DOULINK_LIST *plist,DOULINK_NODE *pnode);	//尾插
extern int PopTailDouLink(DOULINK_LIST *plist);							//尾删
extern void ListForEach(DOULINK_LIST *plist);							//遍历
extern DOULINK_NODE *FindNodeDouLink(DOULINK_LIST *plist,int (*pfun)(DOULINK_NODE *,void *),void *t);														//查找指定的数据并修改
extern void DestoryDouLink(DOULINK_LIST *plist);						//销毁
extern int DeleteNodeDouLink(DOULINK_LIST *plist,char *name);			//删除指定的数据
extern void ReverseDouLink(DOULINK_LIST *plist);						//倒置
#endif

创建链表

DOULINK_LIST *CreatDouLinkList()
{
	DOULINK_LIST *ptemp = malloc(sizeof(DOULINK_LIST));	//申请空间
	if(NULL == ptemp)
	{
		perror("fail to creat list malloc");
		return NULL;
	}

	ptemp->phead = NULL;
	ptemp->clen = 0;

	return ptemp;
}

创建节点

DOULINK_NODE *CreatNode(DATA_TYPE *data,int num)
{
	DOULINK_NODE *pnode = malloc(sizeof(DOULINK_NODE));
	if(NULL == pnode)
	{
		perror("fail to creat node malloc");
		return NULL;
	}

	pnode->data = data[num];
	pnode->ppre = NULL;
	pnode->pnext = NULL;
	
	return pnode;
}

判断链表是否为空

int IsEmptyLink(DOULINK_LIST *plist)
{
	return NULL == plist->phead;
}

头插

int PushHeadDouLink(DOULINK_LIST *plist,DOULINK_NODE *pnode)
{
	if(NULL == plist || NULL == pnode)
	{
		return -1;
	}

	pnode->pnext = plist->phead;
	if(plist->clen != 0)
	{
		plist->phead->ppre = pnode;
	}
	plist->phead = pnode;

	plist->clen++;

	return 0;
}

头删

int PopHeadDouLink(DOULINK_LIST *plist)
{
	if(IsEmptyLink(plist))
	{
		return 0;
	}
	
	DOULINK_NODE *ptmp = plist->phead;

	if(plist->clen == 1)
	{
		free(ptmp);
		plist->phead = NULL;
		plist->clen--;
		return 0;
	}

	plist->phead = plist->phead->pnext;
	free(ptmp);
	plist->phead->ppre = NULL;
	plist->clen--;

	if(plist->clen == 1)
	{
		plist->phead->pnext = NULL;
	}

	return 0;
}

尾插

int PushTailDouLink(DOULINK_LIST *plist,DOULINK_NODE *pnode)
{
	if(NULL == plist || NULL == pnode)
	{
		return -1;
	}

	if(IsEmptyLink(plist))
	{
		plist->phead = pnode;
	}
	else
	{
		DOULINK_NODE *ptmp = plist->phead;

		while(ptmp->pnext)
		{
			ptmp = ptmp->pnext;
		}

		ptmp->pnext = pnode;
		pnode->ppre = ptmp;
	}
	plist->clen++;
	return 0;
}

尾删

int PopTailDouLink(DOULINK_LIST *plist)
{
	if(IsEmptyLink(plist))
	{
		return 0;
	}

	DOULINK_NODE *ptmp = plist->phead;
	while(ptmp->pnext)
	{
		ptmp = ptmp->pnext;
	}

	if(ptmp->ppre != NULL)
	{
		ptmp->ppre->pnext = NULL;
	}
	else
	{
		plist->phead = NULL;
	}

	free(ptmp);
	plist->clen--;

	return 0;
}

遍历

void ListForEach(DOULINK_LIST *plist)
{
	DOULINK_NODE *ptmp = plist->phead;
	
	while(ptmp)
	{
		printf("id = %d\n",ptmp->data.id);
		printf("name = %s\n",ptmp->data.name);
		printf("score = %d\n",ptmp->data.score);
		ptmp = ptmp->pnext;
	}
}

查找指定的数据并修改

int compare_id(DOULINK_NODE *pnode,void *t)
{
	if(*(int *)t == pnode->data.id)
	{
		return 1;
	}
	return 0;
}

int compare_name(DOULINK_NODE *pnode,void *t)
{
	if(!strcmp(pnode->data.name,(char *)t))
	{
		return 1;
	}

	return 0;
}

int i = 3;
DOULINK_NODE *p = FindNodeDou_Link(plist,compare_id,&i);
if(NULL != p)
{
	p->data.score = 99;
}
p = FindNodeDou Link(plist, compare_name,"zhangsan"); 
if(NULL != p)
{
	strcpy(p->data.name,"wuhuuuuu");
}

DOULINK_NODE *FindNodeDouLink(DOULINK_LIST *plist,int (*pfun)(DOULINK_NODE *,void *),void *t)
{
	if(IsEmptyLink(plist))
	{
		return NULL;
	}

	DOULINK_NODE *ptmp = plist->phead;

	while(ptmp)
	{
		if(pfun(ptmp,t))
		{
			return ptmp;
		}
		ptmp = ptmp->pnext;
	}

	return NULL;
}

结果:
在这里插入图片描述

销毁

void DestoryDouLink(DOULINK_LIST *plist)
{
	
	while(!IsEmptyLink(plist))
	{
		PopHeadDouLink(plist);
	}

	free(plist);
}

删除指定的数据

int DeleteNodeDouLink(DOULINK_LIST *plist,char *name)
{
	if(IsEmptyLink(plist))
	{
		return -1;
	}

	DOULINK_NODE *ptmp = plist->phead;
	DOULINK_NODE *p = NULL;
	int del_cnt = 0;

	while(ptmp)
	{
		if(!strcmp(ptmp->data.name,name))
		{
			if(ptmp == plist->phead)
			{
				plist->phead = ptmp->pnext;
				free(ptmp);
				ptmp = plist->phead;
			}
			else
			{
				p->pnext = ptmp->pnext;
				free(ptmp);
				ptmp = p->pnext;
			}
			plist->clen--;
			del_cnt++;
		}
		else
		{
			p = ptmp;
			ptmp = ptmp->pnext;
		}
	}
	
	return del_cnt;
}

倒置

void ReverseDouLink(DOULINK_LIST *plist)
{
	int i = 0;
	if(IsEmptyLink(plist))
	{
		return ;
	}

	DOULINK_NODE *prev = plist->phead;
	DOULINK_NODE *p = NULL;

	plist->phead = NULL;

	while(prev)
	{
		p = prev;
		prev = prev->pnext;
		p->pnext = NULL;
		p->ppre = NULL;

		p->pnext = plist->phead;
		if(i > 0)
		{
			plist->phead->ppre = p;
		}
		plist->phead = p;
		++i;
	}
}

结果:
在这里插入图片描述

以上就是今天内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值