本周学习内容:
1.了解掌握了二叉树的存储,创建和遍历
2.学会了二叉搜索树(BST),做完了课后习题
3.看懂、学习了简单平衡二叉搜索树——Treap树
4.高精度计算
BST
1.每个元素的键值可以比较大小,将键值存放在BST的结点上
2.键值最大的结点没有右儿子,键值最小的结点没有左儿子
3.最坏的情况下,树的深度为n;最好的情况下,得到的左右子树完全平衡,深度为log2(n).
BST的关键在于运用算法努力使它保持平衡
eg:HDU 3999 “The order of a Tree”
#includeusing namespace std; const int N=100005; int tree[N],l[N],r[N],a[N]; int root,f,m; //root(根)的值为0,以tree[0]为根结点 // f的作用是去记录每个值出现的顺序,m是去控制遍历输出的顺序 void buildtree(int root,int x) { if(x<=tree[root]) { if(l[root]==-1) l[root]=f; //l[n],r[n]存放的是tree[n]的下标 else buildtree(l[root],x); //递归向下,存放左儿子 } else { if(r[root]==-1) r[root]=f; else buildtree(r[root],x); //递归向下,存放右儿子 } } void order(int root) //将建的树的值进行存储,递归赋给a[N] { a[m++]=tree[root]; if(l[root]!=-1) order(l[root]); if(r[root]!=-1) order(r[root]); } int main() { int n; while(cin>>n) { memset(l,-1,sizeof(l)); //都初始化为-1,方便之后的输出 memset(r,-1,sizeof(r)); root=-1;f=0; //根的值+1后,就没变过 for(int i=0;i >x; if(root==-1) tree[++root]=x; //作为根节点 else { tree[++f]=x; buildtree(root,x); //tree[0]为中心建树 } } m=0; order(root); for(int i=0;i Treap 树 1.treap树的插入和调整
优先级决定了元素的位置,优先级最高的为树根;而键值决定了元素作为左孩子或是右孩子。优先级高的利用左旋、右旋上升调整位置。
2.treap树的删除:若结点是叶子结点,则直接删除;若结点有子节点,那么找到优先级最大的子节点,向相反方向旋转,调整为叶子结点后删除。
(treap树的代码有点麻烦,有时对应STL容器解题会方便很多)eg:给出和尚们打架的顺序(P75)页
(灵活使用迭代器,map容器可根据键来进行升序排列)#includeusing namespace std; map mp; int main() { int n; while(cin>>n) { mp.clear(); mp[1e9]=1; while(n--) { int id,g; cin>>id>>g; mp[g]=id; int tmp; map ::iterator it=mp.find(g); //用find函数查找到键所在的下标 if(it==mp.begin()) tmp=(++it)->second; else { map ::iterator it2=it; it2--;it++; if((g-it2->first)<=(it->first-g)) tmp=it2->second; else tmp=it->second; } cout< 而Treap树的代码五由部分构成:
高精度计算
1.定义结点struct Node。2.旋转rorate()。3.插入insert()。4.找第k大的数kth()。5.查询某个数find().
第四、五部分是名次数的两个功能。
(代码就先略了,这部分我还要好好学,理解不深,后面补)书本上用JAVA实现,主要运用两个系统已经编写好的类。而c,c++中处理大数,需要用数组模拟,然后按位处理进位,借位。
万进制解决大数问题:
1.先将大的数字从右到左进行分配.eg:12346789 sum[0]=6789,sum[1]=12342.进位取余。eg:12346789*15
sum[0]*15=101835;beyond=101835/10000=10; sum[0]=sum[0]%10000=1835 sum[1]=1234*15+beyond(10)=18520 beyond=18520/10000=1; sum[1]=8520 sum[2]=sum[2]+beyond=1 结果为:1852018353.除了最高位若不满足4位,则在左边补0.
万进制求解n的阶乘(n>=1&&n<=10000)
#includeusing namespace std; int sum[10005]; int main() { int beyond,last,n; while(cin>>n) { memset(sum,0,sizeof(sum)); sum[0]=1; last=0; //记录每次乘上一个i,四位一组,组成的个数 for(int i=1;i<=n;i++) { beyond=0; for(int j=0;j<=last;j++) // 内循环为万进制操作 { sum[j]=sum[j]*i+beyond; beyond=sum[j]/10000; sum[j]%=10000; } if(beyond>0) { last++; sum[last]=beyond; } } cout< =0;i--) { cout<



