根据数据存储结构,可以将数据结构划分为:
之前介绍过的顺序表即采用顺序存储结构,这里介绍链式存储结构。主要包括单链表和双链表。
以下为通过 p y t h o n 3 python3 python3 实现的单链表代码
# -*- coding: utf-8 -*-
# 定义单链表结点
class Node(object):
def __init__(self, value=None, next=None): # root 节点默认都是 None
self.value = value
self.next = next
# 定义循环单链表结点
class Node(object):
def __init__(self, value=None, next=None): # root 节点默认都是 None
self.value = value
self.next = next
定义单链表类
# 定义单链表
class LinkedList(object):
""" 单链表 ADT
[root] -> [node0] -> [node1] -> [node2]
"""
def __init__(self, maxsize=None):
"""
:param maxsize: int or None, 如果是 None,无限扩充
"""
self.maxsize = maxsize
self.root = Node() # 默认根结点指向 None
self.tailnode = None # 尾结点
self.length = 0 # 链表长度
def __len__(self):
return self.length # 返回链表长度
def append(self, value): # 尾插法,时间复杂度O(1)
if self.maxsize != None and len(self) >= self.maxsize:
raise Exception('LinkedList is full!')
node = Node(value) # 构造新结点
tailnode = self.tailnode
if tailnode is None: # 空链表追加到根结点后
self.root.next = node
else: # 追加到尾结点的后边,并更新尾结点和链表长度
tailnode.next = node
# 若为循环链表,此处加上:node.next = self.root.next
self.tailnode = node
self.length += 1
def appendleft(self, value): # 头插法
if self.maxsize != None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value)
if self.tailnode == None: # 原链表为空,则修改尾结点
self.tailnode = node
# 若为循环链表,此处加上:self.tailnode.next = node
node.next = self.root.next
self.root.next = node
self.length += 1
def __iter__(self):
for node in self.iter_node():
yield node.value
def iter_node(self):
"""遍历从头结点到尾结点"""
curnode = self.root.next
while curnode != self.tailnode: # 从第一个节点开始遍历
yield curnode
curnode = curnode.next # 移动到下一个节点
if curnode is not None:
yield curnode
def remove(self, value): # 删除结点 O(n)
""" 删除包含值的第一个节点
:param value:
"""
prevnode = self.root
for curnode in self.iter_node():
if curnode.value == value:
prevnode.next = curnode.next
if curnode is self.tailnode: # 注意更新尾结点
self.tailnode = prevnode
"""若为循环链表,此处加上:
if curnode is self.root.next:
self.tailnode.next = self.root.next
"""
del curnode
self.length -= 1
return 1 # 删除成功
else:
prevnode = curnode
return -1 # 删除失败
def find(self, value): # O(n)
""" 查找结点,返回序号,从 0 开始
:param value:
"""
index = 0
for node in self.iter_node():
if node.value == value:
return index
index += 1
return -1 # 没找到
def popleft(self): # O(1)
""" 删除第一个链表节点
"""
if self.root.next == None:
raise Exception('pop from empty LinkedList')
headnode = self.root.next
self.root.next = headnode.next
# 若为循环链表,此处加上:self.tailnode.next = self.root.next
self.length -= 1
value = headnode.value
if self.tailnode == headnode: # 单节点删除处理
self.tailnode = None
del headnode
return value
def clear(self):
"""清空链表"""
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
self.tailnode = None
def reverse(self):
"""反转链表"""
curnode = self.root.next
prevnode = None # 若为循环链表,此处改为:prevnode = self.tailnode
self.tailnode = curnode # 更新 tailnode
while curnode:
nextnode = curnode.next # 记录下一结点
curnode.next = prevnode # 指向前一结点
if nextnode is None: # 尾结点变头结点
self.root.next = curnode
prevnode = curnode
curnode = nextnode
"""若为循环链表,以上循环改为:
while curnode.next is not self.root.next:
nextnode = curnode.next # 记录下一结点
curnode.next = prevnode # 指向前一结点
prevnode = curnode
curnode = nextnode
curnode.next = prevnode # 指向前一结点
self.root.next = curnode # 尾结点变头结点
"""
首先定义双向链表结点
class Node(object):
def __init__(self, value=None, prev=None, next=None):
self.value, self.prev, self.next = value, prev, next
定义双向链表
class DoubleLinkedList(object):
"""双向循环链表 ADT
"""
def __init__(self, maxsize=None):
self.maxsize = maxsize
node = Node()
node.next, node.prev = node, node
self.root = node
self.length = 0
def __len__(self): # 返回链表长度
return self.length
def headnode(self): # 头结点
return self.root.next
def tailnode(self): # 尾结点
return self.root.prev
def append(self, value): # O(1), 尾插法
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value=value)
tailnode = self.tailnode() or self.root
tailnode.next = node
node.prev = tailnode
node.next = self.root
self.root.prev = node
self.length += 1
def appendleft(self, value): # 头插法
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value=value)
if self.root.next is self.root: # 空链表
node.next = self.root
node.prev = self.root
self.root.next = node
self.root.prev = node
else:
node.prev = self.root
node.next = self.root.next
self.root.next.prev = node
node.prev.next = node
self.length += 1
def remove(self, node): # O(1),传入node 而不是 value
"""remove
:param node
"""
if node is self.root:
return
else:
node.prev.next = node.next
node.next.prev = node.prev
self.length -= 1
return node
def iter_node(self):
if self.root.next is self.root:
return
curnode = self.root.next
while curnode.next is not self.root:
yield curnode
curnode = curnode.next
yield curnode
def __iter__(self):
for node in self.iter_node():
yield node.value
def iter_node_reverse(self):
"""相比单链表独有的反序遍历"""
if self.root.prev is self.root:
return
curnode = self.root.prev
while curnode.prev is not self.root:
yield curnode
curnode = curnode.prev
yield curnode
注意:链表在进行插入和删除操作时,需要注意顺序,以下为双向链表插入删除示意图: