慕课(7)

图:
Tree Traversals Again:
有序二叉树遍历可以通过堆栈以非递归方式实现。例如,假设遍历6节点二叉树(键的编号从1到6)时,堆栈操作为:push(1);push(2);push(3);pop();pop();push(4);pop();pop();push(5);push(6);pop();pop()。然后,可以从这个操作序列生成一个唯一的二叉树(如图1所示)。你的任务是给出这个树的后序遍历序列。

每个输入文件包含一个测试用例。对于每种情况,第一行包含一个正整数N(≤30),它是树中节点的总数(因此节点的编号从1到N)。接下来是2N行,每行描述一个堆栈操作,格式为:“Push X”,其中X是被推送到堆栈上的节点的索引;或“Pop”,意思是从堆栈中弹出一个节点。

对于每个测试用例,在一行中打印对应树的后序遍历序列。一定有解决办法。所有数字必须用一个空格隔开,并且行的末尾不能有多余的空格。

题意:用栈的push、pop操作给出一棵二叉树的中序遍历顺序,求这棵二叉树的后序遍历。
核心代码:

void  shu(int a int b,int m,int n)
{
    int r,l,i;
    if(n==0)
        return;
    if(n==1)
    {
        post[m]=pre[a];
        break;
    }
    root=pre[a];
    post[m+n-1]=root;
    for(i=0;i<n;i++)
        if(in[b+i]==root)
        break;
    l=i;
    r=n-l-1;
    shu(a+1,b,m,l);
    shu(a+l+1,b+l+1,m+l,r)
}

Complete Binary Search Tree

二进制搜索树(BST)递归地定义为具有以下属性的二进制树:

节点的左子树只包含键小于节点键的节点。

节点的右子树仅包含键大于或等于节点键的节点。

左子树和右子树也必须是二进制搜索树。

完整的二叉树(CBT)是一个完全填充的树,但底层可能例外,它是从左到右填充的。

现在给定一系列不同的非负整数键,如果要求树也必须是CBT,则可以构造唯一的BST。您应该输出这个BST的水平顺序遍历序列。

输入规格:

每个输入文件包含一个测试用例。对于每种情况,第一行包含一个正整数N(≤1000)。然后在下一行给出N个不同的非负整数键。一行中所有数字用空格隔开,且不大于2000。

输出规格:

对于每个测试用例,在一行中打印对应的完整二进制搜索树的级别顺序遍历序列。一行中的所有数字都必须用空格隔开,并且行的末尾不能有多余的空格。

思路:
根据输入的结点数,建立完全二叉树;
将节点数值放在数组中,从小到大排序;
根据根左儿子的结点数(左儿子的值都比根的值小,右儿子的值都比根的值大,所以,例如左儿子有6个结点,则根的值为数组中第7大的值),选取数组中对应的值,放入其中,然后更新左儿子数组,右儿子数组,递归将值放入其中。

核心代码:

void  shu(int left int right,int root)
{
    n=right-left+1;
    if(n==0)
        return;
    l=getletflength(n);
    T[root]=A[left+l];
    letfroot=root*2+1;
    rightroot=leftroot+1;
    shu(left,left+l-1,leftroot);
    shu(left+1+l,right,rightroot);
}

Huffman Codes:
Huffman Codes的特点:
1.最优编码—总长度最小
2.无歧视解码—前缀码,数据仅存于叶子节点
3.没有度为1的节点—满足1.2则必然有3

核心代码

Minheap H=Creatheap(N)//创建一个空的,容量为N的最小堆
H=ReadData(N);
HuffmanTree T=Huffman(H);
int codelen=WPL(T,0);

int WPL(HuffmanTree T,int depth)
{
    if(!T->left&&!T->right)
        return depth*T->weight;
    else
        return (WPL(RT->left,depth+1)+WPL(T->right,depth+1));
}

最短路径:
用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

关于最短路径的解法,我个人是用三个数组分别是存路长,标记,代表起点到某个点的距离,通过不断查找最短距离来最后得到结果

放例题:
大奶牛很热爱加班,他和朋友在凌晨一点吃完海底捞后又一个人回公司加班,为了多加班他希望可以找最短的距离回到公司。
深圳市里有N个(2 <= N <= 1000)个公交站,编号分别为1…N。深圳是大城市,公交车整天跑跑跑。公交站1是大奶牛的位置,公司所在的位置是N。所有公交站中共有T (1 <= T <= 2000)条双向通道。大奶牛对自己的导航能力不太自信,所以一旦开始,他总是沿着一条路线走到底。
大奶牛为了锻炼未来的ACMer,决定让你帮他计算他到公司的最短距离。可以保证存在这样的路存在。
Input
第一行:两个整数:T和N
接下来T行:每一行都用三个空格分隔的整数描述一个轨迹。前两个整数是路线经过的公交站台。第三个整数是路径的长度,范围为1到100。
Output
一个整数,表示大奶牛回到公司的最小距离。
Sample Input
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
Sample Output
90

#include<stdio.h>
#include<string.h>
int n,m;
int a[3000][3000],book[3000],c[3000];
int max=1000010;
int bijiao(int x,int y)
{
    int i,min,k,j;
    for(i=1; i<=n; i++)
        c[i]=a[x][i];
    c[x]=0;
    book[x]=1;
    for(i=1; i<=n; i++)
    {
        min=max;
        for(j=1; j<=n; j++)
        {
            if(book[j]==0&&c[j]<min)
            {
                k=j;
                min=c[j];
            }
        }
        book[k]=1;
        for(j=1; j<=n; j++)
        {
            if(book[j]==0&&c[j]>min+a[k][j])
            {
                c[j]=a[k][j]+min;
            }
        }
    }
    return c[y];
}
int main()
{
    scanf("%d %d",&m,&n);
    memset(book,0,sizeof(book));
    int i,j,x,y,ans,sum;
    for(i=1; i<=n; i++)
        for(j=1; j<=n; j++)
        {
            a[i][j]=max;
            a[j][i]=max;
        }
    while(m--)
    {
        scanf("%d %d %d",&x,&y,&ans);
        if(ans<a[x][y])
        {
            a[x][y]=ans;
            a[y][x]=ans;
        }
    }
    sum=bijiao(1,n);
    printf("%d\n",sum);
    return 0;
}

代码个人认为还是非常好理解的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值