python实现链表基本操作

目录

一、链表类定义

二、查找链表的中间结点

三、检测链表是否有环

四、删除链表倒数第n个结点

五、两个有序链表合并

六、链表反转

七、判断链表是否是回文字符串


一、链表类定义

结点定义:

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))    

猜你喜欢

转载自blog.csdn.net/woniu201411/article/details/85254670