数据结构——双向链表

        双向链表区别于单链表,单链表的每个结点只包含一个指向下一个结点的指针,但是双向链表的指针域包含了前驱和后继,即指向前一个结点和下一个结点的指针。其主要意义在于可以在链表的任意结点位置正序或逆序遍历链表,提高访问链表结点的效率,下面我们一起来看一下。

#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=NULL;
	node->next=NULL;
	return node;
}

头添加

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

尾添加

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

按位置插入

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

按位置删除

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

按值删除

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

修改

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

访问

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

查询

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

遍历

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

好了,下面我们浅浅的测试一下

int main(int argc,const char* argv[])
{
	Node *head=create_node(0);
	for(int i=0;i<5;i++)
	{
		add_head(head,i+1);	
	}
	for(int i=0;i<5;i++)
	{
		add_tail(head,i+6);	
	}
	//insert_list(head,3,8);
	delete_index(head,9);
	//delete_value(head,10);
	//modify_list(head,6,66);
	TYPE val;
	access_list(head,6,&val);
	printf("%d\n",val);
	//printf("%d\n",query_list(head,66));

	show_list(head);	
	return 0;
}

完美,双向链表的基本操作基本如上。

over

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值