链表常见考点(Python)

文章介绍了链表作为线性表数据结构的一种,与数组的区别以及常见的链表类型。接着,文章列举了五个链表相关的编程题,包括链表反转、环的检测、两个有序链表的合并、删除倒数第k个节点以及寻找链表中间节点的解题方法。
摘要由CSDN通过智能技术生成

0. 概念

介绍“链表”之前,我们先聊聊“数组”。
“数组”(Array)大家应该都比较熟悉,知道它是一种线性表(Linear List)数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。顾名思义,“线性表”就是数据排成像一条线一样的结构,线性表上的每个数据最多只有前和后两个方向。
其实除了“数组”,我们所熟知的“链表”,“队列”和“栈”也是线性表结构。
在这里插入图片描述
而与之相对立的概念是“非线性表”,比如树,堆,图等。在非线性表中,数据之间就不是简单的前后关系。
在这里插入图片描述
“数组”是用一组连续的内存空间,来存储一组具有相同类型的数据。与之对应的,“链表”则是用一组不连续的内存空间,来存储相同类型的数据。
在这里插入图片描述
相比于“数组”,“链表”具有五花八门的结构,其中最常见的三种分别是:单链表,双链表和循环链表。
“单链表”是最简单的链表,面试中考查链表的知识,一般都是基于“单链表”来进行考查。
单链表中每个结点,需要一个变量来存放数据,同时还需要一个“指针”指向下一个结点。
在这里插入图片描述

1. 常见考点

接下来,介绍5个常见的考查“链表”的编程题。

链表结点定义如下:

class Node:
	def __init__(self, x):
		self.data = x
		self.next = None

1.1 链表反转

给定一个链表的头结点,请反转这个链表,返回反转后新链表的头结点。

def reverse_list(head):
  if head is None or head.next is None:
    return head
  prev, cur = None, head
  while cur:
    cur.next, prev, cur = prev, cur, cur.next
  return prev

1.2 链表中环的检测

给定一个链表的头结点,返回该链表是否是环。

def is_cyclic(head):
  if head is None:
    return False
  slow = fast = head
  while slow.next and fast.next.next:
    slow, fast = slow.next, fast.next.next
    if slow == fast:
      return True
  return False

1.3 两个有序链表的合并

给定两个有序链表的头结点,请合并这两个链表,返回合并之后新链表的头结点。

def merge_two_list(l1, l2):
  ret = cur = Node(0)
  while l1 and l2:
    if l1.data < l2.data:
      cur.next = l1
      l1 = l1.next
    else:
      cur.next = l2
      l2 = l2.next
    cur = cur.next
  cur.next = l1 or l2
  return ret.next	# ret只是一个哨兵,新链表的头结点应该是ret.next

1.4 删除链表中倒数第k个结点

这题可以拆分成两个函数,第一个函数实现找到倒数第k个结点,第二个函数实现删除结点。

def kth_to_last(head):
	if head is None or k < 1:
		return None
	p1 = p2 = head
	for i in range(k):	# 先将p1向前移动k位
		if p1 is None:	# 若中途p1为None,说明k值过大,超出链表长度
			return None
		p1 = p1.next
	while p1:	# 然后再同时移动p1和p2,直到p1为None
		p1 = p1.next
		p2 = p2.next
	return p2

def delete_node(head, p):
	if head is None or p is None:
		raise ValueError
	if p.next is None:	# p是尾结点,则直接将p删除即可(置为None)
		p = None
	else:	# p不是尾结点,则p结点复制后继结点的值,然后删除后继结点
		p.data = p.next.data
		p.next = p.next.next

1.5 找链表的中间结点

def mid_node(head):
	if head is None or head.next is None:
		return head
	slow = fast = head
	while slow.next and fast.next.next:
		slow, fast = slow.next, fast.next.next
	return slow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值