python数据结构----链表

       在数组之后,链表结构(linkedstructure)可能是程序中最常用的数据结构。链表结构中最简单的是单链表结构(singly linked structure)和双链表结构(doubly linkedstructure)。为了形象的表示链表结构,我们采用格子和指针来表示链表结构。

1 单链表结构

       单链表结构示意图:


       单链表结构的用户,沿着一个外部的头链接(head link)来访问第一项。然后用户通过从第一项产生的、串联起来的、单个的链条来访问其他的项。因此,单链表结构和容易获取一个项的后继项,但并不是很容易获取一个项的前驱项。最后一项没有指向下一项的链接,叫做空链接(empty link)。

       链表结构的节点包含了一个数据项以及到结构中的下一个节点的一个链接。Python程序员使用对对象的引用建立起了节点和链表的结构。head=Node(item, head)这种链接结构是从后向前创建的,即新加入的值在最前端

       链表结构的插入和删除操作和数组的插入删除操作不同点在于:

(1)一旦找到插入点和删除点,就可以进行插入和删除,而不需要在内存中移动数据项;

(2)在每一次的插入和删除的过程中,链表结构会调整大小,并且不需要额外的内存代价,也不需要复制数据项。

       单链表结构相对于数组的主要优点并不是时间性能,而是内存性能。当必须调整数组大小的时候,其时间和内存都是线性的,当调整链表结构的大小的时候,其时间和内存都是常数。在链表中没有浪费内存的问题。但是链表结构确实有额外的内存代价,因为链表结构需要为直接分配内存单元格。

       如果试图访问一个None节点,那么python则会抛出一个AttributeError作为相应,为了保证不会发生意外,在尝试访问前,我们先询问其是否为None。

       单链表的操作:

       1.遍历:遍历的时候要使用一个临时的指针变量,这个指针变量先初始化为链表结构的head指针,然后控制一个循环。如果不使用临时指针变量进行遍历的话,就会把这个链表所有的值删除了,因为Head节点控制的是链表的头节点,当head节点移动时,说有起始点发生了改变。

        2.搜索:搜索终止的可能性分为两种:第一种是找到了目标点,第二种是遍历整个链表也没有找到目标点。

       3.替换:在链表结构中搜索一个给定的项或给定的位置。如果是替换给定的项,那么就要判断该项是否在链表中,如果在则替换且返回True,如果不在则不能替换返回False;如果是给定的位置,我们假设给定位置的数值在链表的范围内,即假设链表的长度为n,其给定位置的值为0 <= index < n,这种情况就直接遍历到指定位置,然后完成替换即可。

      4.插入:插入的情况根据插入位置index分为三种:插在开头,插在中间,插在结尾。而根据节点的情况可以分为两种:空节点、非空节点。综合这两个变量可知:当插入位置索引值index <= 0或者节点为空的时候,都要插在开头,进行head=Node(item, head)。接下来就遍历链表,直至到达索引值位置处或者链表末尾才结束遍历,然后进行插值操作:probe.next = Node(newItem, probe.next)。当我们访问到最后一个节点时,probe.next= None。

      5.删除:删除和插入的分析思路是一样,当index <=0 或者head.next is None 时删除的第一个元素。删除中间节点以及结尾节点都需找到对应的索引值的前边的那个节点,所以要index > 1 and probe.next.next != None,直到找到满足条件的节点,删除其后边节点,将所有节点链接起来:probe.next = probe.next.next

Code:

class Node( object ):
   
"""representsa singly linked node"""
   
def __init__ ( self , data , next= None ):
       
self .data = data
       
self .next = next

def main ():
    head =
None       # head link
    # set value to Node
   
for i in range ( 6 ):
        head = Node(i
, head)

   
# traversal
   
print ( "##############Traversal ##############" )
    probe = head
   
while probe != None :
       
print (probe.data)
        probe = probe.next

   
# search
   
print ( "############## Search##############" )
    targetValue =
4
   
probe = head
    count =
0
   
while probe != None and probe.data != targetValue:
        probe = probe.next
        count +=
1
   
if probe != None :
       
print ( "TargetValue has beenfound, it is located in " , count)
   
else :
       
print ( "TargetVaule is not inthe linked structure" )

   
# replace
   
print ( "##############Replace ##############" )
    targetItem =
9
   
newItem = 10
   
targetIndex = 3
   
probe = head
   
# given target item
   
while probe != None and probe.data != targetItem:
        probe = probe.next
   
if probe != None :
        probe.data = newItem
       
print ( "True" )
       
# return True
   
else :
       
print ( "False" )
       
# return False
    # given target index
   
probe = head
   
while targetIndex > 0 :
        probe = probe.next
        targetIndex -=
1
   
probe.data = newItem
   
# Insert
   
print ( "############## Insert##############" )
    targetIndex =
2
   
newItem = 20
   
if targetIndex <= 0 or head is None :
        head = Node(newItem
, head)
   
else :
        probe = head
       
while targetIndex > 1 and probe.next != None :
            probe = probe.next
            targetIndex -=
1
       
probe.next = Node(newItem , probe.next)
       
# traversal
   
print ( "############## Insertresult ##############" )
    probe = head
   
while probe != None :
       
print (probe.data)
        probe = probe.next

   
print ( "############## Delete##############" )
    targetIndex =
1
   
if targetIndex <= 0 or head.next is None :
        removedItem = head.data
       
head = head.next
       
print (removedItem)
       
# return removedItem
   
else :
        probe = head
       
while targetIndex > 1 and probe.next.next != None :
            probe = probe.next
            targetIndex -=
1
       
removedItem =probe.next.data
        probe.next = probe.next.next
       
print (removedItem)
       
# return removedItem

if __name__ == "__main__" :
    main()

2 双链表结构

双链表结构示意图:


       双链表包含了两个方向的链接,用户很容易移动到一个项的后继项和它的前驱项,第二个外部链接叫尾链接(tail link),它允许双链表结构的用户直接访问最后一项。但双链表结构中的额外指针需要额外的、线性的内存使用量。

Code:

# create a doubly linked structure with one node
head = TwoWayNode(1)
tail = head

# Add four nodes to the end of the doubly linked structure
for data in range(2, 6):
    tail.next = TwoWayNode(data, tail)
    tail = tail.next

# print the contents of the linked structure in reverse order
probe = tail
while probe != None:
    print(probe.data)
    probe = probe.previous

3 带有一个哑头节点的循环链表结构

       循环链表结构包含了从结构中的最后一个节点返回到第一个节点的一个链接。哑头节点(dummy header node)不包含数据,但是充当了链表结构的开头和结尾的一个标记。下边分别展示带有哑头节点的一个空循环链表结构和在插入了第1个节点之后的循环链表结构。


这种结构的优点在于插入和删除操作只需要考虑一种情况,即第i个节点位于当前的第i个节点和它的前一个节点之间的这种情况。

Code :

# 带一个哑头节点的循环链表

head = Node(None, None)

head.next = head

# 插入数值

probe = head

while index > 0 and probe.next != head:

         probe= probe.next

         index-= 1

probe.next = Node(item, probe.next)

# 如果想循环放入数值

head = Node(None, None)
head.next = head

for i in range(10):
    head.next = Node(i, head.next)
    head = head.next
head= head.next

probe = head.next
while probe != head:
    print(probe.data)
    probe = probe.next


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值