python链表实现栈_使用python实现数组、链表、队列、栈

引言

什么是数据结构?

数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。

简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中。

比如:列表,集合和字典等都是数据结构

N.Wirth:“程序=数据结构+算法”

数据结构按照其逻辑结构可分为线性结构、树结构、图结构

线性结构:数据结构中的元素存在一对一的互相关系。

树结构:数据结构中的元素存在一对多的互相关系。

图结构:数据结构中的元素存在多对多的互相关系。

数组

在python中是没有数组的,有的是列表,它是一种基本的数据结构类型。

实现

classArray(object):def __init__(self, size=32):""":param size: 长度"""self._size=size

self._items= [None] *size#在执行array[key]时执行

def __getitem__(self, index):returnself._items[index]#在执行array[key] = value 时执行

def __setitem__(self, index, value):

self._items[index]=value#在执行len(array) 时执行

def __len__(self):returnself._size#清空数组

def clear(self, value=None):for i inrange(len(self._items)):

self._items[i]=value#在遍历时执行

def __iter__(self):for item inself._items:yield item

使用

a = Array(4)

a[0]= 1

print(a[0]) #1

a.clear()print(a[0]) #None

a[0]= 1a[1] = 2a[3] = 4

for i ina:print(i) #1, 2, None, 4

链表

链表中每一个元素都是一个对象,每一个对象被称为节点,包含有数据域value和指向下一个节点的指针next。

通过各个节点直接的相互链接,最终串成一个链表。

1414912-20191219155923315-2037345855.png

实现

classNode(object):def __init__(self, value=None, next=None):

self.value, self.next=value, nextclassLinkedList(object):def __init__(self, size=None):""":param size: int or None, 如果None,则该链表可以无限扩充"""self.size=size#定义一个根节点

self.root =Node()#尾节点始终指向最后一个节点

self.tail_node =None

self.length=0def __len__(self):returnself.lengthdefappend(self, value):#size 不为 None, 且长度大于等于size则链表已满

if self.size and len(self) >=self.size:raise Exception("LinkedList is full")#构建节点

node =Node(value)

tail_node=self.tail_node#判断尾节点是否为空

if tail_node isNone:#还没有 append 过,length = 0, 追加到 root 后

self.root.next =nodeelse:#否则追加到最后一个节点的后边,并更新最后一个节点是 append 的节点

tail_node.next =node#把尾节点指向node

self.tail_node =node#长度加一

self.length += 1

#往左边添加

defappend_left(self, value):if self.size and len(self) >=self.size:raise Exception("LinkedList is full")#构建节点

node =Node(value)#链表为空,则直接添加设置

if self.tail_node isNone:

self.tail_node=node#设置头节点为根节点的下一个节点

head_node =self.root.next#把根节点的下一个节点指向node

self.root.next =node#把node的下一个节点指向原头节点

node.next =head_node#长度加一

self.length += 1

#遍历节点

defiter_node(self):#第一个节点

current_node =self.root.next#不是尾节点就一直遍历

while current_node is notself.tail_node:yieldcurrent_node#移动到下一个节点

current_node =current_node.next#尾节点

if current_node is notNone:yieldcurrent_node#实现遍历方法

def __iter__(self):for node inself.iter_node():yieldnode.value#删除指定元素

defremove(self, value):#删除一个值为value的节点,只要使该节点的前一个节点的next指向该节点的下一个

#定义上一个节点

perv_node =self.root#遍历链表

for current_node inself.iter_node():if current_node.value ==value:#把上一个节点的next指向当前节点的下一个节点

perv_node.next =current_node.next#判断当前节点是否是尾节点

if current_node isself.tail_node:#更新尾节点 tail_node

#如果第一个节点就找到了,把尾节点设为空

if perv_node isself.root:

self.tail_node=Noneelse:

self.tail_node=perv_node#删除节点,长度减一,删除成功返回1

delcurrent_node

self.length-= 1

return 1

else:

perv_node=current_node#没找到返回-1

return -1

#查找元素,找到返回下标,没找到返回-1

deffind(self, value):

index=0#遍历链表,找到返回index,没找到返回-1

for node inself.iter_node():if node.value ==value:returnindex

index+= 1

return -1

#删除第一个节点

defpopleft(self):#链表为空

if self.root.next isNone:raise Exception("pop from empty LinkedList")#找到第一个节点

head_node =self.root.next#把根节点的下一个节点,指向第一个节点的下一个节点

self.root.next =head_node.next#获取删除节点的value

value =head_node.value#如果第一个节点是尾节点, 则把尾节点设为None

if head_node isself.tail_node:

self.tail_node=None#长度减一,删除节点,返回该节点的值

self.length -= 1

delhead_nodereturnvalue#清空链表

defclear(self):for node inself.iter_node():delnode

self.root.next=None

self.tail_node=None

self.length=0#反转链表

defreverse(self):#第一个节点为当前节点,并把尾节点指向当前节点

current_node =self.root.next

self.tail_node=current_node

perv_node=Nonewhilecurrent_node:#下一个节点

next_node =current_node.next#当前节点的下一个节点指向perv_node

current_node.next =perv_node#当前节点的下一个节点为空,则把根节点的next指向当前节点

if next_node isNone:

self.root.next=current_node#把当前节点赋值给perv_node

perv_node =current_node#把下一个节点赋值为当前节点

current_node = next_node

使用

ll =LinkedList()

ll.append(0)

ll.append(1)

ll.append(2)

ll.append(3)print(len(ll)) #4

print(ll.find(2)) #2

print(ll.find(-1)) #-1

ll.clear()print(len(ll)) #0

print(list(ll)) #[]

循环链表

双链表中每一个节点有两个指针,一个指向后面节点、一个指向前面节点。

1414912-20191219161342455-1754452270.png

循环链表实现

classNode(object):def __init__(self, value=None, prev=None, next=None):

self.value=value

self.prev=prev

self.next=nextclassCircularDoubleLinkedList(object):"""双向循环链表"""

def __init__(self, maxsize=None):

self.maxsize=maxsize

node=Node()

node.prev=node

node.next=node

self.root=node

self.length=0def __len__(self):returnself.lengthdefhead_node(self):returnself.root.nextdeftail_node(self):returnself.root.prev#遍历

defiter_node(self):if self.root.next isself.root:returncurrent_node=self.root.nextwhile current_node.next is notself.root:yieldcurrent_node

current_node=current_node.nextyieldcurrent_nodedef __iter__(self):for node inself.iter_node():yieldnode.value#反序遍历

defiter_node_reverse(self):if self.root.prev isself.root:returncurrent_node=self.root.prevwhile current_node.prev is notself.root:yieldcurrent_node

current_node=current_node.prevyieldcurrent_nodedefappend(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception("LinkedList is full")

node=Node(value)

tail_node= self.tail_node() orself.root

tail_node.next=node

node.prev=tail_node

node.next=self.root

self.root.prev=node

self.length+= 1

defappend_left(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception("LinkedList is full")

node=Node(value)if self.root.next isself.root:

self.root.next=node

node.prev=self.root

node.next=self.root

self.root.prev=nodeelse:

node.next=self.root.next

self.root.next.prev=node

self.root.next=node

node.prev=self.root

self.length+= 1

defremove(self, node):if node isself.root:returnnode.next.prev=node.prev

node.prev.next=node.next

self.length-= 1

return node

循环链表的使用

dll =CircularDoubleLinkedList()

dll.append(0)

dll.append(1)

dll.append(2)assert list(dll) == [0, 1, 2]print(list(dll)) #[0, 1, 2]

print([node.value for node in dll.iter_node()]) #[0, 1, 2]

print([node.value for node in dll.iter_node_reverse()]) #[2, 1, 0]

headnode=dll.head_node()print(headnode.value) #0

dll.remove(headnode)print(len(dll)) #2

队列

队列(Queue)是一个数据集合,仅允许在列表的一端进行插入,另一端进行删除。

进行插入的一端成为队尾(rear),插入动作称为进队或入队。

进行删除的一端称为队头(front),删除动作称为出队。

队列的性质:先进先出(First-in, First-out)。

1414912-20191219163231988-1044503215.jpg

基于数组实现环形队列

classArray(object):def __init__(self, size=32):""":param size: 长度"""self._size=size

self._items= [None] *size#在执行array[key]时执行

def __getitem__(self, index):returnself._items[index]#在执行array[key] = value 时执行

def __setitem__(self, index, value):

self._items[index]=value#在执行len(array) 时执行

def __len__(self):returnself._size#清空数组

def clear(self, value=None):for i inrange(len(self._items)):

self._items[i]=value#在遍历时执行

def __iter__(self):for item inself._items:yielditemclassArrayQueue(object):def __init__(self, maxsize):

self.maxsize=maxsize

self.array=Array(maxsize)

self.head=0

self.tail=0def __len__(self):return self.head -self.tail#入队

defpush(self, value):if len(self) >=self.maxsize:raise Exception("Queue is full")

self.array[self.head% self.maxsize] =value

self.head+= 1

#出队

defpop(self):

value= self.array[self.tail %self.maxsize]

self.tail+= 1

return value

使用

size = 5q=ArrayQueue(size)for i inrange(size):

q.push(i)print(len(q)) #5

print(q.pop()) #0

print(q.pop()) #1

双向队列

两端都可以进行插入,删除。

1414912-20191219164231193-421766962.jpg

基于双向链表实现双向队列

classNode(object):def __init__(self, value=None, prev=None, next=None):

self.value=value

self.prev=prev

self.next=nextclassCircularDoubleLinkedList(object):"""双向循环链表"""

def __init__(self, maxsize=None):

self.maxsize=maxsize

node=Node()

node.prev=node

node.next=node

self.root=node

self.length=0def __len__(self):returnself.lengthdefhead_node(self):returnself.root.nextdeftail_node(self):returnself.root.prev#遍历

defiter_node(self):if self.root.next isself.root:returncurrent_node=self.root.nextwhile current_node.next is notself.root:yieldcurrent_node

current_node=current_node.nextyieldcurrent_nodedef __iter__(self):for node inself.iter_node():yieldnode.value#反序遍历

defiter_node_reverse(self):if self.root.prev isself.root:returncurrent_node=self.root.prevwhile current_node.prev is notself.root:yieldcurrent_node

current_node=current_node.prevyieldcurrent_nodedefappend(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception("LinkedList is full")

node=Node(value)

tail_node= self.tail_node() orself.root

tail_node.next=node

node.prev=tail_node

node.next=self.root

self.root.prev=node

self.length+= 1

defappend_left(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception("LinkedList is full")

node=Node(value)if self.root.next isself.root:

self.root.next=node

node.prev=self.root

node.next=self.root

self.root.prev=nodeelse:

node.next=self.root.next

self.root.next.prev=node

self.root.next=node

node.prev=self.root

self.length+= 1

defremove(self, node):if node isself.root:returnnode.next.prev=node.prev

node.prev.next=node.next

self.length-= 1

returnnode#双向队列

classDeque(CircularDoubleLinkedList):#从右边出队

defpop(self):if len(self) <=0:raise Exception("stark is empty!")

tail_node=self.tail_node()

value=tail_node.value

self.remove(tail_node)returnvalue#从左边出队

defpopleft(self):if len(self) <=0:raise Exception("stark is empty!")

head_node=self.head_node()

value=head_node.value

self.remove(head_node)return value

双向队列的使用

dq =Deque()

dq.append(1)

dq.append(2)print(list(dq)) #[1, 2]

dq.appendleft(0)print(list(dq)) #[0, 1, 2]

dq.pop()print(list(dq)) #[0, 1]

dq.popleft()print(list(dq)) #[1]

dq.pop()print(len(dq)) #0

栈(Stack)是一个数据集合,可以理解为只能在一端插入或删除操作的链表。

栈的特点:后进先出(Last-in, First-out)

栈的概念:

栈顶

栈底

栈的基本操作:

进栈(压栈):push

出栈:pop

1414912-20191219165343462-7462866.jpg

基于双向队列实现

classNode(object):def __init__(self, value=None, prev=None, next=None):

self.value=value

self.prev=prev

self.next=nextclassCircularDoubleLinkedList(object):"""双向循环链表"""

def __init__(self, maxsize=None):

self.maxsize=maxsize

node=Node()

node.prev=node

node.next=node

self.root=node

self.length=0def __len__(self):returnself.lengthdefhead_node(self):returnself.root.nextdeftail_node(self):returnself.root.prev#遍历

defiter_node(self):if self.root.next isself.root:returncurrent_node=self.root.nextwhile current_node.next is notself.root:yieldcurrent_node

current_node=current_node.nextyieldcurrent_nodedef __iter__(self):for node inself.iter_node():yieldnode.value#反序遍历

defiter_node_reverse(self):if self.root.prev isself.root:returncurrent_node=self.root.prevwhile current_node.prev is notself.root:yieldcurrent_node

current_node=current_node.prevyieldcurrent_nodedefappend(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception("LinkedList is full")

node=Node(value)

tail_node= self.tail_node() orself.root

tail_node.next=node

node.prev=tail_node

node.next=self.root

self.root.prev=node

self.length+= 1

defappend_left(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception("LinkedList is full")

node=Node(value)if self.root.next isself.root:

self.root.next=node

node.prev=self.root

node.next=self.root

self.root.prev=nodeelse:

node.next=self.root.next

self.root.next.prev=node

self.root.next=node

node.prev=self.root

self.length+= 1

defremove(self, node):if node isself.root:returnnode.next.prev=node.prev

node.prev.next=node.next

self.length-= 1

returnnodeclassDeque(CircularDoubleLinkedList):defpop(self):if len(self) <=0:raise Exception("stark is empty!")

tail_node=self.tail_node()

value=tail_node.value

self.remove(tail_node)returnvaluedefpopleft(self):if len(self) <=0:raise Exception("stark is empty!")

head_node=self.head_node()

value=head_node.value

self.remove(head_node)returnvalueclassStack(object):def __init__(self):

self.deque=Deque()#压栈

defpush(self, value):

self.deque.append(value)#出栈

defpop(self):return self.deque.pop()

使用

s =Stack()

s.push(0)

s.push(1)

s.push(2)print(s.pop()) #2

print(s.pop()) #1

print(s.pop()) #0

~>.<~

loading.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笛卡尔乘积c语言代码,c# – 高效笛卡尔乘积算法

有人可以向我证明比目前使用的笛卡儿乘积算法更有效(假设有一个)。我已经看了周围的SO和谷歌&#xff0c;但看不到任何明显的东西&#xff0c;所以我可能会缺少一些东西。foreach (int i in is) {foreach (int j in js) {//Pair i and j}}这是我在代码中做的非常简化的版本。两…

【音视频安卓开发 (七)】安卓视频播放窗口去掉标题栏、全屏、横屏

java中的MainActivity初始化部分设置这些操作 //去掉标题栏supportRequestWindowFeature( Window.FEATURE_NO_TITLE);//全屏&#xff0c;隐藏状态getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN ,WindowManager.LayoutParams.FLAG_FULLSCREEN);//屏幕为横屏…

drools6.5_Drools 6.4.0.Final提供

drools6.5最新和最出色的Drools 6.4.0.Final版本现已可供下载。 这是我们先前构建的增量版本&#xff0c;对核心引擎和Web工作台进行了一些改进。 您可以在此处找到更多详细信息&#xff0c;下载和文档&#xff1a; Drools网站 资料下载 文献资料 发行说明 请阅读下面的…

python 统计组合用什么库_Python机器学习需要用到的库

www.oldboyedu.com 老男孩 IT 教育&#xff0c;只培养技术精英 Python 机器学习需要用到的库 Python 是一种面向对象的解释型计算机程序设计语言&#xff0c;具有丰富和强大的 库&#xff0c;再加上其简单、易学、速度快、开源免费、可移植性、可扩展性以及面向对 象的特点&…

c语言编程数学黑洞,一个数学黑洞——6174

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*问题描述&#xff1a;从0-9中任意选取4个不完全相同的数比如&#xff0c;不能是5 5 5 5&#xff0c;可以是1 2 2 2用这4个数排列出最大的数&#xff0c;2221&#xff0c;最小的数1222最大减最小&#xff1a;2221-12220999用0 9 9…

【音视频安卓开发 (八)】OpenSLES播放音频步骤和接口讲解

OpenSLES是安卓内部的音频播放和录音 初始化引擎 创建输出设备 配置PCM格式信息 初始化播放器 播放和缓冲队列 本文开源项目下载

kata_FizzBu​​zz Kata与Java流

kata在柔道练习仅几周之后&#xff0c;我的儿子感到无聊。 他抱怨说自己没有学任何东西&#xff0c;因为他一遍又一遍地做着同样的事情。 混淆学习和做新事物的不仅是幼儿。 例如&#xff0c;有多少软件开发人员通过执行kata或参加dojos来进行刻意练习的麻烦&#xff1f; 重复…

python中if语句的实例_对python中if语句的真假判断实例详解

说明 在python中&#xff0c;if作为条件语句&#xff0c;当if后面的条件参数为真时&#xff0c;则执行后面的语句块&#xff0c;反之跳过&#xff0c;为了深入理解if语句&#xff0c;我们需要知道if语句的真假判断方式。 示例 在python交互器中&#xff0c;经过测试发现以下条件…

ds18b20c语言显示小数位,DS18B20多点测温(读序列,匹配序列,51单片机C程序,1602显示)...

DS18B20多点测温(读序列&#xff0c;匹配序列&#xff0c;51 C程序&#xff0c;1602显示)程序一&#xff1a;单个读序列号。程序二&#xff0c;匹配并且读两个DS18B20&#xff0c;当然&#xff0c;读多个与读两个基本原理一样&#xff0c;只要加上其序列号等即可。本程序所有显…

【WebRTC---入门篇】(五)Web服务器原理与Nodejs搭建

Web服务器工作原理 Nodejs工作原理 首先自己开发的APPLICATION(自己开发的JS程序)输出给V8引擎,解析后的二进制文件调用NODE API,然后调用LIBUV事件处理库(插入到事件队列,在队列中不断循环处理事件)。 JavaScript解析 V8引擎先收到JS程序,解析生成JS语法树,通过解析器…

代理模式和动态代理模式_代理模式介绍

代理模式和动态代理模式代表&#xff1a;被选中或当选为他人投票或代理的人– Merriam-Webster 。 委托模式&#xff1a;在软件工程中&#xff0c;委托模式是面向对象编程中的一种设计模式&#xff0c;其中&#xff0c;一个对象而不是执行其陈述的任务之一&#xff0c;而是将该…

【WebRTC---入门篇】(六)JavaScript基础

变量与类型 var与let的区别&#xff0c;var局部变量&#xff1b;let全局变量 函数

javaio流层次结构_流的多层次分组

javaio流层次结构1.简介 使用Java 8流&#xff0c;可以很容易地根据不同的标准对对象集合进行分组。 在这篇文章中&#xff0c;我们将看到如何从简单的单级分组到更复杂的&#xff0c;涉及多个级分组的分组。 我们将使用两个类来表示我们要分组的对象&#xff1a;人和宠物。 …

【开源项目----Android OPenGLES渲染YUV视频文件】

【开源项目----Android OPenGLES渲染YUV视频文件】 OpenGLES对YUV渲染相关文章参考

大型程序是如何开发的_大型小程序如何研发提效

作者:王梦君微信公众号:滴滴顺风车技术出处:https://mp.weixin.qq.com/s/M1VArJ_ORY-eXSKzD6ysQw导读&#xff1a;自2016年小程序诞生以来&#xff0c;小程序以其“用完即走”的设计理念&#xff0c;以及简单易上手的开发模式&#xff0c;吸引了大批的小程序使用者以及开发者&a…

c 语言栈,C语言栈

C语言实现简单的栈结构今天看到一个问题是要交换两个变量的值并且不能使用中间变量&#xff0c;首先想到的方法就是用数学的方法&#xff1a;int a 10,b 12;a a b; // 求和b a - b; // 和减去b得到的是a的值a a - b; // 和减去a(此时的b是最初a的值)得到b 的值这种方法很…

【WebRTC---入门篇】(七)MediaStream

MediaStream方法 MediaStream.addTrack( ) 功能&#xff1a;向流媒体中加入不同的轨 MediaStream.removeTrack( ) 功能&#xff1a;从流媒体中移除不同的轨 MediaStream.getVideoTracks( ) 功能&#xff1a;从流媒体中取出所有的视频轨 MediaStream.getAudioTracks( …

jvm 宕机 打印jvm_通过入侵JVM打印阵列

jvm 宕机 打印jvm总览 Java中最常见的陷阱之一就是知道如何打印数组。 如果有关如何打印阵列的答案获得了超过1000票赞成票&#xff0c;那么您必须怀疑是否有更简单的方法。 几乎所有其他流行语言都具有这种更简单的方法&#xff0c;所以我不清楚为什么Java仍会这样做。 与其他…

python数码时钟代码_Python+Pyqt实现简单GUI电子时钟

本文实例为大家分享了PythonPyqt实现简单GUI电子时钟的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 突发奇想想用GUI做一个简单的电子时钟界面&#xff0c;利用pyqt模块也很方便&#xff0c;代码如下&#xff1a; from PyQt5.QtGui import * from PyQt5.QtCore im…

两个人投票的c语言程序,设计网页投票器(二)《精通Unix下C语言编程与项目实践》之十...

本处设计一个网页投票器&#xff0c;它访问“www.zhiliaowang.com”上的服务程序“/toupiaoceshi.asp”&#xff0c;并通过“name”参数向选手投票。如代码15-16所示&#xff1a;代码15-16网页投票器(节自/code/chapter15/http1.c)#include char buf2[]/*组装HTTP协议GET请求报…