这题写了几天。收获不少。
用堆实现的优先队列的层次结构。
堆还是第一次应用。即能以LOG2N,进行插入删除操作。又不会象二叉搜索树那样会退化。比用平衡树方便的多。还有二分查找的效率!真是 好东西呀!
FOR循环上写了个STRLEN,百万次循环,时间耗费不少。这错误也托了我好几小时!遇到大数据还是要慎重啊!
还有就是那2个函数S=1时的特例处理。
最后2秒过的。呵呵。
附代码。看有写人不到1秒就过了。不知道还能如何优化?
#include <stdio.h>
#include <iostream>
#include <string.h>
struct orders 
...{
int begin;
int num;
orders *next;
};
struct heapball
...{
int num;
char colo;
struct chainball *tochain;
orders *beginorder,*endorder;
};
struct chainball 
...{
int num;
char colo;
int toheap;
struct chainball *next,*fro;
orders *beginorder,*endorder;
};
struct heapball heap[1000001];
int heapnum;
char ch[1000000];
struct chainball *head;
inline int heapdown(int s)
...{ int j;
heapball temp;
temp=heap[s];
for (j=s*2;j<=heapnum;j*=2)
...{
if ((j<heapnum)&&((heap[j+1].num>heap[j].num)||((heap[j+1].num==heap[j].num)&&(heap[j+1].beginorder->begin<heap[j].beginorder->begin))))
...{
j++;
}
if ((temp.num>heap[j].num)||((temp.num==heap[j].num)&&(temp.beginorder->begin<heap[j].beginorder->begin)))
...{
break;
}
heap[s]=heap[j];
heap[j].tochain->toheap=s;
s=j;
}
heap[s]=temp;
temp.tochain->toheap=s;
return s;


}

inline int heapup(int s)
...{
heapball temp;int j;
temp=heap[s];
j=s/2;
while (j!=0)
...{
if ((heap[j].num<temp.num)||((heap[j].num==temp.num)&&(heap[j].beginorder->begin>temp.beginorder->begin)))
...{
heap[s]=heap[j];
heap[j].tochain->toheap=s;
s=j;
j=j/2;
}
else
...{
break;
}
}
heap[s]=temp;
temp.tochain->toheap=s;
return s;
}


inline int insert(heapball newball)
...{
heapnum++;
heap[heapnum]=newball;
if (heapnum==1)
...{
return 1;
}
else
...{
return(heapup(heapnum));
}
}
inline void erase(int s)
...{int f;
heap[s]=heap[heapnum];
heapnum--;
if (s!=1)
...{
f=s/2;
if ((heap[f].num<heap[s].num)||((heap[f].num==heap[s].num)&&(heap[f].beginorder->begin>heap[s].beginorder->begin)))
...{
heapup(s);
}
else
...{
heapdown(s);
}
}
else
...{
heapdown(s);
} 
}
inline void output_max()
...{int i;chainball *p,*pf,*pn,*tempchain;heapball tempheap;
printf("%c",heap[1].colo);
while (heap[1].beginorder!=NULL)
...{
for (i=0;i<heap[1].beginorder->num;i++)
...{
printf(" %d",heap[1].beginorder->begin+i);
}
heap[1].beginorder=heap[1].beginorder->next;
}
p=heap[1].tochain;
heap[1]=heap[heapnum];
heapnum--;
heapdown(1);

if ((p->fro!=NULL)&&(p->next!=NULL))
...{
pf=p->fro;
pn=p->next;
if (pf->colo==pn->colo)
...{
tempchain=new chainball;
if (pf->fro!=NULL) pf->fro->next=tempchain;
if (pn->next!=NULL) pn->next->fro=tempchain;
tempchain->colo=pf->colo;
tempchain->num=pf->num+pn->num;
tempchain->fro=pf->fro;
tempchain->next=pn->next;
tempchain->beginorder=pf->beginorder;
pf->endorder->next=pn->beginorder;
tempchain->endorder=pn->endorder;
tempheap.colo=pf->colo;
tempheap.num=tempchain->num;
tempheap.beginorder=tempchain->beginorder;
tempheap.endorder=tempchain->endorder;
tempheap.tochain=tempchain;
erase(pf->toheap);
free(pf);
erase(pn->toheap);
free(pn);
tempchain->toheap=insert(tempheap);
}
pf->next=pn;
pn->fro=pf;
}
else
...{
if (p->fro==NULL)
...{
if (p->next!=NULL) p->next->fro=NULL;
}
else
...{
p->fro->next=NULL;
}
}
free(p);
}



void construct()
...{
int i,l;
orders *orp;
chainball * p,*pf;
scanf("%s",ch);
p=new chainball;
orp=new orders;
p->colo=ch[0];
p->num=1;
orp->num=1;
orp->begin=1;
p->beginorder=orp;
p->endorder=orp;
p->toheap=1;
pf=p;
head=p;
head->fro=NULL;
heapnum=1;
heap[1].colo=ch[0];
heap[1].num=1;
heap[1].tochain=p;
heap[1].beginorder=orp;
heap[1].endorder=orp;
heap[1].beginorder->next=NULL;
l=strlen(ch);
for (i=1;i<l;i++)
...{
if (ch[i]==pf->colo)
...{
pf->num++;
}
else
...{
p=new chainball;
heapnum++;
orp=new orders;
p->colo=ch[i];
heap[heapnum].colo=ch[i];
p->num=1;
heap[heapnum].beginorder=orp;
p->beginorder=orp;
heap[heapnum].endorder=orp;
p->endorder=orp;
heap[heapnum].num=1;
p->num=1;
heap[heapnum].beginorder->begin=i+1;
p->beginorder->begin=i+1;
heap[heapnum].beginorder->next=NULL;
p->beginorder->next=NULL;
heap[heapnum-1].num=pf->num;
heap[heapnum-1].beginorder->num=pf->num;
pf->beginorder->num=pf->num;
pf->next=p;
p->fro=pf;
heap[heapnum].tochain=p;
p->toheap=heapnum;
pf=p;
}
}
pf->next=NULL;
heap[heapnum].num=pf->num;
heap[heapnum].beginorder->num=pf->num;
pf->beginorder->num=pf->num;
heap[heapnum].beginorder->next=NULL;
pf->beginorder->next=NULL;
for (i=heapnum/2;i>=1;i--)
...{
heapdown(i);
}
}
void main()
...{
construct();
while ((!(heap[1].num==1))&&(heapnum>0))
...{
output_max();
if ((!(heap[1].num==1))&&(heapnum>0)) printf(" ");
else printf(" ");
}
}
本文分享了一种使用堆来实现优先队列的方法,并详细介绍了其层次结构。通过该实现方式,可在对数时间内完成插入和删除操作,避免了二叉搜索树可能产生的退化问题。文中还提到了在大量数据处理过程中遇到的性能瓶颈及优化经验。
1215

被折叠的 条评论
为什么被折叠?



