双向循环链表

 

链表功能:尾插节点、头插节点、向后遍历,向前遍历、搜索节点、删除节点、删除链表

 

主函数:

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

int main()
{
	//初始化链表头
	list_node *head = NULL;
	head = init_list(head);
	
	//尾插节点
	tail_add_node(head,10);
	tail_add_node(head,20);
	tail_add_node(head,30);
	
	//头插节点
	head_add_node(head,3);
	head_add_node(head,5);
	head_add_node(head,8);
	
	//删除节点
	delete_list_node(head,30);
	
	//向后遍历链表
	forward_show_list(head);
	
	//向前遍历链表
	backward_show_list(head);
	
	//搜索节点
	search_list_node(head,20);
	
	//删除链表
	delete_list(head);

	return 0;
}

 

尾插节点:

void tail_add_node(list_node *head, int num)
{
	list_node *node = NULL;
	node = (list_node *)malloc(sizeof(list_node));
	if(node == NULL)
		printf("malloc node error!\n");
	
	node->a = num;
	
	node->prev = head->prev;	//新节点的前驱节点连末尾节点(head->prev: 头节点的前驱等于末尾节点)
	node->next = head;			//新节点的后继节点连接头节点
	
	head->prev->next = node;	//末尾节点的后继节点连接新节点
	head->prev = node;			//头节点的前驱结点连接新节点
}

 

头插节点:

void head_add_node(list_node *head, int num)
{
	list_node *node = NULL;
	node = (list_node *)malloc(sizeof(list_node));
	if(node == NULL)
		printf("malloc node error!\n");
	
	node->a = num;
	
	//链接节点
	node->prev = head;			//新节点的前驱指向头节点
	node->next = head->next;	//新节点的后继 指向 头节点后面的一个节点
	
	head->next->prev = node;	//头节点的后面一个节点的前驱指向新节点(原本指向头节点)
	head->next = node;			//头节点的后继指向新节点
	
}

 

向后遍历:

void forward_show_list(list_node *head)
{
	list_node *p = NULL;
	for(p=head->next; p!=head; p=p->next)
	{
		printf("a = %d\n",p->a);
	}
}

 

向前遍历:

void backward_show_list(list_node *head)
{
	list_node *p = NULL;
	for(p=head->prev; p!=head; p=p->prev)
	{
		printf("a = %d\n",p->a);
	}
}

 

搜索节点:

int search_list_node(list_node *head, int num)
{
	list_node *p = NULL;
	
	//遍历链表查找指定值
	for(p=head->next; p!=head; p=p->next)	
	{
		if(p->a == num)
		{
			printf("already found!\n");
			return 0;
		}
	}
	
	return -1;
}

 

删除节点:

int delete_list_node(list_node *head, int num)
{
	list_node *p = NULL;
	list_node *q = NULL;
	
	for(q=head,p=head->next; p!=head; q=p,p=p->next)
	{
		if(p->a == num)
		{
			q->next = p->next;		//p节点的前一个节点后继连接p节点的后一个节点(p为要删除的节点)
			p->next->prev = q;		//p节点的后一个节点的前驱连接p节点的前一个节点
			free(p);				//释放p指向的那片空间
			
			return 0;
		}
	}
	
	return -1;
}

 

删除链表:

void delete_list(list_node *head)
{
	list_node *p = NULL;
	list_node *q = NULL;
	
	head->prev->next = NULL;		//先将末尾节点的后继节点给置为NULL,(原本指向head)使其循环链表不循环
	
	for(p=q=head; p!=NULL; p=q)		//开始p和q都指向头节点
	{
		q = p->next;		        //q指向后面一个节点
		free(p);			//释放p(p此时指向的是q的前面),执行for的p=q,此时p又与q指向同一个节点。
	}	

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值