链表

链表是一种线性数据结构,不同于数组,其顺序由指针决定。本文聚焦于未排序的双链表,每个元素包含关键字、前驱指针和后继指针。使用哨兵节点可以简化代码,但可能增加存储开销。链表的删除操作并不真正删除对象,只是从链表中移除,对象本身依然存在。链表的灵活性允许在各种编程环境中实现,如使用数组模拟。
摘要由CSDN通过智能技术生成

链表(linked list):一种数据结构,其中的对象按线性顺序排列,与数组类似,但不同的是,数组按下标排序,而链表顺序由指针决定。

链表有多种形式:单/双链接,已/未排序,是/否循环。本文讨论未排序的双链接链表。

双向链表(doubly linked list)L中的每一个元素都是一个对象,通常有三个属性:一个关键字key(储存的数据),两个指针:next与prev。当然,也可以包括其他的辅助数据(或称卫星数据)。

对于每一个元素x,x.prev指向前驱元素,x.next指向后继元素。

x.prev=NULL时,x为链表的头(head);x.next=NULL时,x为链表的尾(tail)。L.head指向链表第一个元素,若L.head=NULL,则链表为空。

函数原型:

list-search(L, k):
x = L.head
while x!=NULL && x.key!=k:
    x = x.next
return x
list-insert(L, x)
x.next = L.head
if L.head != NULL
    L.head.prev = x
L.head = x
x.prev = NULL
list-delete(L, x):
if x.prev!=NULL:
    x.prev.next = x.next
else L.head = x.next
if x.next!=NULL
    x.next.prev = x.prev

哨兵:一个用来简化边界条件的哑对象。L.null代表NULL,但也拥有和其他对象相同的各个属性。

使用哨兵后的函数原型:

list-search(L, k):
x = L.null.next
while x!=L.null && x.key!= k:
    x = x.next
return x
list-insert(L, x):
x.next = L.null.next.prev
L.null.next.prev = x
L.null.next = x
x.prev = L.null
list-delete(L, x):
x.prev.next = x.next
x.next.prev = x.prev

哨兵基本不能降低数据结构相关操作的渐进时间界,但是可以降低常数因子。在循环语句中使用哨兵的好处往往是使代码简介,而非提高速度。

并且,如果有许多个很短的链表,使用哨兵反而会浪费大量储存空间资源。

显然,链表的delete操作并非真正地把某个对象删除,只是把它踢出了链表而已,实际上这个对象仍旧存在。

事实上,虽然常用结构体、类、对象这类数据类型储存链表,当程序语言没有这类数据类型时,可以用单数组或多数组的形式储存链表,且可以在单数组中通过free自由表分配和释放链表元素,即便自由表与链表交错仍然可行。所以,数据结构是很灵活的,并非一成不变。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值