引言

什么是数据结构?

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

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

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

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。

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

实现

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)) #[]

循环链表

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

循环链表实现

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)。

基于数组实现环形队列

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

双向队列

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

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

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

基于双向队列实现

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

~>.<~

python链表实现栈_使用python实现数组、链表、队列、栈相关推荐

  1. python实现括号匹配不用栈_使用Python实现栈,判断括号是否平衡

    栈(Stack)在计算机领域是一个被广泛应用的集合,栈是线性集合,访问都严格地限制在一段,叫做顶(top). 举个例子,栈就想一摞洗干净的盘子,你每次取一个新盘子,都是放在这一摞盘子的最上头,当你往里 ...

  2. 西安把python需要纳入课堂_西安Python测试开发全栈核心课程

    从初级的手工测试到.顶端的测试开发,大家都希望能不断的进行技术的提升,而就目前的现状而言,在企业内部不愿意花费成本去进行高级人才的培养,企业更愿意花高薪招聘高级技术人才,而我们希望能够在工作中不断提升 ...

  3. python数组和链表的区别_算法图解2 - 数组和链表

    原标题:算法图解2 - 数组和链表 我们继续上文的脚步,深入了解一下数组和链表.掌握它们之间的区别和联系,以及各自的使用场景,为后续的算法学习打好基础. 一.计算机内存的工作原理 为了更好的理解数组和 ...

  4. python 链表推导式_五--python之数据结构(Data Structures)

    1.列表list:a=[value1,value2,value3,value4,-] 方法论methods:list.append(x) #列表追加,等同于a[len(a):] = [x]list.e ...

  5. python大数据免费_用python做大数据

    不学Python迟早会被淘汰?Python真有这么好的前景? 最近几年Python编程语言在国内引起不小的轰动,有超越Java之势,本来在美国这个编程语言就是最火的,应用的非常非常的广泛,而Pytho ...

  6. python生成一笔画_用Python玩烧脑小游戏《一笔画完》,瞬间闯到100关

    原标题:用Python玩烧脑小游戏<一笔画完>,瞬间闯到100关 " 昨天和朋友出去外面吃饭,吃完饭后朋友打开了一个小程序玩了起来...... 游戏长这样 大概玩法是:从地图中猫 ...

  7. python大牛 关东升_《Python从小白到大牛》第4章 Python语法基础

    本章主要为大家介绍Python的一些语法,其中包括标识符.关键字.常量.变量.表达式.语句.注释.模块和包等内容. 标识符和关键字 任何一种计算机语言都离不开标识符和关键字,因此下面将详细介绍Pyth ...

  8. python要学哪些_学python都要学哪些内容?

    如果培训都是分五个阶段,第一阶段学习Python核心编程,主要是Python语言基础.Linux.MySQL,前期学习Python编程语言基础内容;中期主要涉及OOP基础知识,学习后应该能自己处理OO ...

  9. python之禅 中文_《Python之禅》中对于Python编程过程中的一些建议

    <Python之禅>中对于Python编程过程中的一些建议 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  <Python之禅>中对于Pyt ...

  10. python什么是数据结构_〖Python〗-- 数据结构

    [数据结构] 什么是数据结构? 定义:简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中.比如:列表.集合与字典等都是一种数据结构. PS:"程序=数据结构+算法" 列表 ...

最新文章

  1. php开源文件管理,搭建php开源的文件管理器eXtplorer
  2. 文件包含中过滤了php,文件包含漏洞---php协议
  3. 最短路径 - 迪杰斯特拉(Dijkstra)算法
  4. vsftpd虚拟用户和本地用户不能共存的解决方法
  5. 深度学习(六)——CNN进化史
  6. Vue3---安装Element-Plus组件库
  7. Shadow Defender 语言文件并注册
  8. 美国大学计算机与信息科学,【计算机学术讲堂】美国福特汉姆大学计算机与信息科学系Md Zakirul Alam Bhuiyan博士莅临我院作学术报告...
  9. Linux系统修改远程连接22端口
  10. 凸优化有关的数值线性代数知识四:分块消元与Schur补
  11. 基于肌电信号(sEMG) 的深度学习手势分类
  12. 为什么Word打印预览的跟实际的不一样呢
  13. SPSS 26下载与安装
  14. SATA工作模式咋选?揭秘AHCI和IDE区别(1)
  15. c#语言打印九九乘法表,C#打印九九乘法表
  16. PYTHON Fraction 分数处理
  17. Thinkphp重复字段过滤
  18. 猴王问题(项目分析以及项目实现)
  19. Git报错Kex_exchange_identification
  20. web页面中如何唤起打开APP

热门文章

  1. JDK 14 Rampdown:内部版本27
  2. JDBC –模拟序列
  3. 什么是JavaServer Faces(JSF)
  4. 使用Docker堆栈部署的微服务-WildFly,Java EE和Couchbase
  5. 使用Junit和Easytest进行数据驱动的测试
  6. hibernate jpa_教程:Hibernate,JPA –第1部分
  7. Gradle入门:创建Web应用程序项目
  8. 好的微服务架构=企业服务总线(ESB)的灭亡?
  9. 当字符串为空但不为空时
  10. 预留空间过大的OutOfMemoryError