栈的封装
栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),
如上图所示:
允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素时称为“空栈”。向一个栈内插入元素称为是进栈,push;从一个栈删除元素称为是出栈,pop。
#从图中能看出需要后进先出!
先定义出入栈的函数:
class Stack(object):
def __init__(self):
self.stack = []
def push(self,value): #入栈
self.stack.append(value)
print(f"入栈元素是{value}")
def pop(self):"""出栈"""
if self.is_empty():
raise Exception('栈为空')
item = self.stack.pop()
print(f"出栈元素是{item}")
return item
def is_empty(self):
return len(self.stack) == 0
def top(self):
if self.is_empty():
raise Exception('栈为空')
return self.stack[-1]
def __len__(self):
return len(self.stack)
在赋值输出
if __name__ == '__main__':
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(len(stack))
stack.pop()
print(stack.is_empty())
print(stack.top())
组合在一起执行如下:
案例:队列的封装
队列和栈不同:
队列是限制在一端进行插入操作和另一端删除操作的线性表,允许进行插入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”,当队列中没有元素时称为“空队”。
class Queue(object):
def __init__(self):
self.queue = []
def enqueue(self,value):
self.queue.insert(0,value)
print(f"入队元素是{value}")
def dequeue(self):
"""出队"""
if self.is_empty():
raise Exception('队列为空')
item = self.queue.pop()
print("出队元素为{item}")
return item
def __len__(self):
return len(self.queue)
def first(self):
if self.is_empty():
raise Exception('队列为空')
return self.queue[-1]
def is_empty(self):
return len(self.queue) == 0
def last(self):
if self.is_empty():
raise Exception('队列为空')
return self.queue[0]
if __name__ == '__main__':
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.is_empty())
queue.dequeue()
queue.dequeue()
print(queue.first())
print(queue.last())
执行结果如下:
案例:二叉树的封装
二叉树的介绍:
二叉树是树的特殊一种,具有如下特点:1、每个结点最多有两颗子树,结点的度最大为2。2、左子树和右子树是有顺序的,次序不能颠倒。3、即使某结点只有一个子树,也要区分左右子树。
斜树
所有的结点都只有左子树(左斜树),或者只有右子树(右斜树)。这就是斜树,应用较少
满二叉树
所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树。就是完美圆满的意思,关键在于树的平衡。
完全二叉树
对一棵具有n个结点的二叉树按层序排号,如果编号为i的结点与同样深度的满二叉树编号为i结点在二叉树中位置完全相同,就是完全二叉树。满二叉树必须是完全二叉树,反过来不一定成立。
其中关键点是按层序编号,然后对应查找。
二叉树
操作如下:
先对于节点的左右进行赋值:
class Node(object):
def __init__(self, val=None, left=None, right=None):
self.val = val
self.left = left
self.right = right
接着封装二叉树:
把先中后的左右都要遍历:
把树形图结构先弄出来:
class BinaryTree(object):
def __init__(self, root):
self.root = root
def pre_travel(self, root):
if (root != None):
print(root.val)
self.pre_travel(root.left)
self.pre_travel(root.right)
def in_travel(self, root):
if (root != None):
self.in_travel(root.left)
print(root.val)
self.in_travel(root.right)
def last_travel(self, root):
if (root != None):
self.last_travel(root.left)
self.last_travel(root.right)
print(root.val)
接下来的部分需要做判断:
定义变量节点的数字:
if __name__ == '__main__':
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node7 = Node(7)
node8 = Node(8)
node9 = Node(9)
node10 = Node(10)
然后赋值:
我们可以看到赋值的时候:
给1节点的分支左右赋值为2,3
给2节点的分支左右赋值为4,5
给3节点的分支左右赋值为6,7
给4节点的分支左右赋值为8,9
给5节点的分支左右赋值为10
bt = BinaryTree(root=node1)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right= node5
node3.left = node6
node3.right = node7
node4.left = node8
node4.right = node9
node5.left = node10
node5.left = node11 #这里不需要若节点
给定遍历的数字:
bt.pre_travel(node1)
如下图:
可以看到若是
bt.pre_travel(node1)那么输出的是所有节点的数字:
bt.pre_travel(node2)那么输出的是2节点下的数字:
bt.pre_travel(node5)那么输出的是5节点下的数字:
依次以此类推,就可以输出相应结点的数字!!