数据结构基础+python实现(二):链表
1. 单链表
由于python语言不具有链表数据结构,所以我们需要定义链表节点和链表类。
1.1 单链表结点的实现:
class Node(object):
"""节点"""
def __init__(self,elem):
self.elem = elem
self.next = None
1.2 单链表的实现:
class SingleLinkList(object):
"""单链表"""
def __init__(self, node = None):
self.__head = node #头结点设置成私有属性,因为外部使用人员不需要知道头结点的属性
def is_empty(self):
"""链表判空"""
pass
def length(self):
"""求链表长度”“”
pass
def travel(self):
"""遍历整个链表"""
pass
def add(self, item):
"""链表头部添加元素"""
pass
def append(self, item):
"""链表尾插"""
pass
def insert(self, pos, item):
"""指定位置添加元素"""
pass
def remove(self, item):
"""删除结点"""
pass
def search(self, item):
"""查找结点是否存在"""
pass
定义了一个单链表,实现了基本方法。下面完成方法的具体实现:
def is_empty(self):
"""链表判空"""
return self.__head == None
def length(self):
"""求链表长度“”“
#cur游标,用来移动遍历结点
cur = self.__head
#count记录数量
count = 0
while cur != None:
count +=1
cur = cur.next
return count
def travel(self):
"""遍历整个链表"""
cur = self.__head
while cur != None:
print(cur.elem)
cur = cur.next
def append(self, item):
"""链表尾插"""
node = Node(item) #定义要插入的结点对象
if self.is_empty():
self.__head = node #判断特殊情况,链表为空
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
def add(self, item):
"""链表头插"""
node = Node(item)
node.next = self.__head
self.__head = node
def insert(self, pos, item):
"""在指定位置插入元素
:param pos 从0开始
"""
if pos <= 0 :
self.add(item) #如果插入位置小于0,按头插法
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 search(self, item):
"""查找结点是否存在"""
cur = self.__head
while cur !=None:
if cur.elem = item:
return ture
else:
cur = cur.next
return False
def remove(self, item):
"""删除结点"""
cur = self.__head
pre = None #cur已经指向第一个结点了,pre指向空,和cur之间保持一个距离
while cur != None:
if cur.elem == item:
# 先判断此结点是否是头结点,如果是头结点的话,pre.next错误(因为开始pre指向空),所以需要self.__head指向cur.next
# 头结点
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
# 移动过程有先后顺序,保持同步
pre = cur
cur = cur.next
# 这时候需要定义两个游标!
2. 双向链表
2.1 双向链表结点的实现:
class Node(object):
"""结点"""
def __init__(self, item):
self.elem = item
self.next = None #后继指向
self.prev = None #前驱指向
2.2 双向链表的实现:
双向链表的判空、求长度、遍历、查找的实现方法和单链表一样,这里就省略。列出不一样的。
def add(self, item):
"""头插法"""
node = Node(item)
node.next = self.__head
self.__head = node
node.next.prev = node
def append(self, item):
"""尾插法"""
node = Node(item)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, pos, item):
"""指定位置添加元素
:param pos从0开始
"""
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
# 当退出循环后,cur指向pos位置
node = Node(item)
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
def remove(self, item):
"""删除结点"""
cur = self.__head
while cur != None:
if cur.elem == item:
# 先判断此结点是否是头结点,
# 头结点
if cur == self.__head:
self.__head = cur.next
if cur.next:# 链表不止一个结点
# 判断链表是否只有一个结点,如果删的是头结点,并且只有一个结点,cur.next指向None,cue.next没有prev,错的,所以要加前面的判断是否不止一个
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next: # 如果cur.next是存在的,才能.prev,这是对末结点的特殊情况进行判断
cur.next.prev = cur.prev
break
else:
cur = cur.next
3. 单向循环链表
3.1 单向循环链表结点的实现:
和单链表的实现一样,省略。
3.2 单向循环链表的实现:
class SingleLinkList(object):
"""单向循环链表"""
def __init__(self, node = None):
self.__head = node
# 和单链表的构造函数有点区别,多一个回环的操作
if node:
node.next = node
...
def length(self):
"""求长度"""
if self.is_empty():
return 0
# cur游标,用来移动遍历结点
cur = self.__head
# count记录数量
count = 1 # 从1计数,和单链表不一样
while cur.next != self.__head: # 注意判断末尾和单链表不一样,回环
count += 1
cur = cur.next
return count
def travel(sekf):
"""遍历"""
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.elem, end = " ")
cur = cur.next
# 退出循环,cur指向尾节点,但尾节点的元素未打印
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
# 退出循环,cur指向尾结点,需要对尾节点进行操作
node.next = self.__head
self.__head = node
cur.next = self.__head
def appedn(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
cur.next = node
def insert(self, pos, item):
"""指定位置添加
:param 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 search(self, item):
"""查找结点是否存在"""
if self.is_empty():
return False
cur = self.__head
while cur.next != self.__head:
if cur.elem == item:
return True
else:
cur = cur.next
# 退出循环,cur指向尾节点,需要对尾节点进行判断
if cur.elem == item:
return True
return False
下面算是最难理解的单循环链表的删除操作!!!很多特殊情况的判断!
def remove(self, item):
if self.is_empty():
return
cur = self.__head
pre = None
while cur.next != self.__head:
if cur.elem == item:
# 先判断此结点是否是头结点
if cur == self.__head:
# 头结点时候
# 找尾节点
rear = self.__head
while rear.next != self.__head:
rear = rear.next
self.__head = cur.next
rear.next = self.__head
else:
# 中间结点
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
# 退出循环,cur指向尾节点
if cur.elem == item:
if cur == self.__head:
# 链表只有一个结点
self.__head = None
else:
pre.next = cur.next