大二博客总结第四周

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大二博客总结第四周相关的知识,希望对你有一定的参考价值。

本周学习内容:
1.了解掌握了二叉树的存储,创建和遍历
2.学会了二叉搜索树(BST),做完了课后习题
3.看懂、学习了简单平衡二叉搜索树——Treap树
4.高精度计算


BST

1.每个元素的键值可以比较大小,将键值存放在BST的结点上
2.键值最大的结点没有右儿子,键值最小的结点没有左儿子
3.最坏的情况下,树的深度为n;最好的情况下,得到的左右子树完全平衡,深度为log2(n).
BST的关键在于运用算法努力使它保持平衡

eg:HDU 3999 “The order of a Tree”

#include <bits/stdc++.h>

using 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<n;i++)
        {
            int x;
            cin>>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<m;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
}

Treap 树

1.treap树的插入和调整
优先级决定了元素的位置,优先级最高的为树根;而键值决定了元素作为左孩子或是右孩子。优先级高的利用左旋、右旋上升调整位置。
2.treap树的删除:若结点是叶子结点,则直接删除;若结点有子节点,那么找到优先级最大的子节点,向相反方向旋转,调整为叶子结点后删除。
(treap树的代码有点麻烦,有时对应STL容器解题会方便很多)

eg:给出和尚们打架的顺序(P75)页
(灵活使用迭代器,map容器可根据键来进行升序排列)

#include <bits/stdc++.h>
using namespace std;
map<int,int>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<int,int>::iterator it=mp.find(g); 
            //用find函数查找到键所在的下标
            if(it==mp.begin())
                tmp=(++it)->second;
            else
            {
                map<int,int>::iterator it2=it;
                it2--;it++;
                if((g-it2->first)<=(it->first-g))
                    tmp=it2->second;
                else
                    tmp=it->second;
            }
            cout<<id<<" "<<tmp<<endl;
        }
    }
    return 0;
}

而Treap树的代码五由部分构成:
1.定义结点struct Node。2.旋转rorate()。3.插入insert()。4.找第k大的数kth()。5.查询某个数find().
第四、五部分是名次数的两个功能。
(代码就先略了,这部分我还要好好学,理解不深,后面补)

高精度计算

书本上用JAVA实现,主要运用两个系统已经编写好的类。而c,c++中处理大数,需要用数组模拟,然后按位处理进位,借位。

万进制解决大数问题:
1.先将大的数字从右到左进行分配.

eg:12346789     	
sum[0]=6789,sum[1]=1234

2.进位取余。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
结果为:185201835

3.除了最高位若不满足4位,则在左边补0.

万进制求解n的阶乘(n>=1&&n<=10000)

#include <bits/stdc++.h>
using 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<<sum[last];
        for(int i=last-1;i>=0;i--)
        {
            cout<<setw(4)<<setfill('0')<<sum[i];
        }
        cout<<endl;
    }
    return 0;
}

以上是关于大二博客总结第四周的主要内容,如果未能解决你的问题,请参考以下文章

周总结(第四周)

第四周学习进度总结

2017-2018-1 20155305 《信息安全系统设计基础》第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客)

大二博客总结(第三周)

大二博客总结第五周

软件工程学习进度第四周