使用python实现数组、链表、队列、栈的方法


Posted in Python onDecember 20, 2019

引言

什么是数据结构?

  • 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。
  • 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中。
  • 比如:列表,集合和字典等都是数据结构
  • N.Wirth:“程序=数据结构+算法”

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

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

数组

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

实现

class Array(object):
 def __init__(self, size=32):
  """
  :param size: 长度
  """
  self._size = size
  self._items = [None] * size

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

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

 # 在执行len(array) 时执行
 def __len__(self):
  return self._size
 
 # 清空数组
 def clear(self, value=None):
  for i in range(len(self._items)):
   self._items[i] = value

 # 在遍历时执行
 def __iter__(self):
  for item in self._items:
   yield item

使用

a = Array(4)
a[0] = 1
print(a[0]) # 1

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

a[0] = 1
a[1] = 2
a[3] = 4
for i in a:
 print(i) # 1, 2, None, 4

链表

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

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

使用python实现数组、链表、队列、栈的方法

实现

class Node(object):
 def __init__(self, value=None, next=None):
  self.value, self.next = value, next

class LinkedList(object):
 def __init__(self, size=None):
  """
  :param size: int or None, 如果None,则该链表可以无限扩充
  """
  self.size = size
  # 定义一个根节点
  self.root = Node()
  # 尾节点始终指向最后一个节点
  self.tail_node = None
  self.length = 0
 def __len__(self):
  return self.length
 def append(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 is None:
   # 还没有 append 过,length = 0, 追加到 root 后
   self.root.next = node
  else:
   # 否则追加到最后一个节点的后边,并更新最后一个节点是 append 的节点
   tail_node.next = node
  # 把尾节点指向node
  self.tail_node = node
  # 长度加一
  self.length += 1
 # 往左边添加
 def append_left(self, value):
  if self.size and len(self) >= self.size:
   raise Exception("LinkedList is full")
  # 构建节点
  node = Node(value)
  # 链表为空,则直接添加设置
  if self.tail_node is None:
   self.tail_node = node
  # 设置头节点为根节点的下一个节点
  head_node = self.root.next
  # 把根节点的下一个节点指向node
  self.root.next = node
  # 把node的下一个节点指向原头节点
  node.next = head_node
  # 长度加一
  self.length += 1
 # 遍历节点
 def iter_node(self):
  # 第一个节点
  current_node = self.root.next
  # 不是尾节点就一直遍历
  while current_node is not self.tail_node:
   yield current_node
   # 移动到下一个节点
   current_node = current_node.next
  # 尾节点
  if current_node is not None:
   yield current_node
 # 实现遍历方法
 def __iter__(self):
  for node in self.iter_node():
   yield node.value
 # 删除指定元素
 def remove(self, value):
  # 删除一个值为value的节点,只要使该节点的前一个节点的next指向该节点的下一个
  # 定义上一个节点
  perv_node = self.root
  # 遍历链表
  for current_node in self.iter_node():
   if current_node.value == value:
    # 把上一个节点的next指向当前节点的下一个节点
    perv_node.next = current_node.next
    # 判断当前节点是否是尾节点
    if current_node is self.tail_node:
     # 更新尾节点 tail_node
     # 如果第一个节点就找到了,把尾节点设为空
     if perv_node is self.root:
      self.tail_node = None
     else:
      self.tail_node = perv_node
    # 删除节点,长度减一,删除成功返回1
    del current_node
    self.length -= 1
    return 1
   else:
    perv_node = current_node
  # 没找到返回-1
  return -1
 # 查找元素,找到返回下标,没找到返回-1
 def find(self, value):
  index = 0
  # 遍历链表,找到返回index,没找到返回-1
  for node in self.iter_node():
   if node.value == value:
    return index
   index += 1
  return -1
 # 删除第一个节点
 def popleft(self):
  # 链表为空
  if self.root.next is None:
   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 is self.tail_node:
   self.tail_node = None
  # 长度减一,删除节点,返回该节点的值
  self.length -= 1
  del head_node
  return value
 # 清空链表
 def clear(self):
  for node in self.iter_node():
   del node
  self.root.next = None
  self.tail_node = None
  self.length = 0
 # 反转链表
 def reverse(self):
  # 第一个节点为当前节点,并把尾节点指向当前节点
  current_node = self.root.next
  self.tail_node = current_node
  perv_node = None
  while current_node:
   # 下一个节点
   next_node = current_node.next
   # 当前节点的下一个节点指向perv_node
   current_node.next = perv_node
   # 当前节点的下一个节点为空,则把根节点的next指向当前节点
   if next_node is None:
    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)) # []

循环链表

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

使用python实现数组、链表、队列、栈的方法

循环链表实现

class Node(object):
 def __init__(self, value=None, prev=None, next=None):
  self.value = value
  self.prev = prev
  self.next = next


class CircularDoubleLinkedList(object):
 """
 双向循环链表
 """

 def __init__(self, maxsize=None):
  self.maxsize = maxsize
  node = Node()
  node.prev = node
  node.next = node
  self.root = node
  self.length = 0

 def __len__(self):
  return self.length

 def head_node(self):
  return self.root.next

 def tail_node(self):
  return self.root.prev

 # 遍历
 def iter_node(self):
  if self.root.next is self.root:
   return
  current_node = self.root.next
  while current_node.next is not self.root:
   yield current_node
   current_node = current_node.next
  yield current_node

 def __iter__(self):
  for node in self.iter_node():
   yield node.value

 # 反序遍历
 def iter_node_reverse(self):
  if self.root.prev is self.root:
   return
  current_node = self.root.prev
  while current_node.prev is not self.root:
   yield current_node
   current_node = current_node.prev
  yield current_node

 def append(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() or self.root
  tail_node.next = node
  node.prev = tail_node
  node.next = self.root
  self.root.prev = node
  self.length += 1

 def append_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 is self.root:
   self.root.next = node
   node.prev = self.root
   node.next = self.root
   self.root.prev = node
  else:
   node.next = self.root.next
   self.root.next.prev = node
   self.root.next = node
   node.prev = self.root
  self.length += 1

 def remove(self, node):
  if node is self.root:
   return
  node.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)。

使用python实现数组、链表、队列、栈的方法

基于数组实现环形队列

class Array(object):
 def __init__(self, size=32):
  """
  :param size: 长度
  """
  self._size = size
  self._items = [None] * size

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

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

 # 在执行len(array) 时执行
 def __len__(self):
  return self._size
 
 # 清空数组
 def clear(self, value=None):
  for i in range(len(self._items)):
   self._items[i] = value

 # 在遍历时执行
 def __iter__(self):
  for item in self._items:
   yield item


class ArrayQueue(object):
 def __init__(self, maxsize):
  self.maxsize = maxsize
  self.array = Array(maxsize)
  self.head = 0
  self.tail = 0

 def __len__(self):
  return self.head - self.tail

 # 入队
 def push(self, value):
  if len(self) >= self.maxsize:
   raise Exception("Queue is full")
  self.array[self.head % self.maxsize] = value
  self.head += 1

 # 出队
 def pop(self):
  value = self.array[self.tail % self.maxsize]
  self.tail += 1
  return value

使用

size = 5
q = ArrayQueue(size)
for i in range(size):
 q.push(i)

print(len(q)) # 5

print(q.pop()) # 0
print(q.pop()) # 1

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

class Node(object):
 def __init__(self, value=None, prev=None, next=None):
  self.value = value
  self.prev = prev
  self.next = next


class CircularDoubleLinkedList(object):
 """
 双向循环链表
 """

 def __init__(self, maxsize=None):
  self.maxsize = maxsize
  node = Node()
  node.prev = node
  node.next = node
  self.root = node
  self.length = 0

 def __len__(self):
  return self.length

 def head_node(self):
  return self.root.next

 def tail_node(self):
  return self.root.prev

 # 遍历
 def iter_node(self):
  if self.root.next is self.root:
   return
  current_node = self.root.next
  while current_node.next is not self.root:
   yield current_node
   current_node = current_node.next
  yield current_node

 def __iter__(self):
  for node in self.iter_node():
   yield node.value

 # 反序遍历
 def iter_node_reverse(self):
  if self.root.prev is self.root:
   return
  current_node = self.root.prev
  while current_node.prev is not self.root:
   yield current_node
   current_node = current_node.prev
  yield current_node

 def append(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() or self.root
  tail_node.next = node
  node.prev = tail_node
  node.next = self.root
  self.root.prev = node
  self.length += 1

 def append_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 is self.root:
   self.root.next = node
   node.prev = self.root
   node.next = self.root
   self.root.prev = node
  else:
   node.next = self.root.next
   self.root.next.prev = node
   self.root.next = node
   node.prev = self.root
  self.length += 1

 def remove(self, node):
  if node is self.root:
   return
  node.next.prev = node.prev
  node.prev.next = node.next
  self.length -= 1
  return node


# 双向队列
class Deque(CircularDoubleLinkedList):
 # 从右边出队
 def pop(self):
  if len(self) <= 0:
   raise Exception("stark is empty!")
  tail_node = self.tail_node()
  value = tail_node.value
  self.remove(tail_node)
  return value

 # 从左边出队
 def popleft(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

双向队列

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

使用python实现数组、链表、队列、栈的方法

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

class Node(object):
 def __init__(self, value=None, prev=None, next=None):
  self.value = value
  self.prev = prev
  self.next = next


class CircularDoubleLinkedList(object):
 """
 双向循环链表
 """

 def __init__(self, maxsize=None):
  self.maxsize = maxsize
  node = Node()
  node.prev = node
  node.next = node
  self.root = node
  self.length = 0

 def __len__(self):
  return self.length

 def head_node(self):
  return self.root.next

 def tail_node(self):
  return self.root.prev

 # 遍历
 def iter_node(self):
  if self.root.next is self.root:
   return
  current_node = self.root.next
  while current_node.next is not self.root:
   yield current_node
   current_node = current_node.next
  yield current_node

 def __iter__(self):
  for node in self.iter_node():
   yield node.value

 # 反序遍历
 def iter_node_reverse(self):
  if self.root.prev is self.root:
   return
  current_node = self.root.prev
  while current_node.prev is not self.root:
   yield current_node
   current_node = current_node.prev
  yield current_node

 def append(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() or self.root
  tail_node.next = node
  node.prev = tail_node
  node.next = self.root
  self.root.prev = node
  self.length += 1

 def append_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 is self.root:
   self.root.next = node
   node.prev = self.root
   node.next = self.root
   self.root.prev = node
  else:
   node.next = self.root.next
   self.root.next.prev = node
   self.root.next = node
   node.prev = self.root
  self.length += 1

 def remove(self, node):
  if node is self.root:
   return
  node.next.prev = node.prev
  node.prev.next = node.next
  self.length -= 1
  return node


# 双向队列
class Deque(CircularDoubleLinkedList):
 # 从右边出队
 def pop(self):
  if len(self) <= 0:
   raise Exception("stark is empty!")
  tail_node = self.tail_node()
  value = tail_node.value
  self.remove(tail_node)
  return value

 # 从左边出队
 def popleft(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

使用python实现数组、链表、队列、栈的方法

基于双向队列实现

class Node(object):
 def __init__(self, value=None, prev=None, next=None):
  self.value = value
  self.prev = prev
  self.next = next


class CircularDoubleLinkedList(object):
 """
 双向循环链表
 """
 def __init__(self, maxsize=None):
  self.maxsize = maxsize
  node = Node()
  node.prev = node
  node.next = node
  self.root = node
  self.length = 0

 def __len__(self):
  return self.length

 def head_node(self):
  return self.root.next

 def tail_node(self):
  return self.root.prev

 # 遍历
 def iter_node(self):
  if self.root.next is self.root:
   return
  current_node = self.root.next
  while current_node.next is not self.root:
   yield current_node
   current_node = current_node.next
  yield current_node

 def __iter__(self):
  for node in self.iter_node():
   yield node.value

 # 反序遍历
 def iter_node_reverse(self):
  if self.root.prev is self.root:
   return
  current_node = self.root.prev
  while current_node.prev is not self.root:
   yield current_node
   current_node = current_node.prev
  yield current_node

 def append(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() or self.root
  tail_node.next = node
  node.prev = tail_node
  node.next = self.root
  self.root.prev = node
  self.length += 1

 def append_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 is self.root:
   self.root.next = node
   node.prev = self.root
   node.next = self.root
   self.root.prev = node
  else:
   node.next = self.root.next
   self.root.next.prev = node
   self.root.next = node
   node.prev = self.root
  self.length += 1

 def remove(self, node):
  if node is self.root:
   return
  node.next.prev = node.prev
  node.prev.next = node.next
  self.length -= 1
  return node


class Deque(CircularDoubleLinkedList):
 def pop(self):
  if len(self) <= 0:
   raise Exception("stark is empty!")
  tail_node = self.tail_node()
  value = tail_node.value
  self.remove(tail_node)
  return value

 def popleft(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


class Stack(object):
 def __init__(self):
  self.deque = Deque() 
 
 # 压栈
 def push(self, value):
  self.deque.append(value)

 # 出栈
 def pop(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 相关文章推荐
Python psutil模块简单使用实例
Apr 28 Python
初步解析Python下的多进程编程
Apr 28 Python
django实现登录时候输入密码错误5次锁定用户十分钟
Nov 05 Python
详解django.contirb.auth-认证
Jul 16 Python
Python实现购物评论文本情感分析操作【基于中文文本挖掘库snownlp】
Aug 07 Python
python把ipynb文件转换成pdf文件过程详解
Jul 09 Python
Python中的相关分析correlation analysis的实现
Aug 29 Python
Python面向对象之私有属性和私有方法应用案例分析
Dec 31 Python
基于Python绘制美观动态圆环图、饼图
Jun 03 Python
python获取百度热榜链接的实例方法
Aug 25 Python
python打包生成so文件的实现
Oct 30 Python
python连接mongodb数据库操作数据示例
Nov 30 Python
python隐藏类中属性的3种实现方法
Dec 19 #Python
Python合并2个字典成1个新字典的方法(9种)
Dec 19 #Python
关于Python中定制类的比较运算实例
Dec 19 #Python
在python中利用try..except来代替if..else的用法
Dec 19 #Python
Python字符串的修改方法实例
Dec 19 #Python
python中property和setter装饰器用法
Dec 19 #Python
python装饰器代替set get方法实例
Dec 19 #Python
You might like
了解Joomla 这款来自国外的php网站管理系统
2010/03/11 PHP
php基础学习之变量的使用
2011/06/09 PHP
php设计模式  Command(命令模式)
2011/06/17 PHP
Yii框架登录流程分析
2014/12/03 PHP
使用GDB调试PHP代码,解决PHP代码死循环问题
2015/03/02 PHP
[原创]php求圆周率的简单实现方法
2016/05/30 PHP
javascript 强制刷新页面的实现代码
2009/12/13 Javascript
jQuery实现的Email中的收件人效果(按del键删除)
2011/03/20 Javascript
js 函数调用模式小结
2011/12/26 Javascript
Prototype源码浅析 Number部分
2012/01/16 Javascript
JQuery切换显示的效果实例代码
2013/02/27 Javascript
浅谈checkbox的一些操作(实战经验)
2013/11/20 Javascript
javascript利用apply和arguments复用方法
2013/11/25 Javascript
IE6-8中Date不支持toISOString的修复方法
2014/05/04 Javascript
js实现每日自动换一张图片的方法
2015/05/04 Javascript
基于jQuery.Hz2Py.js插件实现的汉字转拼音特效
2015/05/07 Javascript
无刷新上传文件并返回自定义值
2015/06/11 Javascript
BootStrap Typeahead自动补全插件实例代码
2016/08/10 Javascript
js 原型对象和原型链理解
2017/02/09 Javascript
canvas实现爱心和彩虹雨效果
2017/03/09 Javascript
jQuery Ajax 实现分页 kkpager插件实例代码
2017/08/10 jQuery
Angular模版驱动表单的使用总结
2018/05/05 Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
2020/04/28 Javascript
python结合selenium获取XX省交通违章数据的实现思路及代码
2016/06/26 Python
TensorFlow实现Softmax回归模型
2018/03/09 Python
Python基于辗转相除法求解最大公约数的方法示例
2018/04/04 Python
Python3使用pandas模块读写excel操作示例
2018/07/03 Python
Selenium(Python web测试工具)基本用法详解
2018/08/10 Python
python 调试冷知识(小结)
2019/11/11 Python
Pytorch Tensor基本数学运算详解
2019/12/30 Python
浅谈Python3多线程之间的执行顺序问题
2020/05/02 Python
Python基于os.environ从windows获取环境变量
2020/06/09 Python
Linux如何为某个操作添加别名
2015/02/05 面试题
最新英语专业学生求职信范文
2013/09/21 职场文书
美丽乡村建设实施方案
2014/03/23 职场文书
党支部三会一课计划
2014/09/24 职场文书