2024年Python最全Python数据结构与算法(3(1),2024春招面试资格线

(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

raise IndexError(‘Stack Underflow!’)

else:

result = self.stack[self.top]

self.top -= 1

return result

2.1.7 求栈顶元素

若栈不空,则只需返回栈顶元素:

def peek(self):

if self.isempty():

raise IndexError(‘Stack Underflow!’)

else:

return self.stack[self.top]

2.2 链栈的实现

栈的另一种存储表示方式是使用链式存储结构,因此也常称为链栈,其中 push 操作是通过在链表头部插入元素来实现的,pop 操作是通过从头部删除节点来实现的。

2.2.1 栈结点

栈的结点实现与链表并无差别:

class Node:

def init(self, data):

self.data = data

self.next = None

def str(self):

return str(self.data)

2.2.2 栈的初始化

栈的初始化函数中,使栈顶指针指向 None,并初始化栈长:

class Stack:

def init(self):

self.top = None

栈中元素数

self.length = 0

2.2.3 求栈长

返回 length 的值用于求取栈的长度,如果没有 length 属性,则需要遍历整个链表才能得到栈长:

def size(self):

return self.length

2.2.4 判栈空

根据栈的长度可以很容易的判断栈是否为空栈:

def isempty(self):

if self.length == 0:

return True

else:

return False

2.2.5 入栈

入栈时,在栈顶插入新元素即可:

def push(self, data):

p = Node(data)

p.next = self.top

self.top = p

self.length += 1

由于插入元素是在链表头部进行的,因此入栈的时间复杂度为 O ( 1 ) O(1) O(1),在这种情况下链尾作为栈底 。

2.2.5 出栈

若栈不空,则删除并返回栈顶元素:

def pop(self):

if self.isempty():

raise IndexError(“Stack Underflow!”)

ele = self.top.data

self.top = self.top.next

self.length -= 1

return ele

由于删除元素仅需修改头指针指向其 next 域,因此出栈的时间复杂度同样为 O ( 1 ) O(1) O(1)。

2.2.6 求栈顶元素

若栈不空,返回栈顶元素即可,但栈顶元素并不会被删除:

def peek(self):

if self.isempty():

raise IndexError(“Stack Underflow!”)

return self.top.data

2.3 栈的不同实现对比

本节我们将对比栈的不同实现之间的异同:

  • 顺序栈

  • 操作的时间复杂度均为 O ( 1 ) O(1) O(1),列表的尾部作为栈顶

  • 栈满时需要进行动态的扩展,复制原栈元素到新栈中

  • 链栈

  • 操作的时间复杂度均为 O ( 1 ) O(1) O(1),链表的头部作为栈顶

  • 优雅的扩展,无需考虑栈满,需要额外的空间存储指针

3. 栈应用


接下来,我们首先测试上述实现的链表,以验证操作的有效性,然后利用实现的基本操作来解决实际算法问题。

3.1 顺序栈的应用

首先初始化一个顺序栈 stack,然后测试相关操作:

初始化一个最大长度为4的栈

s = Stack(4)

print(‘栈空?’, s.isempty())

for i in range(4):

print(‘入栈元素:’, i)

s.push(i)

print(‘栈满?’, s.isfully())

print(‘栈顶元素:’, s.peek())

print(‘栈长度为:’, s.size())

while not s.isempty():

print(‘出栈元素:’, s.pop())

测试程序输出结果如下:

栈空? True

入栈元素: 0

入栈元素: 1

入栈元素: 2

入栈元素: 3

栈满? True

栈顶元素: 3

栈长度为: 4

出栈元素: 3

出栈元素: 2

出栈元素: 1

出栈元素: 0

3.2 链栈的应用

首先初始化一个链栈 stack,然后测试相关操作:

初始化新栈

s = Stack()

print(‘栈空?’, s.isempty())

for i in range(4):

print(‘入栈元素:’, i)

s.push(i)

print(‘栈顶元素:’, s.peek())

print(‘栈长度为:’, s.size())

while not s.isempty():

print(‘出栈元素:’, s.pop())

测试程序输出结果如下:

栈空? True

入栈元素: 0

入栈元素: 1

入栈元素: 2

入栈元素: 3

栈顶元素: 3

栈长度为: 4

出栈元素: 3

出栈元素: 2

出栈元素: 1

出栈元素: 0

3.3 利用栈基本操作实现复杂算法

[1] 匹配符号是指正确地匹配左右对应的符号(符号允许进行嵌套),不仅每一个左符号都有一个右符号与之对应,而且两个符号的类型也是一致的,下表展示了一些符号串的匹配情况:

| 符号串 | 是否匹配 |

| — | — |

| []()() | 匹配 |

| [(())() | 不匹配 |

| {([]())} | 匹配 |

| (())[]} | 不匹配 |

为了检查符号串的匹配情况,需要遍历符号串,如果字符是 ([{ 之类的开始分隔符,则将其写入栈中;当遇到诸如 )]} 等结束分隔符时,则栈顶元素出栈,并将其与当前遍历元素进行比较,如果它们匹配,则继续解析符号串,否则表示不匹配。当遍历完成后,如果栈不为空,则同样表示不匹配:

def isvalid_expression(expression):

stack = Stack()

symbols = {‘)’:‘(’, ‘]’:‘[’, ‘}’:‘{’}

for s in expression:

if s in symbols:

if stack:

top_element = stack.pop()

else:

top_element = ‘#’

if symbols[s] != top_element:

return False

else:

stack.push(s)

return not stack

由于我们只需要遍历符号串一边,因此算法的时间复杂度为 O ( n ) O(n) O(n),算法的空间复杂度同样为 O ( n ) O(n) O(n)。

[2] 给定一链表(带有头结点) L : L 0 → L 1 → … → L n L: L_0 \rightarrow L_1 \rightarrow … \rightarrow L_n L:L0​→L1​→…→Ln​,将其重排为: L 0 → L n → L 1 → L n − 1 … L_0 \rightarrow L_n \rightarrow L_1 \rightarrow L_{n-1}… L0​→Ln​→L1​→Ln−1​…。

例如链表中包含 9 个元素,则下图现实了重排前后的链表元素情况:

链表重排

由于栈的先进后出原则,可以利用栈与原链表的配合进行重排,首次按遍历链表,将每个结点入栈;栈中元素的出栈顺序为原链表结点的逆序,然后交替遍历链表和栈,构建新链表。

def reorder_list(L):

p = L.head.next

if p == None:

return L

stack = Stack()

while p!= None:

stack.push§

p = p.next

l = L.head.next

from_head = L.head.next

from_stack = True

while (from_stack and l != stack.peek() or (not from_stack and l != from_head)):

if from_stack:

from_head = from_head.next

l.next = stack.pop()

from_stack = False

else:

l.next = from_head

from_stack = True

l = l.next

l.next = None

该算法的时间复杂度和空间复杂度均为 O ( n ) O(n) O(n)。

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值