数据结构——双向循环链表

        对于双向循环链表,我们先来抠字眼。分别看双向和循环,之前的帖子有讲双向链表,即指针域包含了一个指向前驱的指针和一个指向后继的指针;那循环,可以参考循环队列的概念,通俗讲就是链表的首尾相连,让双向链表最后一个结点的后继指向头结点而非NULL,同样让头结点的前驱指向尾结点,礼尚往来嘛。

#define TYPE int

话不多说我们开始构造

typedef struct Node
{
	TYPE data;
	struct Node *prior;
	struct Node *next;
}Node;

下面来看一下双循环链表的操作:

创建结点

//创建结点
Node *create_node(TYPE data)
{
	Node *node=malloc(sizeof(Node));
	node->data=data;
	node->prior=node;
	node->next=node;
	return node;
}

头添加

//头添加
bool add_head(Node *head,TYPE data)
{
	Node *node=create_node(data);
	node->prior=head;
	node->next=head->next;
	head->next->prior=node;
	head->next=node;
	return true;
}

尾添加

//尾添加
bool add_tail(Node *head,TYPE data)
{
	Node *node=create_node(data);
	node->prior=head->prior;
	node->next=head;
	head->prior->next=node;
	head->prior=node;
	return true;
}

按位置插入

//按位置插入
bool insert_list(Node *head,int index,TYPE data)
{
	Node *p=head->next;
	while(--index>0)
	{
		p=p->next;
		if(head==p->next) return false;
	}
	Node *node=create_node(data);
	node->prior=p;
	node->next=p->next;
	p->next->prior=node;
	p->next=node;
	return true;
}

按位置删除

//按位置删除
bool delete_index(Node *head,int index)
{
	if(head->next==head->prior) return false;
	Node *p=head;
	if(0!=index) p=head->next;
	while(--index>0)
	{
		p=p->next;
		if(head==p->next) return false;
	}
	p=p->next;
	p->next->prior=p->prior;
	p->prior->next=p->next;
	free(p);
	return true;
}

按值删除

//按值删除
bool delete_value(Node *head,TYPE val)
{
	if(head->next==head->prior) return false;
	for(Node *n=head->next;n->next!=head;n=n->next)
	{
		if(val==n->data)
		{
			n->next->prior=n->prior;
			n->prior->next=n->next;
			free(n);
			return true;
		}
	}
	return false;
}

修改

//修改
bool modify_list(Node *head,TYPE old,TYPE new)
{
	if(head->next==head->prior) return false;	
	for(Node *n=head->next;n->next!=head;n=n->next)
	{
		if(old==n->data)
		{
			n->data=new;
			return true;
		}
	}
	return false;
}

访问

//访问
bool access_list(Node *head,int index,TYPE *val)
{
	if(head->next==head->prior) return false;
	Node *p=head->next;
	while(--index>0)
	{
		p=p->next;
		if(head==p->next) return false;
	}
	*val=p->data;
	return true;
}

查询

//查询
int query_list(Node *head,TYPE key)
{
	if(head->next==head->prior) return -1;
	int num=0;
	for(Node *n=head->next;n->next!=head;n=n->next,num++)
	{
		if(key==n->data) return num;	
	}
	return -1;
}

后继遍历(从前往后)

//后继遍历
void show_next(Node *head)
{
	for(Node *n=head->next;n!=head;n=n->next)
	{
		printf("%d ",n->data);	
	}
	printf("\n");
}

前驱遍历(从后往前)

//前驱遍历
void show_prior(Node *head)
{
	for(Node *n=head->prior;n!=head;n=n->prior)
	{
		printf("%d ",n->data);	
	}
	printf("\n");
}

over

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值