数据结构与算法之数据结构 链表面试高频 反转 / 合并 / 环形链表

数据结构与算法阿木 发布于 4 天前 1 次阅读


摘要:链表是数据结构中的一种重要类型,它在面试中经常被考察。本文将围绕链表的反转、合并以及环形链表这一主题,解析常见面试高频问题,并提供相应的代码实现。

一、

链表是一种非线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表具有插入、删除操作灵活等优点,在计算机科学中应用广泛。在面试中,链表问题往往考察应聘者的数据结构与算法基础,以及解决问题的能力。本文将针对链表的反转、合并以及环形链表这一主题,解析常见面试高频问题,并提供相应的代码实现。

二、链表反转

1. 问题解析

链表反转是面试中常见的问题,主要考察应聘者对链表结构的理解以及反转操作的实现。链表反转可以分为两种情况:单链表反转和双向链表反转。

2. 代码实现

以下为单链表反转的代码实现:

python

class ListNode:


def __init__(self, val=0, next=None):


self.val = val


self.next = next

def reverse_single_linked_list(head):


prev = None


curr = head


while curr:


next_node = curr.next


curr.next = prev


prev = curr


curr = next_node


return prev

测试代码


head = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))


reversed_head = reverse_single_linked_list(head)


while reversed_head:


print(reversed_head.val)


reversed_head = reversed_head.next


以下为双向链表反转的代码实现:

python

class DoublyListNode:


def __init__(self, val=0, prev=None, next=None):


self.val = val


self.prev = prev


self.next = next

def reverse_doubly_linked_list(head):


prev = None


curr = head


while curr:


next_node = curr.next


curr.next = prev


curr.prev = next_node


prev = curr


curr = next_node


return prev

测试代码


head = DoublyListNode(1, DoublyListNode(2, DoublyListNode(3, DoublyListNode(4))))


reversed_head = reverse_doubly_linked_list(head)


while reversed_head:


print(reversed_head.val)


reversed_head = reversed_head.next


三、链表合并

1. 问题解析

链表合并是面试中另一个常见问题,主要考察应聘者对链表合并操作的实现。链表合并可以分为两种情况:单链表合并和双向链表合并。

2. 代码实现

以下为单链表合并的代码实现:

python

def merge_single_linked_lists(l1, l2):


dummy = ListNode()


tail = dummy


while l1 and l2:


if l1.val < l2.val:


tail.next = l1


l1 = l1.next


else:


tail.next = l2


l2 = l2.next


tail = tail.next


tail.next = l1 or l2


return dummy.next

测试代码


l1 = ListNode(1, ListNode(3, ListNode(5)))


l2 = ListNode(2, ListNode(4, ListNode(6)))


merged_head = merge_single_linked_lists(l1, l2)


while merged_head:


print(merged_head.val)


merged_head = merged_head.next


以下为双向链表合并的代码实现:

python

def merge_doubly_linked_lists(l1, l2):


dummy = DoublyListNode()


tail = dummy


while l1 and l2:


if l1.val < l2.val:


tail.next = l1


l1 = l1.next


else:


tail.next = l2


l2 = l2.next


tail = tail.next


tail.next = l1 or l2


return dummy.next

测试代码


l1 = DoublyListNode(1, DoublyListNode(3, DoublyListNode(5)))


l2 = DoublyListNode(2, DoublyListNode(4, DoublyListNode(6)))


merged_head = merge_doubly_linked_lists(l1, l2)


while merged_head:


print(merged_head.val)


merged_head = merged_head.next


四、环形链表

1. 问题解析

环形链表是链表的一种特殊形式,其中某个节点指向链表中的另一个节点,形成一个环。在面试中,环形链表问题主要考察应聘者对环形链表检测和删除操作的实现。

2. 代码实现

以下为环形链表检测的代码实现:

python

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

测试代码


l1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))


l2 = l1.next.next.next


l2.next = l1.next


print(has_cycle(l1)) 输出:True


以下为环形链表删除的代码实现:

python

def remove_cycle(head):


slow = head


fast = head


while fast and fast.next:


slow = slow.next


fast = fast.next.next


if slow == fast:


break


if slow != fast:


return head


slow = head


while slow.next != fast.next:


slow = slow.next


fast = fast.next


fast.next = None


return head

测试代码


l1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))


l2 = l1.next.next.next


l2.next = l1.next


head = remove_cycle(l1)


while head:


print(head.val)


head = head.next


五、总结

本文针对链表的反转、合并以及环形链表这一主题,解析了常见面试高频问题,并提供了相应的代码实现。通过学习本文,读者可以加深对链表数据结构的理解,提高解决实际问题的能力。在实际面试中,链表问题往往需要结合具体场景进行分析,希望本文能对读者有所帮助。