标签:一个队列 指定 为什么 code add 顺序 img tle 搬迁
特性:先进后出的数据结构,有栈顶和栈尾
应用场景:每个 web 浏览器都有一个返回按钮。浏览网页时,这些网页被放置在一个栈中(实际是网页的网址)。现在查看的网页在顶部,第一个查看的网页在底部。如果按‘返回’按钮,将按相反的顺序浏览刚才的页面。
栈的方法:
Stack():创建一个空的新栈。 它不需要参数,并返回一个空栈。
push(item):将一个新项添加到栈的顶部。它需要 item 做参数并不返回任何内容。
pop():从栈中删除顶部项。它不需要参数并返回 item 。栈被修改。
peek():从栈返回顶部项,但不会删除它。不需要参数。 不修改栈。
isEmpty():测试栈是否为空。不需要参数,并返回布尔值。
size():返回栈中的 item 数量。不需要参数,并返回一个整数。
列表实现一个栈
class Stack():
def __init__(self):
self.items = []
def push(self,item):
""" 栈顶添加 """
self.items.append(item)
def pop(self):
""" 栈顶删除 """
return self.items.pop()
def peek(self):
""" 查看栈顶元素 """
return self.items[-1]
def isEmpty(self):
""" 查看栈是否为空 """
return self.items == []
def size(self):
""" 查看栈中元素个数 """
return len(self.items)
特性:先进先出的数据结构
应用场景:计算机实验室有 30 台计算机与一台打印机联网。当学生想要打印时,他们的打印任务与正在等待的所有其他打印任务“一致”。第一个进入的任务是先完成。如果你是最后一个,你必须等待你前面的所有其他任务打印
队列的方法:
Queue():创建一个空的新队列。 它不需要参数,并返回一个空队列。
enqueue(item):将新项添加到队尾。 它需要 item 作为参数,并不返回任何内容。
dequeue():从队首移除项。它不需要参数并返回 item。 队列被修改。
isEmpty():查看队列是否为空。它不需要参数,并返回布尔值。
size():返回队列中的项数。它不需要参数,并返回一个整数。
列表实现一个队列
class Queue():
def __init__(self):
self.items = []
def enqueue(self,item):
""" 队列尾部添加元素 """
self.items.insert(0,item)
def dequeue(self):
""" 删除队列头部的元素 """
return self.items.pop()
def isEmpty(self):
""" 查看队列是否为空 """
return self.items == []
def size(self):
""" 查看队列中元素的个数 """
return len(self.items)
队列应用示例:
烫手的山芋
1.烫手山芋游戏介绍:
6个孩子围城一个圈,排列顺序孩子们自己指定。第一个孩子手里有一个烫手的山芋,需要在计时器计时1秒后将山芋传递给下一个孩子,依次类推。规则是,在计时器每计时7秒时,手里有山芋的孩子退出游戏。该游戏直到剩下一个孩子时结束,最后剩下的孩子获胜。请使用队列实现该游戏策略,排在第几个位置最终会获胜。
2.提取有价值的信息:
计时1s的时候山芋在第一个孩子手里面
山芋会被1s传递一次
7秒钟山芋被传递了6次
准则:保证第一个(队头)孩子手里面永远要有山芋,山芋不动、人动
kids = ['A','B','C','D','E','F']
q = Queue()
for kid in kids:
q.enqueue(kid)
while q.size() > 1: # 当队列中孩子的个数大于1游戏继续否则游戏结束
for i in range(1,7): # 山芋传递的次数
kid = q.dequeue() # 对头元素出队列再入队列
q.enqueue(kid)
q.dequeue() # 一轮游戏结束后,将对头孩子淘汰(对头孩子手里永远有山芋)
print(q.dequeue())
特性:同队列相比,有两个头部和尾部。可以在双端进行数据的插入和删除,提供了单数据结构中栈和队列的特性
双端队列的方法:
Deque():创建一个空的新 deque。它不需要参数,并返回空的 deque。
addFront(item):将一个新项添加到 deque 的首部。它需要 item 参数 并不返回任何内容。
addRear(item):将一个新项添加到 deque 的尾部。它需要 item 参数并不返回任何内容。
removeFront():从 deque 中删除首项。它不需要参数并返回 item。deque 被修改。
removeRear():从 deque 中删除尾项。它不需要参数并返回 item。deque 被修改。
isEmpty():测试 deque 是否为空。它不需要参数,并返回布尔值。
size():返回 deque 中的项数。它不需要参数,并返回一个整数。
列表实现双端队列
class Deque:
def __init__(self):
self.items = []
def addFront(self,item):
""" 双端队列头部添加 """
self.items.insert(0,item)
def addRear(self,item):
""" 双端队列尾部添加 """
self.items.append(item)
def removeFront(self):
""" 双端队列头部删除 """
return self.items.pop(0)
def removeRear(self):
""" 双端队列尾部删除 """
return self.items.pop()
def isEmpty(self):
""" 查看双端队列是否为空 """
return self.items == []
def size(self):
""" 查看双端队列元素的个数 """
return len(self.items)
双端队列应用示例:判断一个字符串是否是回文
deque = Deque()
def huiwen(s):
for i in s:
deque.addFront(i)
while deque.size() > 1:
if deque.removeRear() != deque.removeFront():
print('不是回文')
return
print('是回文')
huiwen('12321')
形象化理解内存(内存的大小和地址)
1.开辟好的内存空间会有两个默认的属性:大小,地址
2.大小:衡量该块内存能够存储数据的大小
- bit(位):只可以存放一位二进制的数
- byte(字节):8bit
- kb:1024byte
- 10Mb:10*1024*1024*8
- 作用:可以衡量该内存存储数据大小的范围
3.地址:16进制的数表示
- 作用:定位内存空间的位置
- 变量/引用:内存空间的地址
变量的概念
1.引用==变量,变量就是我们为存储数据单独开辟的内存空间。
2.理解a=10的内存图(指向)
如果一个变量表示的是某一块内存空间的地址,则该变量指向该块内存空间。
如果一个变量指向了某一块内存空间,则该变量就可以代替/表示这块内存中存储的数值
不同数据占用内存空间的大小
整数:4字节
浮点型:float:4字节,double:8字节
字符型(char):1字节
顺序表的结构可以分为两种形式:单数据类型和多数据类型;python中的列表和元组就属于多数据类型的顺序表
单数据类型顺序表的内存图(内存连续开启),以数组为例:
多数据类型顺序表的内存图(内存非连续开辟),以列表为例:
顺序表的弊端
顺序表的结构需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁。
链表简述:
1.链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是每一个结点(数据存储单元)里存放下一个结点的信息(即地址)
2.相对于顺序表,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理且进行扩充时不需要进行数据搬迁。
链表的方法:
is_empty():链表是否为空
length():链表长度
travel():遍历整个链表
add(item):链表头部添加元素
append(item):链表尾部添加元素
insert(pos, item):指定位置添加元素
remove(item):删除节点
search(item):查找节点是否存在
代码实现
class Node():
""" 初始化一个节点 """
def __init__(self,item):
self.item = item # 存储数值数据
self.next = None # 存储下一个节点的地址
class Link():
""" 构建一个空链表 """
def __init__(self):
self._head = None # _head要指向第一个节点,如果没有节点则指向None
def add(self,item):
""" 链表头部添加元素 """
node = Node(item) # 1.创建一个新节点
node.next = self._head # 2.将创建新节点的next指向,指向原来的第一个节点
self._head = node # 3.将链表的_head指向新创建的节点
def travel(self):
""" 遍历链表 """
# 在非空的链表中head永远要指向第一个节点的地址,永远不要修改它的指向,否则会造成数据的丢失
cur = self.__head
while cur:
print(cur.item)
cur = cur.next
def is_empty(self):
""" 判断链表是否为空 """
return self._head == []
def length(self):
""" 查看链表的长度 """
count = 0 # 记录节点的个数
cur = self.__head
while cur:
count += 1
cur = cur.next
return count
def append(self,item):
""" 在链表的尾部添加元素 """
node = Node(item)
cur = self._head # 当前结点
pre = None # 指向cur的前一个节点
if self._head = None: # 如果链表为空则需要单独处理
self._head = node
return
while cur:
pre = cur
cur = cur.next # 循环结束之后cur指向了None,pre指向了最后一个节点
pre.next = node
def search(self,item):
""" 在链表中查找元素 """
cur = self._head
find = False
while cur:
if cur.item == item:
find = True
break
else:
cur = cur.next
return find
def insert(self,pos,item):
""" 在链表中插入元素 """
node = Node(item)
cur = self._head
pre = None
# 如果插入的位置大于链表的长度,则默认插入到尾部
if pos > self.items.length()-1:
self.append(item)
return
for i in range(pos):
pre = cur
cur = cur.next
pre.next = node
node.next = cur
def remove(self,item):
""" 移除指定的元素 """
cur = self._head
pre = None
if item == cur.item:
self._head = cur.next
return
while cur:
if cur.item != item:
pre = cur
cur = cur.next
else:
break
pre.next = cur.next
链表结构内存图:
链表头部添加(add)内存图:
链表插入(insert)内存图:
二叉树概述:
二叉树组成:根节点,叶子节点
2.子树:左右叶子节点都有就是完整子树、只有单个的节点的就是不完整的子树
3.结论:
二叉树的遍历
广度遍历:逐层遍历
深度遍历:纵向遍历,前中后表示的是子树种根节点的位置
一定要基于子树去遍历
前序遍历:根左右
中序遍历:左根右
后序遍历:左右根
为什么用深度遍历:要结合排序二叉树一起使用,深度遍历可以帮我们二叉树进行排序。
普通二叉树实现:
class Node():
def __init__(self,item):
self.item = item
self.left = None
self.right = None
class Tree():
# 构建一棵空树
def __init__(self):
self.root = None
def add(self,item):
""" 插入节点 """
if self.root == None: # 向空树中插入第一个节点
node = Node(item)
self.root = node
return
else: # 向非空的二叉树中插入一个节点
node = Node(item)
cur = self.root # 防止根节点指向改变
queue = [cur]
while queue:
root = queue.pop(0)
if root.left != None:
queue.append(root.left)
else:
root.left = node
break
if root.right != None:
queue.append(root.right)
else:
root.right = node
break
# 广度遍历
def travel(self):
""" 遍历二叉树 """
cur = self.root
queue = [cur]
if self.root == None:
print('')
return
while queue:
root = queue.pop(0)
print(root.item)
if root.left != None:
queue.append(root.left)
if root.right != None:
queue.append(root.right)
# 深度遍历
def forward(self,root):
""" 前序遍历 """
if root == None:
return
print(root.item)
self.forward(root.left)
self.forward(root.right)
def middle(self,root):
""" 中序遍历 """
if root == None:
return
self.middle(root.left)
print(root.item)
self.middle(root.right)
def back(self,root):
""" 后序遍历 """
if root == None:
return
self.back(root.left)
self.back(root.right)
print(root.item)
排序二叉树实现:
# 排序二叉树
class SortTree():
def __init__(self):
self.root = None
def add(self,item):
node = Node(item)
cur = self.root
if self.root == None:
self.root = node
return
while True:
# 插入节点的值小于根节点的值,往根节点左侧插
if node.item < cur.item:
if cur.left == None:
cur.left = node
break
else:
cur = cur.left
else: # 插入节点的值大于根节点,往根节点右侧插
if cur.right == None:
cur.right = node
break
else:
cur = cur.right
def middle(self,root):
""" 中序遍历 """
if root == None:
return
self.middle(root.left)
print(root.item)
self.middle(root.right)
tree = SortTree()
alist = [3,8,4,6,7,8]
for i in alist:
tree.add(i)
tree.middle(tree.root)
标签:一个队列 指定 为什么 code add 顺序 img tle 搬迁
原文地址:https://www.cnblogs.com/liubing8/p/12059431.html