目录
一. 链表作用和定义
1.1作用
顺序表构建需要预习知道数据大小来申请连续的存储空间且涉及数据搬迁等操作,并不灵活,链表结构却可以充分利用计算机内存空间,实现灵活的内存动态管理。
1.2定义
链表是一种线性表,在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。
二. 单向链表
2.1定义:
单向链表也叫单链表,每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
尾节点的链接域指向空
2.2 单链表的操作
is_empty() 链表是否为空
length() 链表长度
travel() 遍历整个链表
add(item) 链表头部添加元素
append(item) 链表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 删除节点
search(item)查找节点是否存在
2.3单链表节点的实现
class Node ( object ) :
def __init__ ( self, item) :
self. item = item
self. next = None
2.4 单链表的头部添加元素与尾部添加元素
2.5 单链表在指定位置添加元素
2.6 删除节点
class Node ( object ) :
def __init__ ( self, element) :
self. element = element
self. next = None
class SingleLinkList ( object ) :
def __init__ ( self, node = None ) :
self. __head= None
def is_empty ( self) :
return self. __head == None
def length ( self) :
cur = self. __head
count = 0
while cur != None :
count += 1
cur = cur. next
return count
def travel ( self) :
cur = self. __head
while cur != None :
print ( cur. element, end = " " )
cur = cur. next
def add ( self, item) :
node = Node( item)
node. next = self. __head
self. __head = node
def append ( self, item) :
node = Node( item)
if self. is_empty( ) :
self. __head = node
else :
cur = self. __head
while cur. next != None :
cur = cur. next
cur. next = node
def insert ( self, pos, item) :
node = Node( item)
if pos <= 0 :
self. add( item)
elif pos > ( self. length( ) - 1 ) :
self. append( item)
pre = self. __head
count = 0
while count < pos - 1 :
count += 1
pre = pre. next
node. next = pre. next
pre. next = node
def remove ( self, item) :
pre = None
cur = self. head
if cur. element == item:
self. head = self. head. next
else :
while cur:
if cur. element != item:
pre = cur
cur = cur. next
else :
pre. next = cur. next
cur. prev = pre. next
break
if __name__ == '__main__' :
link = SingleLinkList( )
print ( '链表是否为空?' , link. is_empty( ) )
print ( '链表长度:' , link. length( ) )
print ( '添加头结点:' )
for item in range ( 1 , 7 ) :
link. append( item)
link. travel( )
print ( '链表是否为空?' , link. is_empty( ) )
print ( '链表长度:' , link. length( ) )
2.7 链表与顺序表的对比
虽然链表看起来复杂度更高,但链表和顺序表在插入和删除时进行的是完全不同的操作。链表主要耗时操作是遍历查找,顺序表主要耗时操作是拷贝覆盖。(数据搬迁)
操作 链表 顺序表 访问元素 O(n) O(1) 在头部插入/删除 O(1) O(1) 在尾部插入/删除 O(n) O(1) 在中间插入/删除 O(n) O(n)
三. 单向循环链表
3.1 定义
单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。
3.2 操作
is_empty() 链表是否为空
length() 链表长度
add(item) 链表头部添加元素
append(item) 链表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 删除节点
search(item) 查找节点是否存在
3.3 操作实现
class Node ( object ) :
def __init__ ( self, item) :
self. item = item
self. next = None
class SinCycLinkedlist ( object ) :
def __init__ ( self) :
self. __head = None
def is_empty ( self) :
return self. __head == None
def length ( self) :
if self. is_empty( ) :
return 0
count = 1
cur = self. __head
while cur. next != self. __head:
count += 1
cur = cur. next
return count
def travel ( self) :
if self. is_empty( ) :
return
cur = self. __head
print ( cur. item)
while cur. next != self. __head:
cur = cur. next
print ( cur. item)
print ( "" )
def add ( self, item) :
node = Node( item)
if self. is_empty( ) :
self. __head = node
node. next = self. __head
else :
node. next = self. __head
cur = self. __head
while cur. next != self. __head:
cur = cur. next
cur. next = node
self. __head = node
def append ( self, item) :
node = Node( item)
if self. is_empty( ) :
self. __head = node
node. next = self. __head
else :
cur = self. __head
while cur. next != self. __head:
cur = cur. next
cur. next = node
node. next = self. __head
def insert ( self, pos, item) :
if pos <= 0 :
self. add( item)
elif pos > ( self. length( ) - 1 ) :
self. append( item)
else :
node = Node( item)
cur = self. __head
count = 0
while count < ( pos- 1 ) :
count += 1
cur = cur. next
node. next = cur. next
cur. next = node
def remove ( self, item) :
if self. is_empty( ) :
return
cur = self. __head
pre = None
while cur. next != self. __head:
if cur. item == item:
if cur == self. __head:
rear = self. __head
while rear. next != self. __head:
rear = rear. next
self. __head = cur. next
rear. next = self. __head
else :
pre. next = cur. next
return
else :
pre = cur
cur = cur. next
if cur. item == item:
if cur == self. __head:
self. __head = None
else :
pre. next = self. __head
def search ( self, item) :
if self. is_empty( ) :
return False
cur = self. __head
if cur. item == item:
return True
while cur. next != self. __head:
cur = cur. next
if cur. item == item:
return True
return False
if __name__ == '__main__' :
ll = SinCycLinkedlist( )
ll. add( 1 )
ll. add( 2 )
ll. append( 3 )
print ( ll)
ll. append( 3 )
ll. insert( 2 , 4 )
ll. insert( 4 , 5 )
ll. insert( 0 , 6 )
print ( ll)
print ( "length:" , ll. length( ) )
ll. travel( )
print ( ll. search( 3 ) )
print ( ll. search( 7 ) )
ll. remove( 1 )
ll. remove( 10 )
print ( "length:" , ll. length( ) )
ll. travel( )
四. 双向链表
4.1定义
一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。所以,在这里一个节点包括了三部分,前驱、数据、后驱。
4.2 操作
is_empty() 链表是否为空
length() 链表长度
travel() 遍历链表
add(item) 链表头部添加
append(item) 链表尾部添加
insert(pos, item) 指定位置添加
remove(item) 删除节点
search(item) 查找节点是否存在
4.3 链表节点的实现
class Node ( object ) :
def __init__ ( self, item) :
self. item = item
self. next = None
self. prev = None
4.4 操作实现
对于判断链表是否为空、链表长度、遍历链表,和单向链表差别不大
class DLinkList ( object ) :
def __init__ ( self) :
self. __head = None
def is_empty ( self) :
return self. __head == None
def length ( self) :
cur = self. __head
count = 0
while cur != None :
count += 1
cur = cur. next
return count
def travel ( self) :
cur = self. __head
while cur != None :
print ( cur. item)
cur = cur. next
def add ( self, item) :
node = Node( item)
if self. is_empty( ) :
self. __head = node
else :
node. next = self. __head
self. __head = node
node. next . prev = node
尾部插入元素,只要在单向链表的基础上加上pev的字段操作即可
def append ( self, item) :
node = Node( item)
if self. is_empty( ) :
self. _head = node
else :
cur = self. _head
while cur. next != None :
cur = cur. next
cur. next = node
node. prev = cur
在指定位置添加节点:
def insert ( self, pos, item) :
if pos <= 0 :
self. add( item)
elif pos > ( self. length( ) - 1 ) :
self. append( item)
else :
node = Node( item)
cur = self. _head
count = 0
while count < ( pos- 1 ) :
count += 1
cur = cur. next
node. prev = cur
node. next = cur. next
cur. next . prev = node
cur. next = node
删除元素:
def remove ( self, item) :
if self. is_empty( ) :
return
else :
cur = self. _head
if cur. item == item:
if cur. next == None :
self. _head = None
else :
cur. next . prev = None
self. _head = cur. next
return
while cur != None :
if cur. item == item:
cur. prev. next = cur. next
cur. next . prev = cur. prev
break
cur = cur. next