一、单向链表
(1) 链表的定义
链表是一种常见的数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是再每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。
"""
链表的实现: list = [100, 200, 300]
| 内存 | 数据区| 下一个节点地址|
地址1:0x11 100 0x34
地址2:0x34 200 0x20
地址3:0x20 300 None
那么列表实现就如图所示:
"""
(2)为什么需要链表
- 顺序表的构建需要预先知道数据大小来申请一块连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来不是很灵活,引入链表结构可以充分利用计算机内存空间,实现灵活的动态管理。
- 另外,如果现在需要存储一个较大的数据,连续的内存不够用,也可以采用链表进行分散的存储,然后将数据链接在一起。
(3)单向链表
- 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域,最后一个节点的链表域则指向一个空值。
- 单向链表结点:
- 单向链表:
- 变量P指向链表的头结点的位置,从P出发能找到表中的任意结点
(4)单向循环列表
单向循环链表是将单向链表尾结点的next 指向头结点
(5)双向链表
- 概述
双向链表或者双面链表,每个结点有两个链表,一个指向前一个结点,当此结点为第一个结点时,指向空,而另一个指向下一个结点,当此结点为最后一个结点时指向空值。
2. 双向链表结构 其中:P为前趋结点 N 为后继结点
二、单向链表实现
class Node(object):
"""节点"""
def __init__(self, elem):
super(Node, self).__init__()
# 元素
self.elem = elem
# 下一个节点地址
self.next = None
class SingleLinkList(object):
"""单链表:实现增、删、改、查"""
def __init__(self, node=None):
self.__head = node
def is_empty(self):
"""链表为是否为空 """
return self.__head is None
def length(self):
"""链表长度"""
cur = self.__head # 定义游标cur,用来遍历节点
count = 0 # 统计节点个数
while cur is not None:
count += 1
cur = cur.next
return count
def travel(self):
""" 遍历整个链表"""
cur = self.__head
while cur is not None:
print("当前的节点是:%s" % cur.elem)
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, pos, item):
"""
指定位置添加元素 pos: 位置 item:元素
pos: 从0开始
"""
if pos <= 0:
self.add(item)
elif pos > (self.length() - 1):
self.append(item)
else:
pre = self.__head # 前一个位置
count = 0
while count < (pos - 1):
count += 1
pre = pre.next
# 当循环退出后pre = pos -1 的位置
node = Node(item)
node.next = pre.next
pre.next = node
def remove(self, item):
"""
删除节点 : 考虑列表为空,删除列表的头节点, 只有一个节点,尾部的节点
"""
cur = self.__head
pre = None
while cur is not None:
if cur.elem == item:
# 判断次节点是否为头节点
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
def search(self, item):
"""查找节点是否存在"""
cur = self.__head
while cur is not None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
ll = SingleLinkList()
print(ll.is_empty())
ll.append(1)
ll.append(100)
ll.append(200)
ll.travel()
ll.remove(1)
ll.travel()
二、单向循环列表实现
class Node(object):
def __init__(self, item):
"""结点"""
self.elem = item
self.next = None
class SingleLinkCircle(object):
"""单向循环链表"""
def __init__(self, node=None):
self.__head = node
if node:
node.next = node
def is_empty(self):
"""判断是否为空"""
return self.__head is None
def length(self):
"""判断链表长度"""
if self.is_empty():
return 0
else:
cur = self.__head
count = 1
while cur.next != self.__head:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历链表"""
if self.is_empty():
print("")
else:
cur = self.__head
while cur.next != self.__head:
print(cur.elem, end=" ")
cur = cur.next
# 循环结束打印最后一个结点
print(cur.elem)
def add(self, item):
"""在头部添加结点"""
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
self.__head = node
cur.next = 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
node.next = self.__head
cur.next = node
def insert(self, pos, item):
"""在特定位置插入结点"""
if pos <= 0:
self.add(item)
elif pos > (self.length() - 1):
self.append(item)
else:
pre = self.__head
count = 0
while count < (pos - 1):
count += 1
pre = pre.next
node = Node(item)
node.next = pre.next
pre.next = node
def remove(self, item):
"""删除指定结点"""
cur = self.__head
pre = None
if self.is_empty():
return
while cur.next != self.__head:
if cur.elem == item:
# 头结点
if cur == self.__head:
# 找到尾结点
finall = self.__head
while finall.next != self.__head:
finall = finall.next
# 将尾结点的地址指向要删除结点的下一个结点
finall.next = cur.next
self.__head = cur.next
else:
# 中间结点
pre.next = cur.next
return # 这里注意,删除完成后让程序直接退出,不用break
else:
pre = cur
cur = cur.next
# 判断删除的是尾结点
if cur.elem == item:
if cur == self.__head:
self.__head = None
else:
pre.next = self.__head
def search(self, item):
"""查找结点"""
if self.is_empty():
return False
else:
cur = self.__head
while cur.next != self.__head:
if cur.elem == item:
return True
cur = cur.next
if cur.elem == item:
return True
return False
if __name__ == '__main__':
ll = SingleLinkCircle()
ll.add(3)
ll.add(4)
print("test add()\n")
ll.travel()
ll.append(5)
ll.append(6)
print("test append()\n")
ll.travel()
ll.insert(2, 9)
ll.insert(3, 0)
print("test insert()\n")
ll.travel()
ll.remove(4)
ll.remove(6)
print("test remove()\n")
ll.travel()
print("test search()\n")
ll.search(5)
print(ll.length())
三、双向链表实现
class Node(object):
"""node"""
def __init__(self, item):
self.elem = item
self.prev = None
self.next = None
class DoubleLinkList(object):
def __init__(self, node=None):
self.__head = node
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 travel(self):
cur = self.__head
while cur is not None:
print(cur.elem, end=" ")
cur = cur.next
print("")
def add(self, item):
node = Node(item)
"""method one"""
# node.next = self.__head
# self.__head = node
# node.next.prev = node
"""method two"""
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
cur.next = node
node.prev = cur
def insert(self, pos, item):
node = Node(item)
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
cur = self.__head
count = 0
while count < pos:
count += 1
cur = cur.next
# node.prev = cur
# node.next = cur.next
# cur = node
# cur.next = node
""" method"""
node.next = cur
node.prev = cur.prev
cur.prev = node
node.prev.next = node
def remove(self, item):
cur = self.__head
while cur is not None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
if cur.next:
# only one node
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next:
# finally node
cur.next.prev = cur.prev
break
else:
cur = cur.next
def search(self, item):
cur = self.__head
while cur is not None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
lk = DoubleLinkList()
lk.append(2)
lk.append(3)
lk.insert(1, 0)
lk.append(4)
lk.append(5)
lk.add(6)
lk.travel()
lk.remove(6)
lk.travel()
print(lk.length())