首页>>后端>>Golang->Golang:单指针实现双链表

Golang:单指针实现双链表

时间:2023-11-30 本站 点击:0

如何用单指针实现双链表?要解决这个问题,我们需要一些思维的铺垫,下面分三个步骤,由浅入深地带你实现!

正常:实现一个单链表

网上单链表的实现非常多,考虑到实用性,设计也不尽相同。下面选一个最直白简单的。

show me the code

https://gist.github.com/RBowind/1561ac542b0c33bbf1da20d47640d80f

//Element单链表每一个节点typeElementstruct{next*Element//索引下一个节点Valueinterface{}}typeListstruct{root*Element//整个链表tail*Element//索引最后一个节点,方便pushlenint//单链表的长度}

不正常:用单指针地址再实现一个单链表

假设现在我觉的上面的结构会嵌套很深,看起来难受(想炫技?),那么可以把头节点的的next 改成 ptr,指向下一个节点的指针地址,然后下一个节点的 ptr 指向 下下个节点的指针地址。

next*Element==>ptruintptr

show me the code

https://gist.github.com/RBowind/4d35bea89c61707ee150260ae632e341

typeElementstruct{ptruintptr//指向下一个节点的指针地址Valueinterface{}}typeListstruct{root*Elementtailuintptrlenint}

更不正常:单指针实现双链表

首先理解上面 用单指针地址再实现一个单链表 的思路,然后再看下去。

利用异或的特性:$a \bigoplus (a \bigoplus b) = b$

每个节点的 ptr 不再存储下一个节点的的指针地址,而是上一个节点指针地址和下一个节点指针地址的 异或 结果。

如下图:P0 的 ptr 放的是上一个节点 0 与 下一个节点 P1 的指针地址的 异或 ,P1、P2 逻辑也如此。 这样,便可以既顺序遍历,又可以逆序遍历。

0^(0^P1)=P1//其中0^P1就是P0上存储的ptrP0^(P0^P2)=P2//其中P0^P2就是P1上存储的ptr

show me the code

https://gist.github.com/RBowind/f7d7fdce90a2c87efd27ec7461eb804d

typeElementstruct{ptruintptrValueinterface{}}typeListstruct{root*Elementtailuintptrlenint}//...更多细节查看上面gistfunc(l*List)insert(e*Element,tailuintptr)*Element{ifl.len==0{l.root.Value=e.Valuel.root.ptr=0l.tail=uintptr(unsafe.Pointer(l.root))}else{tailElement:=(*Element)(unsafe.Pointer(tail))//拿到最新的尾部节点tailElement.ptr=tailElement.ptr^uintptr(unsafe.Pointer(e))//异或修改尾部节点的指针e.ptr=tail//插入节点的ptr暂存上一个节点的指针,而这个就是下一个插入的tailElement.ptrl.tail=uintptr(unsafe.Pointer(e))//把tail指向最新的节点}l.len++returne}

缺陷

这种结构自然也有缺陷,比如只能顺序/逆序,从头/尾开始遍历,单单给到 P1 节点,是难以拿到 P0 和 P2的,不过,这也算实现了双向链表,这只是一种思维,目前看来并不实用。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/4529.html