Datawhale第九期組隊學習--數據結構與算法(上)Task02:順序表和鏈表(2天)

推薦:82,66(java)
72(python)https://github.com/CBLBY/datawhale_algorithm_learning/blob/master/Task02.ipynb

理論部分
  • 理解線性表的定義與操作。
  • 實現順序表。
  • 實現單鏈表、循環鏈表、雙向鏈表。
練習部分

一、 線性表相關定義
基礎:
數據結構: 是指數據元素的集合及元素間的相互關係和構造方法。
邏輯結構: 元素之間的相互關係(前後關係)是數據的邏輯結構。與存儲位置無關。
存儲結構: 數據元素及元素之間關係的存儲稱爲存儲結構(或物理結構)(指數據的邏輯結構在計算機存儲空間的存放形式。)

數據結構按照邏輯關係的不同分爲線性結構和非線性結構兩大類。
線性表(Linear List): 一個線性表是n(n≥0)個元素的有限序列,通常表示爲(a1,a2, …,an)。線性結構的特點是數據元素之間程序一種線性關係,即元素“一個接一個排列”。
補充: 線性表的存儲結構分爲順序存儲和鏈式存儲。

順序表: 利用順序存儲結構(即利用數組)實現的線性表。
鏈表(Linked list): 利用指針方式實現的線性表稱爲鏈表(單鏈表、循環鏈表、雙鏈表)。它不要求邏輯上相鄰的數據元素在物理位置上也相鄰,即:邏輯結構與物理結構可以相同也可以不相同。
單向鏈表(單鏈表): 每個結點只含有一個鏈域(指針域)的鏈表。即:利用單鏈域的方式存儲線性表的邏輯結構。
雙向鏈表(雙鏈表): 每個結點含有兩個鏈域(指針域)的鏈表,分別指出當前元素的直接前驅和直接後驅。即:利用雙鏈域的方式存儲線性表的邏輯結構。
循環鏈表: 是一種首尾相連的單鏈表。即:在單鏈表(或雙鏈表)中,將尾結點的指針域改爲指向pHead,就得到循環鏈表。

鏈表本身是一種無序的數據結構,元素的插入和刪除不能保證順序性。
有序鏈表:
分不分有序單鏈表,有序雙鏈表?
有序鏈表的有序指順序還是指值的大小?

有序 通常是針對標準順序來說的,而標準順序比如我們自然數由小到大的順序就是標準順序。有序鏈表主要是值其存的值 從頭結點開始 跟標準順序一致 小的在前面 大的在後面。

有序是指鏈表中存的值,從頭結點開始由小到大排序。
單鏈表和雙鏈表的區分在指針域的個數上面,單鏈表只有一個指針域存儲後繼結點的指針,雙鏈表有兩個指針域一個存後繼節點的指針,另一存前驅節點的指針。

  1. 合併兩個有序鏈表
    https://leetcode-cn.com/problems/merge-two-sorted-lists/
    將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。
    示例:
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        #先考慮鏈表其中一個爲空的情況
        if not l1:
            return l2
        if not l2:
            return l1
        curNode1 = l1
        curNode2 = l2
        #先選出第一個節點
        if curNode1.val < curNode2.val:
            head = curNode1
            curNode1 = curNode1.next
        else:
            head = curNode2
            curNode2 = curNode2.next
        cur = head
        while curNode1 and curNode2:
            if curNode1.val < curNode2.val:
                cur.next = curNode1
                curNode1 = curNode1.next
            else:
                cur.next = curNode2
                curNode2 = curNode2.next
            cur = cur.next
        #一直循環到有一個鏈表先結束
        #如果是鏈表1先結束,則拼上鍊表2剩餘的那段
        if not curNode1:
            cur.next = curNode2
        #如果是鏈表2先結束,則拼上鍊表1剩餘的那段
        else:
            cur.next = curNode1
        return head
  1. 刪除鏈表的倒數第N個節點
    https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
    給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。
    示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.
說明:給定的 n 保證是有效的。
進階:你能嘗試使用一趟掃描實現嗎?

疑問:爲什麼快的要比慢的快n個節點?

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head
        fast, slow = dummy, dummy
        for _ in range(n+1):
            fast = fast.next 
        while fast != None:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return dummy.next
  1. 旋轉鏈表
    https://leetcode-cn.com/problems/rotate-list/
    給定一個鏈表,旋轉鏈表,將鏈表每個節點向右移動k個位置,其中k是非負數。
示例 1:
輸入: 1->2->3->4->5->NULL, k = 2
輸出: 4->5->1->2->3->NULL

解釋:
向右旋轉 1 步: 5->1->2->3->4->NULL
向右旋轉 2 步: 4->5->1->2->3->NULL
示例 2:

輸入: 0->1->2->NULL, k = 4
輸出: 2->0->1->NULL

解釋:
向右旋轉 1 步: 2->0->1->NULL
向右旋轉 2 步: 1->2->0->NULL
向右旋轉 3 步: 0->1->2->NULL
向右旋轉 4 步: 2->0->1->NULL

不懂了

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def rotateRight(self, head: ListNode, k: int) -> ListNode:
        if head is None or head.next is None:
            return head
        fast = head
        slow = head
        p = head
        newHead = None
        count = 1
        while p.next:
            p = p.next
            count += 1
        # 看不懂了
        k = k % count
        while fast.next:
            fast = fast.next
            if k<=0:
                slow = slow.next
            k -= 1
        fast.next = head
        newHead = slow.next
        slow.next = None
        return newHead
發佈了11 篇原創文章 · 獲贊 0 · 訪問量 1527
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章