线性表的基本需要:
- 找到首元素
- 从任一元素出发可以找到它的下一个元素
单链表
'''
思路:
空表和非空表不统一,缺点?如何将空表与非空表统一?
头结点:在单链表的第一个元素结点之前附设一个类型相同的结点,以便空表和非空表处理统一。
单链表带头结点,表头、表中、表尾三种情况的操作语句一致
'''
# 结点
class LNode:
def __init__(self, value, param=None):
self.data = value
self.next = param
# 单链表
class LList:
# 怎么初始化?
def __init__(self, A=None):
'''
A是什么?A是一组数据,传进来初始化生成链表的形式存储
如果无参构造,则需手动插入赋值,不能直接开始删改查,得先插入
如果有参构造,则初始化时链表就成形了,可以直接进行增删改查的操作
'''
# 先声明头结点:
self.first = LNode(None, None) # 头结点是空的,只是起一个带头的作用
# 在头结点的后面插入有数据的结点
self.len = 0
if A is not None:
temp = self.first
for i in A:
temp.next = LNode(i, None)
temp = temp.next
self.len = len(A)
def length(self):
temp = self.first.next
count = 0
while temp is not None: # 链长不为空
count += 1
temp = temp.next
return count
def get_index(self, index): # 通过位置取数据
# 判断index是否合法
if index < 1 or index > self.len:
raise Exception("位置不合法!")
# i在中间
temp = self.first.next
for i in range(index):
temp = temp.next
return temp.data
def locate_elem(self, elem):
# 传入的elem是数据,不是结点
# 返回的是位置
temp = self.first.next
count = 1
while temp is not None:
if temp.data == elem:
return count
else:
count += 1
temp = temp.next
# 不合法判断
raise Exception("单链表中不存在该元素!")
def insert(self, index, elem): # 在i位置插入elem
# 判断index是否合法
if index < 1 or (self.len != 0 and (index - 1) > self.len): # 要插入到第1个位置之前
raise Exception("index不合法")
temp = self.first # 考虑在节点后面插入
for i in range(index - 1): # i位置对应下标为i-1的结点,range到index-2,就是到待插入位置的前一个,temp=temp.next之后就是下标为i-1的结点
temp = temp.next
node = LNode(elem, temp.next) # 老师的代码!妙
temp.next = node
self.len += 1
def delete_index(self, index): # 删除index位置上的元素
# 判断index是否合法
if index < 1 or index > self.len:
raise Exception("index不合法")
temp = self.first # 考虑删除链表的第一个结点(不是头结点)
for i in range(index - 1):
temp = temp.next
node = temp.next # 待删结点
temp.next = node.next
self.len -= 1
return node.data
def print_list(self):
if self.len == 0:
raise Exception("空表")
temp = self.first.next
for i in range(self.len):
print(temp.data, end=" ")
temp = temp.next
print()
'''
插入:
1. 工作指针p初始化;
2. 查找第i-1个结点并使工作指针p指向该结点;
3. 若查找不成功,则插入位置不合理,抛出插入位置异常;
否则,
3.1 生成一个元素值为x的新结点s;
3.2 将新结点s插入到结点p之后;
删除:
1. 工作指针p初始化;累加器count初始化;
2. 查找第i-1个结点并使工作指针p指向该结点;
3. 若p不存在或p不存在后继结点,则抛出位置异常;
否则,
3.1 暂存被删结点和被删元素值;
3.2 摘链,将结点p的后继结点从链表上摘下;
3.3 释放被删结点;
3.4 返回被删元素值;
'''
if __name__ == '__main__':
L = LList() # 空链表
print(L.length())
L.insert(1, 1)
L.insert(2, 2)
L.insert(3, 3)
L.print_list()
L.delete_index(1)
L.print_list()
L.delete_index(2)
L.print_list()
在python中,p is not None 可以只写一个p
'''
自定义异常
标准异常类ValueError的子类
'''
class LinkedListUnderflow(ValueError):
pass