带头结点双向循环列表的创建,增删改查

#ifndef __DOUBLELINKEDLISTWITHHEAD_H__
#define __DOUBLELINKEDLISTWITHHEAD_H__

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

typedef  int Elemtype;
typedef struct DLNODE
{

	Elemtype data;
	struct DLNODE* prev;
	struct DLNODE* next;

}DLNode;

typedef struct LIST
{

	struct DLNODE* first;
	struct DLNODE* last;
	int num;

}List;

DLNode* init_DLNode(Elemtype v);
List* init_list(void);
List* creat_list(List* list);
List* add_a_node(List* head, Elemtype var,Elemtype y);
void print_list(List* li);
void delete_a_node(List* lm, Elemtype vm);
void delete_all_node(List* lm, Elemtype vm);






#endif

这段代码是一个双向循环链表的头文件。让我们来解析一下:

- 首先,引入了`stdio.h`和`stdlib.h`头文件,以便使用标准输入输出和动态内存分配函数。
- 定义了元素类型`Elemtype`,这里使用`int`作为示例。
- 定义了双向链表的节点结构`DLNode`。节点结构包含了数据域`data`和两个指针域`prev`和`next`,分别指向前一个节点和后一个节点。
- 定义了链表结构`List`。链表结构包含了指向首节点的指针`first`、指向尾节点的指针`last`,以及记录节点数量的变量`num`。

这个头文件为双向链表提供了节点结构和链表结构的定义,可以在其他源文件中包含该头文件,以使用这些定义的结构类型来操作双向循环链表。

#include "DoubleLinkedListWithHead.h"

DLNode* init_DLNode(Elemtype v)   //初始化一个结点
{
	DLNode* p = malloc(sizeof(DLNode));
	
	p->data = v;
	p->prev = NULL;
	p->next = NULL;
	
	return p;
}

List* init_list(void)     //创造头结点
{
	List* l = malloc(sizeof(List));
	
	l->first = NULL;
	l->last = NULL;
	l->num = 0;

	return l;
}

List* creat_list(List* list)  //创建链表
{
	Elemtype vl = 0;
	DLNode* p = NULL;

	while(1)
	{
		scanf("%d",&vl);
		if(vl == 0)
		{
			break;
		}

		p = malloc(sizeof(DLNode));
		
		p->data = vl;
		p->next = NULL;

		if(list->first == NULL)   //插入到首元结点
		{
			list->first = p;
			list->last = p;
			list->first->prev = list->last;
			list->last->next = list->first;
		}
		else
		{
			list->last->next = p;    //尾插法
			p->prev = list->last;
			list->last = p;
			list->first->prev = list->last;
			list->last->next = list->first;
		}
		list->num++;
	}
	return list;
}

List* add_a_node(List* head, Elemtype var,Elemtype y) //链表中插入一个结点
{
	if(head == NULL)
	{
		return NULL;
	}
	
	DLNode* p = head->first;
	int n = head->num;
	
	 if (n == 0)

	 {
        DLNode* newNode = init_DLNode(y);   //链表中没有结点
        head->first = newNode;
        head->last = newNode;
		head->first->prev = head->last;
		head->last->next = head->first;
        head->num++;
        return NULL;
    }

	while(n--)
	{
		if(p->data == var)
		{
			break;
		}
		p = p->next;
	}

	DLNode* py = init_DLNode(y);
	
	if(n == -1)   //没找到,插入到尾部
	{
		head->last->next = py;
		py->prev = head->last;
		head->last = py;
		py->next = head->first;
	}
	else
	{
		if(p == head->first && n != -1)   //插入到头部
		{
			py->next = head->first;
			head->first->prev = py;
			head->first = py;
			head->last->next = py;
		}
		else
		{
			py->prev = p->prev;   //插入中间
			py->next = p;
			p->prev->next = py;
			p->prev = p;
		}
	}
	head->num++;

	return head;
}


void delete_all_node(List* lm, Elemtype vn) //删除链表中数据域为vn的结点
{
	if(lm == NULL || lm->num == 0)   //无结点和头结点
	{
		return;
	}
	
	DLNode* pm = lm->first;
	DLNode* pn = lm->first;
	int	nu = lm->num;
	
	while(nu--)
	{
		pm = pn;
		while(pm)
		{
			if(pm->data == vn)
			{
				break;
			}
			pm = pm->next;
		}
		
		if(pm == NULL)    //没找到
		{
			return;
		}
		else
		{
			lm->num--;
			pn = pm->next;
			if(pm == lm->last)  //删除尾结点
			{
				lm->last = lm->last->prev;
				lm->last->next = lm->first;
				pm->prev = NULL;
			}
			else if(pm == lm->first)   //删除首元结点
			{
				lm->first = lm->first->next;
				lm->first->prev = lm->last;
				pm->next = NULL;
			}
			else
			{
				pm->prev->next = pm->next;  //删除中间
				pm->next->prev = pm->prev;
				pm->prev = NULL;
				pm->next = NULL;
			}
		
			free(pm);
			pm = NULL;	
	   }
	}
}

void print_list(List* li)    
{
	int n  = (li->num)*2;
	DLNode* pn = li->first;
		
	while(n--)
	{
		printf("%d ",pn->data);
		pn = pn->next;
	}

	printf("\n结点数:%d",li->num);
}

主函数

#include "DoubleLinkedListWithHead.h"

int main()
{
	//创建头结点
	List* l = init_list();
	//输入链表
	l = creat_list(l);
	//打印链表
	printf("原链表:");
	print_list(l);
	printf("\n");
	//printf("3前面插入10:");
	//add_a_node(l,3,10);
	printf("删除链表中数值为5的结点:");
	delete_all_node(l,5);
	//打印插入后链表
	print_list(l);
	return 0;
}

运行结果

      

代码小长,复制粘贴点个赞吧,谢谢了

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值