当前位置:   article > 正文

栈和队列—Python实现基本操作_python栈与队列的基本用法

python栈与队列的基本用法

目录

概述

应用

栈抽象数据类型

栈的顺序表实现

栈的链表实现

栈的应用

队列

栈抽象数据类型

队列的list实现

队列的链表实现


概述

        栈和队列都是保存数据元素的容器。这两种结构支持的元素访问操作包括存入、查看、元素弹出。栈和队列主要用于在计算过程中保存临时数据,这些数据是计算中发现或者产生的,在后面的计算中可能需要使用它们。

        栈和队列也是最简单的缓存结构,它们只支持数据项的存储和访问,不支持数据项之间的任何关系,因此栈和队列的实现结构只需要保证元素存入和取出的顺序,并不需要记录和保证新存入的元素和容器中已有元素之间的任何关系。

  • 栈是后进先出关系结构,简称LIFO(Last In First Out)结构
  • 队列时先进先出关系结构,简称FIFO(First In First Out)结构

应用

栈和队列是计算中使用最广泛的缓存结构:

  • 计算过程分为一些顺序进行的步骤
  • 计算中执行的某些步骤会不断产生一些后面可能需要的中间数据
  • 产生的数据中有些不能立即使用,但又需要在将来使用
  • 需要保存的数据的项数不能事先确定

栈(stack)是一种容器,可存入、访问、删除数据元素。栈的基本性质保证,在任何时刻可以访问、删除的元素都是在此之前最后存入的那个元素。

抽象数据类型

  1. Stack:
  2. Stack(self) # 创建空栈
  3. is_empty(self) # 栈是否为空,True/False
  4. push(self, elem) # 将元素elem加入栈
  5. pop(self) # 删除栈最后压入的元素并将其返回
  6. top(self) # 取得栈最后压入的元素,不删除

栈的顺序表实现

  1. class StackUnderflow(ValueError): # 栈下溢(空栈访问)
  2. pass
  3. class SStack():
  4. """
  5. 基于顺序表实现栈类,用list对象_elems存储栈中元素,所有栈操作映射到list操作
  6. """
  7. def __init__(self):
  8. self._elems = []
  9. def is_empty(self):
  10. return self._elems == []
  11. def top(self):
  12. if self._elems == []:
  13. raise StackUnderflow("in top")
  14. return self._elems[-1]
  15. def push(self, elem):
  16. self._elems.append(elem)
  17. def pop(self):
  18. if self._elems == []:
  19. raise StackUnderflow("in pop")
  20. return self._elems.pop()
'
运行

栈的链表实现

  1. class LNode:
  2. def __init__(self, elem, next_=None):
  3. self.elem = elem
  4. self.next = next_
  5. class LStack():
  6. """
  7. 基于链表实现,用LNode作为结点
  8. """
  9. def __init__(self):
  10. self._top = None
  11. def is_empty(self):
  12. return self._top is None
  13. def top(self):
  14. if self._top is None:
  15. raise StackUnderflow("in top")
  16. return self._top.elem
  17. def push(self, elem):
  18. self._top = LNode(elem, self._top)
  19. def pop(self):
  20. if self._top is None:
  21. raise StackUnderflow("in pop")
  22. p = self._top
  23. self._top = p.next
  24. return p.elem
'
运行

栈的应用

1、括号匹配问题

思路:

  • 顺序扫描被检查正文(一个字符串)里的一个个字符
  • 检查中跳过无关字符(所有非括号字符都与当前处理无关)
  • 遇到开括号时将其压入栈
  • 遇到闭括号时弹出当时的栈顶元素与之匹配
  • 如果匹配成功则继续,发现不匹配时检查以失败结束
  1. def check_parens(text):
  2. """括号配对检查函数"""
  3. parens = "()[]{}"
  4. open_parens = "([{"
  5. opposite = {")": "(", "]": "[", "}": "{"} # 配对关系
  6. def parentheses(text):
  7. """括号生成器,每次调用返回text里的下一个括号和位置"""
  8. i, text_len = 0, len(text)
  9. while True:
  10. while i < text_len and text[i] not in parens:
  11. i += 1
  12. if i >= text_len:
  13. return
  14. yield text[i], i
  15. i += 1
  16. st = SStack()
  17. for paren, i in parentheses(text):
  18. if paren in open_parens:
  19. st.push(paren)
  20. elif st.pop() != opposite[paren]:
  21. print("Not matching is found at", i, "for", paren)
  22. return False
  23. # else: 配对成功,什么也不做,继续
  24. print("All parentheses are correctly matched.")
  25. return True
'
运行

队列

栈抽象数据类型

  1. Queue:
  2. Queue(self) # 创建空队列
  3. is_empty(self) # 队列是否为空,True/False
  4. enqueue(self, elem) # 将元素elem加入队列
  5. dequeue(self) # 删除队列里最早进入的元素并将其返回
  6. peek(self) # 查看队列里最早进入的元素,不删除

队列的list实现

  1. class QueueUnderFlow(ValueError):
  2. pass
  3. class SQueue():
  4. def __init__(self, init_len=8):
  5. self._len = init_len
  6. self._elems = [0] * init_len
  7. self._head = 0
  8. self._num = 0
  9. def is_empty(self):
  10. return self._num == 0
  11. def peek(self):
  12. if self._num == 0:
  13. raise QueueUnderFlow
  14. return self._elems[self._head]
  15. def dequeue(self):
  16. if self._num == 0:
  17. raise QueueUnderFlow
  18. e = self._elems[self._head]
  19. self._head = (self._head + 1) % self._len
  20. self._num -= 1
  21. return e
  22. def enqueue(self, e):
  23. if self._num == self._len:
  24. self.__extend() # 将存储去长度加倍
  25. self._elems[(self._head + self._num) % self._len] = e
  26. self._num += 1
  27. def __extend(self):
  28. old_len = self._len
  29. self._len *= 2
  30. new_elems = [0] * self._len
  31. for i in range(old_len):
  32. new_elems[i] = self._elems[(self._head + 1) % old_len]
  33. self._elems, self._head = new_elems, 0
'
运行

队列的链表实现

        链表实现队列操作没有实质性技术困难。由于需要在链接表的两端操作,从一端插入元素,从另一端删除。最简单的单链表只支持首端高效操作,在另一端操作需要O(n)时间,不适合作为队列的实现基础。带尾端指针的单链表,它支持O(1)时间的尾端插入操作。

        有了尾指针,尾端加入元素是O(1)时间操作,可以用作队列的入队操作enqueue。首端访问和删除都是O(1)时间操作,分别看作队列的peek和dequeue。实现单链表的技术可以直接用于队列,只需要修改几个名字。

  1. class LNode:
  2. def __init__(self, elem, next_=None):
  3. self.elem = elem
  4. self.next = next_
  5. class QueueUnderFlow(ValueError):
  6. pass
  7. class LQueue():
  8. def __init__(self):
  9. self._head = None
  10. self._rear = None
  11. def is_empty(self):
  12. return self._head is None
  13. def enqueue(self, elem):
  14. if self._head is None:
  15. self._head = LNode(elem, self._head)
  16. self._rear = self._head
  17. else:
  18. self._rear.next = LNode(elem)
  19. self._rear = self._rear.next
  20. def dequeue(self):
  21. if self._head is None: # 无结点,引发异常
  22. raise StackUnderflow("in dequeue")
  23. e = self._head.elem
  24. self._head = self._head.next
  25. return e
  26. def peek(self):
  27. if self._head is None: # 无结点,引发异常
  28. raise StackUnderflow("in peek")
  29. return self._head.elem
'
运行

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号