数据结构学习——双向链表

数据结构学习记录DAY4:双向链表

双向链表

双向链表简介:

如果认识单向链表,那么双向链表的定义其实非常之简单,只需要在单向链表的基础上,增加一个指向前结点的指针,即——对于任意一个结点,都有一个指向前一个结点和后一个结点的指针。以下为一个基础双向链表的定义。

struct Dnode{
   
	int elem;
	struct Dnode *prev;
	struct Dnode *next;
}

对于单纯的双向链表来说,头结点不存储数据,头结点的前驱指针(prev)指向NULL,后置指针(next)指向下一个结点,如果没有则指向空。

那么对于不单纯的双向链表来说又如何呢?

所谓不单纯的双向链表,其实就是指的双向循环链表。对其我是这样理解的:对于任意一个拥有头结点以外结点的双向链表,令其最后一个元素的尾指针指向头结点,而头结点的前驱指针指向尾结点,如此就形成了一个循环。
这样做有何益处呢?首先,对于单向链表来说,访问尾结点的时间复杂度为O(n),但由于双向循环链表有指向尾结点的指针,因此访问的时间复杂度变为O(1),可以缩减对于元素的访问时间,尤其是头尾两个结点。其次,双向链表可以方便地通过任意一个结点的位置访问到其他的结点,不必受方向的限制。
弊端自然是增加了指针域,内存利用率再次降低,当然空间换时间的买卖由使用者决定值不值。

双向循环链表

头结点 的prev指向最后一个结点,最后一个结点的next指向头结点。

  • 在头部和尾部进行插入和删除的时间复杂度都为O(1)
  • 能直接访问链表的最后一个结点

双向循环链表的创建

#define SUCCESS 0//此处注意后面也要用
#define FAILURE -1
typedef struct Dnode * DL;
#define SIZE_DNODE sizeof(*DL);

DL create_dlinklist(void)
{
   
    DL list = (DL)malloc(SIZE_DNODE);
    if(NULL != list)
    {
   
        list->prev = list->next = list;
    }
    return list;
}

双向循环链表的插入

static struct Dnode* create_ndoe(struct Dnode *prev, struct Dnode *next, int elem)
{
   
	struct Dnode *node = (struct Dnode*)malloc(SIZE_DNODE);
	if(NULL != node)
	{
   
		node->elem = elem;
		node->prev = prev;
		node->next = next;
	}
	return node;
}
//插入到pos后面的位置
static int insert_after(struct Dnode* node, ElemType elem)
{
   
    struct Dnode* insnode = create_node(node, node->next, elem);
    if(NULL == insnode)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值