单链表

定义

定义节点:数据域、指针域

# 链表节点类
class ListNode(object):
    def __init__(self, val):
        self.val = val
        self.next = None

head指针指向的是第一个节点。

定义单链表,及操作:

# 链表节点类
class ListNode(object):
    def __init__(self, val):
        self.val = val
        self.next = None

# 链表类,生成链表以及定义相关方法
class LinkList(object):
    # 生成链表,这里使用list来生成
    def create(self, valList):
        """
        :type valList: list
        :rtype: ListNode
        """
        node = ListNode(0)
        head = ListNode(0)
        head.next = node
        for i in range(len(valList)):
            node.next = ListNode(0)
            node.next.val = valList[i]
            node = node.next
        return head.next

    # 遍历显示
    def printLink(self, head):
        """
        :type head: ListNode
        :rtype: None
        """
        ans = head.next
        while ans:
            print(ans.val, end=' ')
            ans = ans.next
        # 回车换行
        print()

    # 链表判空
    def isEmpty(self, head):
        """
        :type head: ListNode
        :rtype: Boolean
        """
        # 若头指针为空,即链表为空,返回True; 否则返回False
        return True if not head else False

    # 取链表长度: 不算头结点
    def size(self, head):
        """
        :type head: ListNode
        :rtype: int
        """
        ans = head.next
        size = 0
        while ans:
            size += 1
            ans = ans.next
        return size

    # 根据索引取节点值域
    def getItem(self, head, index):
        """
        :type head: ListNode
        :type index: int
        :rtype: int
        """
        p = head.next
        count = 0
        while count != index:
            p = p.next
            count += 1
        return p.val

    # 根据索引设值
    def setItem(self, head, index, val):
        """
        :type head: ListNode
        :type index: int
        :type val: int
        :rtype: None
        """
        p = head
        count = -1
        while count < index - 1:
            p = p.next
            count += 1
        p.val = val

    # 单链表快速排序
    def quickSort(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head
        ans = ListNode(0)
        ans.next = head
        return self.sort(ans, None)
    def sort(self, head, end):
        if head == end or head.next == end or head.next.next == end:
            return head
        tpmHead = ListNode(0)
        # 划分节点
        poi = head.next
        # 遍历指针
        cur = poi
        pre = tpmHead
        # 一趟划分
        while cur.next != end:
            # 当前节点值域小于划分节点的值域,则将当前节点放到左侧
            if cur.next.val < poi.val:
                pre.next = cur.next
                pre = pre.next
                cur.next = cur.next.next
            else:
                cur = cur.next
        # 合并临时链表和原链表,将原链表接到临时链表后面即可
        pre.next = head.next
        head.next = tpmHead.next
        self.sort(head, poi)
        self.sort(poi, end)
        return head.next

    # 单链表归并排序
    def mergeSort(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head
        # 用快慢指针找链表中间节点,循环结束时:slow.next指向中间节点。
        slow, fast = head, head
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        # 对右半部分归并排序
        right = self.mergeSort(slow.next)
        # 断开左右两部分链表
        slow.next = None
        # 对左半部分归并排序
        left = self.mergeSort(head)
        return self.mergeLink(left, right)
    # 合并两个链表:按升序
    def mergeLink(self, left, right):
        node = ListNode(-1)
        head = node
        while left and right:
            if left.val < right.val:
                node.next = left
                left = left.next
            else:
                node.next = right
                right = right.next
            node = node.next
        node.next = left if left else right
        return head.next

if __name__ == "__main__":
    # 数组/列表,存放链表节点的值域
    li = [4, 2, 5, 3, 7, 9, 1, 0]
    myLink = LinkList()
    # 生成单链表
    head = myLink.create(li)
    # 打印链表长度
    print("长度:", myLink.size(head))
    # 判空
    print("判空:", myLink.isEmpty(head))
    # 单链表快速排序(升序),不稳定排序算法
    ansQuick = myLink.quickSort(head)
    myLink.printLink(ansQuick)
    # 单链表归并排序(升序),稳定排序算法
    ansMerge = myLink.mergeSort(head)
    myLink.printLink(ansMerge)

运行截图:


特点

单链表便于插入、删除,时间复杂度为O(1);不便于查找,时间复杂度为O(n)。

Py和C实现链表的区别

python是动态语言,可以直接把对象赋值给新的变量。

在C/C++中,通常采用“指针+结构体”来实现链表;

而在Python中,则可以采用“引用+类”来实现链表。

如下图:

mylist = Node()
mylist.next = head

head指针指向的是第一个节点。



单链表头插法、尾插法

设node是待插入节点。

头插法:

node.next = head.next
head.next = node

尾插法:

while head.next:
	head = head.next
head.next = node

头插法反转链表:

#新链表的头指针
pre = None
while head:
	#暂存头指针指向节点的下一个节点
	temp = head.next
	#断开原链表,头插法接到新链表
	head.next = pre
	pre = head
	head = temp
return pre

在指定位置(第index个位置)插入节点:

i = 0
cur_node = self.head.next
while i != index:
	cur_node = cur_node.next
	i += 1
node.next = cur_node.next
cur_node.next = node


用“快慢指针”找单链表的中间节点

# 用快慢指针找链表中间节点,循环结束时:slow.next指向中间节点。
slow, fast = head, head
while fast.next and fast.next.next:
    slow = slow.next
    fast = fast.next.next

若快慢指针slow, fast初始为:slow, fast = head.next, head.next,则循环结束时,slow指向中间节点。

posted @ 2020-05-09 13:23  人间烟火地三鲜  阅读(258)  评论(0编辑  收藏  举报