4-3 Python数据结构常考题

Python工程师面试宝典 专栏收录该内容
54 篇文章 0 订阅
一、常考题型

python web后端常考数据结构
1.常见的数据结构链表、队列、栈、二叉树、堆
2.使用内置结构实现高级数据结构,比如内置的 list/deque实现栈
3.Leetcode 或者 《剑指offer》上的常见题

二、常考数据结构之链表

链表有单链表、双链表、循环双端链表
1.如何使用 python来表示链表结构
2.实现链表常见操作,比如插入节点,反转链表,合并多个链表等
3.Leetcode练习常见链表题目

下面是 leetcode206号题 反转链表

# 定义单链表
class ListNode:
	def __init__(self, x):
		self.val = x
		self.next = None

class Solution:
	def reverseList(self, head):
		"""
		:type head: ListNode
		:rtype: ListNode
		"""
		pre = None
		cur = head
		while cur:
			next_node = cur.next
			cur.next = pre
			pre = cur
			cur = next_node
		return pre
		
三、常考数据结构之队列

队列(queue)是先进先出结构

1.如何使用python实现队列?
2.实现队列的 appendpop操作,如何做到先进先出
3.使用 pythonlist或者 collections.deque实现队列

代码示例:

from collections import deque

class Queue:
	def __init__(self):
		self.items = deque()

	def append(self, val):
		return self.items.append(val)

	def pop(self):
		return self.items.popleft()

	def empty(self):
		return len(self.items) == 0

def test_queue():
	q = Queue()
	q.append(0)
	q.append(1)
	q.append(2)
	
	print(q.pop())
	print(q.pop())
	print(q.pop())

test_queue()		

运行结果:
在这里插入图片描述

四、常考数据结构之栈

栈(stack)是后进先出结构
1.如何使用python实现栈?
2.实现栈的 pushpop 操作,如何做到后进先出
3.同样可以用 python list或者 collections.deque实现栈

代码示例:

class Stack:
    def __init__(self):
        self.items = deque()

    def push(self, val):
        return self.items.append(val)

    def pop(self):
        return self.items.pop()

    def empty(self):
        return len(self.items) == 0

def test_stack():
    q = Stack()
    q.push(0)
    q.push(1)
    q.push(2)
    print(q.pop())
    print(q.pop())
    print(q.pop())

test_stack()

借助内置的数据结构非常容易实现一个栈(Stack),后入先出

一个常考问题:如何用两个栈实现队列?

参考链接:Python剑指offer之两个栈实现一个队列-两个队列实现一个栈

class Queue_By_Stack:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []

    def append(self, val):
        self.stack1.append(val)

    def pop(self):
        if self.stack2 == []:
            if self.stack1 == []:
                return None
            else:
                for i in range(len(self.stack1)):
                    self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

如何实现获取最小值的栈MinStack
参考链接Python实现"最小栈"的两种方法

代码示例:

class MinStack:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []
        self.min_stack = []


    def push(self, val: int) -> None:
        if not self.min_stack or self.min_stack[-1] >= val:
            self.min_stack.append(val)
        self.stack.append(val)

    def pop(self) -> None:
        if self.min_stack[-1] == self.stack[-1]:
            del self.min_stack[-1]
        self.stack.pop()

    def top(self) -> int:
        return self.stack[-1]


    def getMin(self) -> int:
        return self.min_stack[-1]
五、常考数据结构之字典与集合

Python dict/set 底层都是哈希表
1.哈希表的实现原理,底层其实就是一个数组
2.根据哈希函数快速定位一个元素,平均查找O(1),非常快
3.不断加入元素会引起哈希表重新开辟空间,拷贝之前元素到新数组

六、哈希表如何解决冲突

链接法和开放寻址法
1.元素 key 冲突之后使用一个链表填充相同 key的元素
2.开放寻址法是冲突之后根据一种方式(二次探查)寻找下一个可用的槽
3.cpython使用的二次探查

七、常考数据结构之二叉树

先序、中序、后序遍历
1.先(根)序:先处理要,之后是左子树,然后是右子树
2.中(根)序:先处理左子树,然后是根,然后是右子树
3.后(根)序:先处理左子树,然后是右子树,最后是根

八、树的遍历方式

先序遍历,其实很简单,递归代码里先处理根就好了
中序遍历,调整下把print(subtree.data)放中间就好啦
后序遍历,调整下把print(subtree.data)放最后

class BinTreeNode:
	def __init__(self, data, left=None, right=None):
		self.data, self.left, self.right = data, left, right


class BinTree:
	def __init__(self, root=None):
		self.root = root

	def preorde_trav(self, subtree):
		""" 先(根)序遍历 """
		if subtree is not None:
			print(subtree.data)   # 递归函数里先处理根
			self.preorder_trav(subtree.left)   # 递归处理左子树
			self.preorder_trav(subtree.right)  # 递归处理右子树

	def inorder_trav(self, subtree):
		""" 中(根)序遍历 """
		if subtree is not None:
			self.preorder_trav(subtree.left)
			print(subtree.data)   # 中序遍历放到中间就好啦
			self.preorder_trav(subtree.right)
			
	 def lastorder_trav(self, subtree):
		""" 后(根)序遍历 """
		if subtree is not None:
			self.preorder_trav(subtree.left)			
			self.preorder_trav(subtree.right)
			print(subtree.data)   # 后序遍历放到最后
九、常考数据结构之堆

堆其实是完全二叉树,有最堆和最小堆
1.最大堆:对于每个非叶子节点 VV的值都比它的两个孩子大
2.最大堆支持每次 pop操作获取最大的元素,最小堆获取最小元素
3.常见问题:用堆来完成 topk 问题,从海量数字中寻找最大的 k

代码示例:

import heapq

class TopK:
    """
    获取大量元素 topk 大个元素,固定内存
    思路:
    1.先放入元素前 k 个建立一个最小堆
    2.迭代剩余元素:
        如果当前元素小于堆顶元素,跳过该元素(肯定不是前 k 大)
        否则替换堆顶元素为当前元素,并重新堆
    """

    def __init__(self, iterable, k):
        self.min_heap = []
        self.capacity = k
        self.iterable = iterable

    def push(self, val):
        if len(self.min_heap) >= self.capacity:
            min_val = self.min_heap[0]
            if val < min_val:  # 当然你可以直接  if val > min_val 操作,这里我只是显示指出跳过个元素
                pass
            else:
                heapq.heapreplace(self.min_heap, val)  # 返回并且 pop 堆顶最小值,推入新的 val 值并调整堆
        else:
            heapq.heappush(self.min_heap, val)  # 前面 k 个元素直接放入 min_heap

    def get_topk(self):
        for val in self.iterable:
            self.push(val)
        return self.min_heap


def test():
    import random
    i = list(range(1000))  # 这里可以是一个可迭代元素,节省内存
    random.shuffle(i)
    _ = TopK(i, 10)
    print(_.get_topk())

test()
  • 0
    点赞
  • 1
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值