目录
一、链表类定义
结点定义:
class Node:
def __init__(self,data,next_node=None):
self.data = data
self.next = next_node
链表类定义,包含结点查找、插入、删除、输出。链表包含头结点,头结点元素为列表中元素个数。
class singLinkedList:
#带头结点的链表,结点中的元素为链表中元素个数
def __init__(self,nodeNum = 0):
self.head = Node(nodeNum)
#根据值查找节点
def find_by_value(self,value):
p = self.head.next
while (p and p.data != value):
p = p.next
return p
#查找第k个节点
def find_by_index(self,k):
if(self.head.data < k):
return
p = self.head.next
position = 1
while(position<k):
p = p.next
position = position + 1
return p
#将节点插入到头结点
def insert_value_to_head(self,value):
newNode = Node(value)
newNode.next = self.head.next
self.head.next = newNode
self.head.data = self.head.data + 1
#将节点插入到表尾
def insert_value_to_tail(self,value):
newNode = Node(value)
p = self.head
while(p.next):
p = p.next
p.next = newNode
self.head.data = self.head.data + 1
#将新结点插入某一结点后
def insert_value_after(self,node,newNode):
if not node or not newNode:
return
newNode.next = node.next
node.next = newNode
self.head.data = self.head.data + 1
#删除指定节点
def delete_by_node(self,node):
if(not self.head.next or not node):
return
if(node.next):
node.data = node.next.data
node.next = node.next.next
else:
p = self.head
while(p and p.next != node):
p = p.next
if (not p):
return
p.next = None
self.head.data = self.head.data - 1
#删除值为value的节点
def delete_by_value(self,value):
pre = self.head
p = pre.next
while(p and p.data!= value):
pre = p
p = p.next
if not p:
return
pre.next = p.next
self.head.data = self.head.data - 1
#输出单链表元素
def print_list(self):
llist = []
p = self.head.next
while(p):
llist.append(p.data)
p = p.next
print("链表中元素个数:", self.head.data)
print(llist)
二、查找链表的中间结点
设置快慢两个指针,快指针一次移动两个结点、慢指针一次移动一个结点,快指针指向链表尾时,慢指针指向中间结点。
def find_mid_node(head):
if (head.data == 0):
print("The list has no node.")
return
p = head
q = head
while(q!=None and q.next!=None):
p = p.next
q = q.next.next
return p
linklist = singLinkedList()
linklist.insert_value_to_tail(1)
linklist.insert_value_to_tail(2)
linklist.insert_value_to_tail(3)
linklist.insert_value_to_tail(4)
linklist.print_list()
midnode = find_mid_node(linklist.head)
print(midnode.data)
在访问一个给定结点变量的字段前,可以通过询问其是否为None,从而保证不会发生异常!!
三、检测链表是否有环
也是设置快慢两个指针,通过判断快慢指针是否相等,检测链表是否有环。
def has_cycle(head):
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
linklist = singLinkedList()
linklist.insert_value_to_tail(1)
linklist.insert_value_to_tail(2)
linklist.insert_value_to_tail(3)
if has_cycle(linklist.head):
print("list has cycle")
else:
print("list has not cycle")
tailnode = linklist.find_by_value(3)
tailnode.next = linklist.head
if has_cycle(linklist.head):
print("list has cycle")
else:
print("list has not cycle")
四、删除链表倒数第n个结点
设置两个指针,指针p先移动n个结点,指针q从头结点开始移动,当指针p指向链表尾部时,指针q指向倒数第n个结点的前驱结点。
def delete_last_N_node(head,n):
if (head.data < n) or ( n < 1):
return
p = head
q = head
for i in range(n):
q = q.next
while(q.next):
p = p.next
q = q.next
p.next = p.next.next
head.data = head.data - 1
linklist = singLinkedList()
linklist.insert_value_to_tail(1)
linklist.insert_value_to_tail(2)
linklist.insert_value_to_tail(3)
linklist.print_list()
delete_last_N_node(linklist.head,1)
linklist.print_list()
五、两个有序链表合并
def merge_sort_list(head1,head2):
mergeList = singLinkedList()
current = mergeList.head
p1 = head1.next
p2 = head2.next
while(p1 and p2):
if p1.data < p2.data:
q1 = p1.next
mergeList.insert_value_after(current,p1)
current = p1
p1 = q1
else:
q2= p2.next
mergeList.insert_value_after(current,p2)
current = p2
p2 = q2
while(p1):
q1 = p1.next
mergeList.insert_value_after(current,p1)
current = p1
p1 = q1
while(p2):
q2 = p2.next
mergeList.insert_value_after(current,p2)
current = p2
p2 = q2
return mergeList
linklist1 = singLinkedList()
linklist1.insert_value_to_tail(1)
linklist1.insert_value_to_tail(3)
linklist1.print_list()
linklist2 = singLinkedList()
linklist2.insert_value_to_tail(2)
linklist2.insert_value_to_tail(4)
linklist2.print_list()
mergeLinkList = merge_sort_list(linklist1.head,linklist2.head)
mergeLinkList.print_list()
六、链表反转
def reverseLinkedList(head):
p = head.next
head.next = None
while(p):
q = p.next
p.next = head.next
head.next = p
p = q
linklist = singLinkedList()
linklist.insert_value_to_tail(3)
linklist.insert_value_to_tail(2)
linklist.insert_value_to_tail(1)
linklist.print_list()
reverseLinkedList(linklist.head)
linklist.print_list()
七、判断链表是否是回文字符串
查找链表的中间结点,将中间结点后的结点反转,遍历中间结点前后是否相同。
def is_palindrome(head):
if(head.data < 1):
return False
#查找链表的中间节点
mid = head
q = head
while(q!=None and q.next!=None):
mid = mid.next
q =q.next.next
#中间节点mid之后的节点翻转
p = mid.next
mid.next = None
while(p!=None):
q = p.next
p.next = mid.next
mid.next = p
p = q
#mid前后节点是否相同
p = head.next
q = mid.next
while (q!=None) and (p.data == q.data):
p = p.next
q = q.next
if(q!=None):
return False
else:
return True
linklist = singLinkedList()
linklist.insert_value_to_tail('a')
linklist.insert_value_to_tail('b')
linklist.insert_value_to_tail('c')
linklist.insert_value_to_tail('b')
linklist.insert_value_to_tail('a')
linklist.print_list()
print(is_palindrome(linklist.head))