①堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
·堆中某个节点的值总是不大于或不小于其父节点的值;
·堆总是一棵完全二叉树。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。
②堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。
③堆是应用程序在运行的时候请求操作系统分配给自己内存,一般是申请/给予的过程。
④堆是指程序运行时申请的动态内存,而栈只是指一种使用堆的方法(即先进后出)。
堆的应用:
#堆排序
def sift(li, left, right):
i = left
j = 2 * i + 1
tmp = li[left]
while j <= right:
if j+1 <= right and li[j] < li[j+1]:
j = j + 1
if tmp < li[j]:
li[i] = li[j]
i = j
j = 2 * i + 1
else:
break
li[i] = tmp
def heap_sort(li):
n = len(li)
for i in range(n//2-1, -1, -1): #建立堆
sift(li, i, n-1)
for i in range(n-1, -1, -1): #挨个出数
li[0], li[i] = li[i],li[0]
sift(li, 0, i-1)
li = [6,8,1,9,3,0,7,2,4,5]
heap_sort(li)
print(li)
栈:
①栈(stack)又名堆栈,一个数据集合,可以理解为只能在一端进行插入或删除操作的列表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
②栈就是一个桶,后放进去的先拿出来,它下面本来有的东西要等它出来之后才能出来(先进后出)
③栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有FIFO的特性,在编译的时候可以指定需要的Stack的大小。
栈的基本操作:
进栈(压栈):push
出栈:pop
取栈顶:gettop
用python实现堆栈
# 后进先出
class Stack():
def __init__(self,size):
self.size=size
self.stack=[]
self.top=-1
def push(self,x):
if self.isfull():
raise exception("stack is full")
else:
self.stack.append(x)
self.top=self.top+1
def pop(self):
if self.isempty():
raise exception("stack is empty")
else:
self.top=self.top-1
self.stack.pop()
def isfull(self):
return self.top+1 == self.size
def isempty(self):
return self.top == '-1'
def showStack(self):
print(self.stack)
s=Stack(10)
for i in range(5):
s.push(i)
s.showStack()
for i in range(3):
s.pop()
s.showStack()
"""
类中有top属性,用来指示栈的存储情况,初始值为1,一旦插入一个元素,其值加1,利用top的值乐意判定栈是空还是满。
执行时先将0,1,2,3,4依次入栈,然后删除栈顶的前三个元素
"""
栈的应用——括号匹配问题
括号匹配问题:给一个字符串,其中包含小括号、中括号、大括号,求该字符串中的括号是否匹配。例如:
()()[]{} 匹配
([{()}]) 匹配
[]( 不匹配
[(]) 不匹配
def kuohao_match(exp): stack = [] di = {'(':')', '{':'}', '[':']'} for c in exp: if c in {'(','{', '['}: stack.append(c) else: if len(stack) == 0: return False top = stack.pop() if di[top] != c: return False if len(stack) > 0: return False else: return True print(kuohao_match('()[]{([]][]}()'))