一、链表简介
链表是一种在存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现。链表是由一系列的结点组成,结点可以在运行时动态生成。每个结点包含两部分:数据域与指针域。数据域存储数据元素,指针域存储下一结点的指针。
二、单向链表
单向链表也叫单链表,是链表中最简单的形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。 head 保存首地址,item 存储数据,next 指向下一结点地址。 链表失去了序列的随机读取优点,同时链表增加了指针域,空间开销也较大,但它对存储空间的使用要相对灵活。 举个栗子:有一堆数据[1,2,3,5,6,7],要在3和5之间插入4, 如果用数组,需要将5之后的数据都往后退一位,然后再插入4,这样非常麻烦,但是如果用链表,直接在3和5之间插入4就行。
1. 定义结点
结点的数据结构为数据元素(item)与 指针(next)
class Node(object):
"""单链表的结点"""
def __init__(self
, item
):
self
.item
= item
self
.next = None
2. 定义链表
链表需要具有首地址指针head。
class SingleLinkList(object):
"""单链表"""
def __init__(self
):
self
._head
= None
创建链表:
if __name__
== '__main__':
link_list
= SingleLinkList
()
node1
= Node
(1)
node2
= Node
(2)
link_list
._head
= node1
node1
.next = node2
print(link_list
._head
.item
)
print(link_list
._head
.next.item
)
是不是感觉很麻烦,所以我们要在链表中增加操作方法。
is_empty() 链表是否为空length() 链表长度items() 获取链表数据迭代器add(item) 链表头部添加元素append(item) 链表尾部添加元素insert(pos, item) 指定位置添加元素remove(item) 删除节点find(item) 查找节点是否存在 代码如下:
class SingleLinkList(object):
"""单链表"""
def __init__(self
):
self
._head
= None
def is_empty(self
):
"""判断链表是否为空"""
return self
._head
is None
def length(self
):
"""链表长度"""
cur
= self
._head
count
= 0
while cur
is not None:
count
+= 1
cur
= cur
.next
return count
def items(self
):
"""遍历链表"""
cur
= self
._head
while cur
is not None:
yield cur
.item
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 is not None:
cur
= cur
.next
cur
.next = node
def insert(self
, index
, item
):
"""指定位置插入元素"""
if index
<= 0:
self
.add
(item
)
elif index
> (self
.length
() - 1):
self
.append
(item
)
else:
node
= Node
(item
)
cur
= self
._head
for i
in range(index
- 1):
cur
= cur
.next
node
.next = cur
.next
cur
.next = node
def remove(self
, item
):
"""删除节点"""
cur
= self
._head
pre
= None
while cur
is not None:
if cur
.item
== item
:
if not pre
:
self
._head
= cur
.next
else:
pre
.next = cur
.next
return True
else:
pre
= cur
cur
= cur
.next
def find(self
, item
):
"""查找元素是否存在"""
return item
in self
.items
()
操作链表:
if __name__
== '__main__':
link_list
= SingleLinkList
()
for i
in range(5):
link_list
.append
(i
)
link_list
.add
(6)
for i
in link_list
.items
():
print(i
, end
='\t')
link_list
.insert
(3, 9)
print('\n', list(link_list
.items
()))
link_list
.remove
(0)
print(link_list
.find
(4))
三、循环链表
单向循环链表为单向链表的变种,链表的最后一个next指向链表头,新增一个循环。
1. 循环链表结点
class Node(object):
"""链表的结点"""
def __init__(self
, item
):
self
.item
= item
self
.next = None
2. 定义循环链表
class SingleCycleLinkList(object):
def __init__(self
):
self
._head
= None
def is_empty(self
):
"""判断链表是否为空"""
return self
._head
is 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 items(self
):
""" 遍历链表 """
if self
.is_empty
():
return
cur
= self
._head
while cur
.next != self
._head
:
yield cur
.item
cur
= cur
.next
yield cur
.item
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
, index
, item
):
""" 指定位置添加结点"""
if index
<= 0:
self
.add
(item
)
elif index
> self
.length
() - 1:
self
.append
(item
)
else:
node
= Node
(item
)
cur
= self
._head
for i
in range(index
- 1):
cur
= cur
.next
node
.next = cur
.next
cur
.next = node
def remove(self
, item
):
""" 删除一个结点 """
if self
.is_empty
():
return
cur
= self
._head
pre
= Node
if cur
.item
== item
:
if cur
.next != self
._head
:
while cur
.next != self
._head
:
cur
= cur
.next
cur
.next = self
._head
.next
self
._head
= self
._head
.next
else:
self
._head
= None
else:
pre
= self
._head
while cur
.next != self
._head
:
if cur
.item
== item
:
pre
.next = cur
.next
return True
else:
pre
= cur
cur
= cur
.next
if cur
.item
== item
:
pre
.next = self
._head
return True
def find(self
, item
):
""" 查找元素是否存在"""
return item
in self
.items
()
if __name__
== '__main__':
link_list
= SingleCycleLinkList
()
print(link_list
.is_empty
())
for i
in range(5):
link_list
.add
(i
)
print(list(link_list
.items
()))
for i
in range(6):
link_list
.append
(i
)
print(list(link_list
.items
()))
link_list
.insert
(3, 45)
print(list(link_list
.items
()))
link_list
.remove
(5)
print(list(link_list
.items
()))
print(4 in link_list
.items
())
四、双向链表
双向链表比单向链表更加复杂,它每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个链接指向下一个节点,当此节点为最后一个节点时,指向空值。 head 保存首地址,item 存储数据,next 指向下一结点地址,prev 指向上一结点地址。
1. 定义双向链表结点
class Node(object):
"""双向链表的结点"""
def __init__(self
, item
):
self
.item
= item
self
.next = None
self
.prev
= None
2. 定义双向链表
class BilateralLinkList(object):
"""双向链表"""
def __init__(self
):
self
._head
= None
def is_empty(self
):
"""判断链表是否为空"""
return self
._head
is None
def length(self
):
"""链表长度"""
cur
= self
._head
count
= 0
while cur
is not None:
count
+= 1
cur
= cur
.next
return count
def items(self
):
"""遍历链表"""
cur
= self
._head
while cur
is not None:
yield 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
.prev
= node
self
._head
= node
def append(self
, item
):
"""尾部添加元素"""
node
= Node
(item
)
if self
.is_empty
():
self
._head
= node
else:
cur
= self
._head
while cur
.next is not None:
cur
= cur
.next
node
.prev
= cur
cur
.next = node
def insert(self
, index
, item
):
""" 指定位置插入元素"""
if index
<= 0:
self
.add
(item
)
elif index
> self
.length
() - 1:
self
.append
(item
)
else:
node
= Node
(item
)
cur
= self
._head
for i
in range(index
):
cur
= cur
.next
node
.next = cur
node
.prev
= cur
.prev
cur
.prev
.next = node
cur
.prev
= node
def remove(self
, item
):
""" 删除结点 """
if self
.is_empty
():
return
cur
= self
._head
if cur
.item
== item
:
if cur
.next is None:
self
._head
= None
return True
else:
self
._head
= cur
.next
cur
.next.prev
= None
return True
while cur
.next is not None:
if cur
.item
== item
:
cur
.prev
.next = cur
.next
cur
.next.prev
= cur
.prev
return True
cur
= cur
.next
if cur
.item
== item
:
cur
.prev
.next = None
return True
def find(self
, item
):
"""查找元素是否存在"""
return item
in self
.items
()