今天其实讲了另外的东西,但我没听懂,所以不写了,把昨天的内容补一补,今天的之后自己体悟一下再来总结......
首先
队列:“先进先出”数据存取
队列顾名思义就像排队一样
更形象一点,就像只能容纳一个人的独木桥
队列是一种“先进先出”的容器
先存进队列的元素比后进队列的元素先取出
必须在先进队列的元素取出后,后入队的元素才可以取出
所以队列用于存取情况为“先进先出”的场景问题的数据存取。
比如解决提到的过独木桥的顺序问题,以及排队问题等。显然,BFS过程中的村塾也是用队列的思想
特点:
1.数据存在一个 数组,数组的大小即队列容量大小
2.用两个变量head和tail分别记录队首数据下标-1和队尾数据下标
3.以数组形式存放一个队列(int q[MAXSIZE];)
4.队空时head=tail
5.队满时tail=MAXSIZE-1(注意:和tail-head无关)
6.head为队首元素的下标-1.通过访问q[head+1]取队首元素。tail为队尾元素下标
给出一个容量为5的队列的例子:
将元素进,出队列:
1.访问当前队首的元素:q[head++]
2.新的元素x入队列:++tail;q[tail]=x;
3.队首元素出队列:++head;
然而,这很浪费空间,10哥元素,逐个入队,再逐个出队,再逐个入队,如此重复10000遍,所需空间就很大
队首出队只是队首下标+1,假装删除了队首,而实际上并没有真正释放空间
所以,改进!
普通的队列vs环形队列:
普通队列vs双端队列:
接下来
堆:
堆就是一个“父亲值比儿子值大”或“父亲值比儿子值小”的完全二叉树
堆实际上时一个序列{k1,k2,k3,......,kn},它满足条件:
当i=1,2,...,n/2时,k[i]<=k[2i]且k[i]<=k[2i+1];或
当i=1,2,...,n/2时,k[i]>=k[2i+1]且k[i]>=k[2i+1];
堆按照父亲和儿子数值的比较关系可分为“大根堆”和“小根堆”两种
堆在取序列最值功能上有出色的表现,
在已经生成好的堆上取序列最值操作的复杂度O(1),修改一个生成好的堆上的数据
的复杂度为O(logn),初始化生成一个堆也值需要O(nlogn)的时间
因此,堆很适合频繁地查找序列中的最大值的问题
去最值:
依照定义,堆结构种的第一个元素即最值
所以,要去堆H[]中的最值,直接访问H[1]即可获得,相当简单
调整:
建堆:
[code]
viod build()
{
int i;
for(i=N/2;i>=1;i--)
heapify(i);
}
删除队首元素:
[code]
void delete()
{
if(N==1)
N==0;
else
{
H[1]=H[N--];
heapify(1);
}
}
插入新元素:
[code]
void insert(int key)
{
int x=++N;
while(x>1)
{
if(key<H[x/2])
{
H[x]=H[x/2];
x/=2;
}
else
break;
}
}
ok,结束