福州培训之数据结构[队列,堆](2月8日)

今天其实讲了另外的东西,但我没听懂,所以不写了,把昨天的内容补一补,今天的之后自己体悟一下再来总结......

首先

队列:“先进先出”数据存取

队列顾名思义就像排队一样

更形象一点,就像只能容纳一个人的独木桥

队列是一种“先进先出”的容器

先存进队列的元素比后进队列的元素先取出

必须在先进队列的元素取出后,后入队的元素才可以取出

所以队列用于存取情况为“先进先出”的场景问题的数据存取。

比如解决提到的过独木桥的顺序问题,以及排队问题等。显然,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,结束

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值