一、顺序表
顺序表是将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。以下为顺序表的基本实现(使用列表)
# 创建顺序表
seq_list = [10, 20, 30, 40, 50] # Python列表本身就是顺序表的实现
# 访问元素 - O(1)
print("第三个元素:", seq_list[2]) # 输出: 30
# 插入元素 - 平均O(n)
seq_list.insert(2, 25) # 在索引2处插入25
print("插入后:", seq_list) # 输出: [10, 20, 25, 30, 40, 50]
# 删除元素 - 平均O(n)
seq_list.pop(3) # 删除索引3的元素
print("删除后:", seq_list) # 输出: [10, 20, 25, 40, 50]
# 查找元素 - O(n)
index = seq_list.index(40) # 查找40的索引
print("40的索引位置:", index) # 输出: 3
# 顺序表特点:
# 1. 随机访问速度快(O(1))
# 2. 插入删除操作慢(O(n))
# 3. 需要预先分配连续内存空间
二、链表
链表是通过指针将一组零散的内存块串联起来的数据结构,每个节点包含数据和指向下一个节点的指针。
1、单链表的基本实现
"""
链表的增删查改操作,如有错误,敬请谅解,也请及时告知,非常感谢!
"""
class Node():
"""链表节点类"""
def __init__(self, data):
self.data = data
self.next = None
class listNode():
"""单链表实现"""
def __init__(self):
self.head = None
def is_empty(self):
"""判断单链表是否为空"""
return self.head is None
def length(self):
"""计算链表长度"""
count = 0
current = self.head
while current:
count += 1
current = current.next
return count
def append(self,data):
"""为链表添加元素"""
if self.is_empty():
self.head = Node(data)
else:
current = self.head
while current.next:
current = current.next
current.next = Node(data)
def print_list(self):
current = self.head
while current:
print("{}->".format(current.data),end='')
current = current.next
print("NULL")
def insert(self,index,data):
"""在某索引出插入新节点,index从0开始"""
if index > self.length():
raise IndexError("index out of range")
new_node = Node(data)
current = self.head
if index == 0:
new_node.next = current
self.head = new_node #注意这里不可以是current,你把变量名 current 指向了另一个对象(new_node),
# 但 这并不会改变 self.head,因为 current 只是一个局部变量;
# Python 里简单的赋值(=)永远不会修改原对象,只会重绑定名字。
else:
for i in range(index-1):
current = current.next
new_node.next = current.next
current.next = new_node
def remove_index(self,index):
"""删除某索引节点,index从0开始"""
if self.is_empty():
print('链表为空!')
return
if index > self.length()-1:
raise IndexError("index out of range")
if index == 0:
self.head = self.head.next
else:
current = self.head
pre = None
for i in range(index):
pre = current
current = current.next
pre.next = current.next
def remove_data(self,data):
"""删除数据为data的节点"""
if self.is_empty():
print('链表为空!')
return
current = self.head
prev = None
while current:
if current.data == data:
if prev is None:
self.head = current.next
else:
prev.next = current.next
prev = current
current = current.next
def search_index(self,data):
"""输入某数值的索引"""
index = []
count = 0
current = self.head
while current:
if current.data == data:
index.append(count)
count = count + 1
current = current.next
return index
def search_data(self,index):
if self.is_empty():
print("链表为空!")
return
if index > self.length()-1:
raise IndexError("index out of range")
current = self.head
for i in range(index):
current = current.next
return current.data
x = listNode()
x.append(1)
x.append(2)
x.append(3)
x.append(4)
x.append(5)
x.append(6)
x.print_list() #输出:1->2->3->4->5->6->NULL
x.insert(1,7)
x.print_list() #输出:1->7->2->3->4->5->6->NULL
x.remove_data(7)
x.print_list() #输出:1->2->3->4->5->6->NULL
x.remove_index(1)
x.print_list() #输出:1->3->4->5->6->NULL
a = x.search_index(5)
print(a) #输出:[3]
b = x.search_data(4)
print(b) #输出:6
2、双向链表的实现
每个节点不仅保存「下一个节点的引用」,还额外保存「上一个节点的引用」。
因此,它可以在 O(1) 时间内:
-
从任意已知节点向前或向后移动
-
在已知节点前/后插入、删除(不需要从头遍历找前驱)
class DNode:
"""双向链表节点类"""
def __init__(self, data):
self.data = data
self.next = None # 指向前驱节点
self.prev = None # 指向后继节点
class DoublyLinkedNode:
def __init__(self):
self.head = None
self.tail = None
def append(self, data):
"""尾部添加节点"""
new_node = DNode(data)
if self.head is None:
self.head = self.tail = new_node
else:
new_node.prev = self.tail
self.tail.next = new_node
self.tail = new_node
def remove(self, data):
"""删除节点"""
current = self.head
while current: #意味着至少有一个节点
if current.data == data:
if current.prev is None: #要删除第一个节点(头结点)
self.head = current.next
if self.head: #链表有两个及以上的节点
self.head.prev = None
else: #链表只有一个节点,即删除第一个节点后为空链表
self.tail = None
elif current.next is None: #删除尾节点,此时经过第一次分支后,说明链表至少有两个节点。
self.tail = current.prev
self.tail.next = None
else: #删除中间节点
current.prev.next = current.next
current.next.prev = current.prev
current = current.next
def __str__(self):
"""打印链表"""
nodes_data = []
current = self.head
while current:
nodes_data.append(str(current.data))
current = current.next
return '<->'.join(nodes_data)
x = DoublyLinkedNode()
x.append(1)
x.append(2)
x.append(3)
x.append(4)
x.append(5)
x.append(6)
print(x) #输出内容1<->2<->3<->4<->5<->6
x.remove(5)
print(x) #输出内容1<->2<->3<->4<->6