예제 #1
0
def test_list_appends_x():
    l = LinkedList()
    l.append(1)
    l.append(2)
    l.append(3)
    assert len(l) == 3
    assert list(l) == [1, 2, 3]
예제 #2
0
def build_two_list_with_common_nodes(seq1, seq2, common_nodes=None):
    if seq1 is None and seq2:
        return List.fromvalues(seq2).head

    if seq1 and seq2 is None:
        return List.fromvalues(seq1).head

    l1 = List.fromvalues(seq1)
    l2 = List.fromvalues(seq2)

    if common_nodes is None or len(common_nodes) < 1:
        return l1.head, l2.head

    last_node1 = l1.find_node(l1[-1])
    last_node2 = l2.find_node(l2[-1])

    l1.head.val += len(common_nodes)
    l2.head.val += len(common_nodes)

    common_node = Node(common_nodes[0], None)
    last_node1.next = common_node
    last_node2.next = common_node

    for x in common_nodes[1:]:
        common_node.next = Node(x, None)
        common_node = common_node.next

    return l1.head, l2.head
def remove_duplicates(data):
    if data is None:
        return None

    if len(data) == 0:
        return []

    head = List.fromvalues(data).head
    return list(List.fromhead(_remove_duplicates(head)))
예제 #4
0
def test_lists_are_equal():
    l1 = LinkedList.fromvalues([1, 2, 3, 4])

    with pytest.raises(TypeError):
        assert l1 == [1, 2, 3, 4]

    l2 = LinkedList.fromvalues([1, 2, 3])
    assert l1 != l2

    l3 = LinkedList.fromvalues([1, 2, 3, 4])
    assert l1 == l3
예제 #5
0
def delete(data, val):
    if data is None:
        return None

    if len(data) == 0:
        return []

    head = List.fromvalues(data).head

    p = head.next

    while p and p.val != val:
        p = p.next

    return list(List.fromhead(_delete_node(head, p)))
예제 #6
0
def test_list_removes_x():
    l = LinkedList.fromvalues([1, 2, 3, 4, 5, 6])
    l.remove(1)
    assert 5 == len(l)
    assert 1 not in l

    with pytest.raises(ValueError):
        l.remove(10)
예제 #7
0
def test_visit_linkedlist_reversely(visit_func, seq, expect):
    assert visit_func(None) is None

    output = StringIO()
    with redirect_stdout(output):
        head = List.fromvalues(seq).head.next
        visit_func(head)

    assert output.getvalue().strip() == expect.strip()
예제 #8
0
def test_list_indexes_x():
    l = LinkedList.fromvalues([1, 2, 3, 4, 5, 6])
    assert 0 == l.index(1)
    assert 5 == l.index(6)
    assert 5 == l.index(6, 5)

    with pytest.raises(ValueError):
        l.index(12)

    with pytest.raises(ValueError):
        l.index(1, 2)
예제 #9
0
def test_list_inserts_x():
    l = LinkedList.fromvalues([1])
    l.insert(0, 2)
    assert len(l) == 2
    assert [2, 1] == list(l)

    l.insert(3, 3)
    assert len(l) == 3
    assert [2, 1, 3] == list(l)

    l.insert(100, 100)
    assert [2, 1, 3, 100] == list(l)
예제 #10
0
def merge_two_sorted_list(values_left, values_right):
    """这个是一个典型的递归过程
    原则是谁小谁做最终链表的头,这样整个递归完成后,就得到有序的
    链表了。
    """
    left_head = List.fromvalues(values_left).head
    right_head = List.fromvalues(values_right).head

    # 考虑特殊情况
    if left_head is None:
        return right_head
    elif right_head is None:
        return left_head

    if left_head is None and right_head is None:
        return None

    # 指向真正的头节点
    merged_head = Node(None, None)

    def merge(left, right):
        if left is None:
            return right
        elif right is None:
            return left

        # 谁小谁做头
        if left.val > right.val:
            head = right
            head.next = merge(left, right.next)
        else:
            head = left
            head.next = merge(left.next, right)

        return head

    merged_head.next = merge(left_head.next, right_head.next)
    return merged_head
예제 #11
0
def build_partial_circular_list(values, entry_value):
    """构建部分环形的链表"""
    if values is None:
        return None

    values = List.fromvalues(values)

    if entry_value is not None:
        # 查找 entry 节点
        entry_node = values.find_node(entry_value)
        last_node = values.find_node(values[-1])
        last_node.next = entry_node

    return values.head
예제 #12
0
def test_list_pops_item():
    l = LinkedList.fromvalues([1, 2, 3, 4, 5, 6])
    assert 1 == l.pop(0)
    assert len(l) == 5

    assert 6 == l.pop()
    assert len(l) == 4

    # [2, 3, 4, 5]
    assert 3 == l.pop(1)
    assert 4 == l.pop(-2)
    assert 5 == l.pop()
    assert 2 == l.pop()

    with pytest.raises(IndexError):
        l.pop()
예제 #13
0
 def _(*args, **kwargs):
     head = func(*args, **kwargs)
     if head is not None:
         return list(List.fromhead(head))
     return None
예제 #14
0
        while q and steps > 0:
            q = q.next
            steps -= 1

    # 二者一起往后走,直到遇到相同的节点

    while p and q:
        if p is q:
            return p.val

        p = p.next
        q = q.next

    return None


def _get_length(head):
    if head is None:
        return 0
    return head.val


if __name__ == '__main__':
    h1, h2 = build_two_list_with_common_nodes([1, 2], [4, 5, 6],
                                              common_nodes=[10, 11, 12])
    print(List.fromhead(h1))
    print(List.fromhead(h2))

    print(find_first_common_node_2(h1, h2))
    print(_get_length(h1))
예제 #15
0
def test_find_kth_node(seq, k, expected):
    head = List.fromvalues(seq).head if seq else None
    if expected is None:
        assert find_kth_node(head, k) is None
    else:
        assert find_kth_node(head, k).val == expected
예제 #16
0
def test_list_contains_x():
    values = [1, 2, 3, 4]
    l = LinkedList.fromvalues(values)
    assert 1 in l
    assert 3 in l
    assert 10 not in l
예제 #17
0
def test_create_linked_list_from_values():
    values = [1, 2, 3, 4]
    l = LinkedList.fromvalues(values)
    assert list(l) == values
    assert len(l) == len(values)
    if head is None:
        return None

    visit_linkedlist_reversely1(head.next)
    print(head.val, end=' ')


def visit_linkedlist_reversely2(head):
    """利用一个栈结构存储节点,避免递归深度过大导致可能的栈溢出问题,提高
    程序的鲁棒性"""
    if head is None:
        return None

    from collections import deque
    nodes = deque()

    while head is not None:
        nodes.append(head.val)
        head = head.next

    while len(nodes) > 0:
        print(nodes.pop(), end=' ')


if __name__ == '__main__':
    from src.datastructures.linkedlist.single import List

    l = List.fromvalues([1, 2, 3, 4])
    visit_linkedlist_reversely1(l.head.next)
    visit_linkedlist_reversely2(l.head.next)
예제 #19
0
def test_reverse_list(values, reversed_values):
    l = LinkedList.fromvalues(values)
    l.reverse()
    assert list(l) == reversed_values
예제 #20
0
    if head is None:
        return None

    if k < 1:
        return None

    behind, ahead = head.next, head.next

    for _ in range(k - 1):
        # 头指针先走 k -1 步
        ahead = ahead.next

        if ahead is None:
            # 防止走过头了,可能链表长度不够
            return None

    # 前后指针共同往后走
    while ahead.next:
        ahead = ahead.next
        behind = behind.next

    # behind 所指向的就是相应的节点
    return behind


if __name__ == '__main__':
    from src.datastructures.linkedlist.single import List

    l = List.fromvalues([1])
    print(find_kth_node(l.head, 1))