zoukankan      html  css  js  c++  java
  • 算法与数据结构实验题 6.3 search

    ★实验任务

    可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索 自己的手机。
    现在我们假设 Bibi 的家位于一棵二叉树的根部。在 Bibi 的心中,每个节点 都有一个权值 x,代表他心中预感向这个节点走可能找回自己手机的程度(虽然 他的预感根本不准)。当 Bibi 到达一个节点时,如果该节点有未搜索过的儿子节 点,则 Bibi 会走向未搜索过的儿子节点进行搜索,否则就返回父亲节点。如果 某节点拥有两个未搜索过的儿子节点,Bibi 会选择先搜索权值大的儿子节点。

    假设 Bibi 从一个节点到达另一个节点需要 1 单位时间,搜索节点的时间忽 略不计,那么请问当 Bibi 的手机位于编号为 k 的节点时,他需要多少单位时间 才能找到手机。

    ★数据输入

    输入第一行为一个正整数 n(1≤n≤100000)表示树的节点数目,树根的编号 总是为 1。
    接下来 n-1 行,每行两个正整数 p,x(1≤x≤100)。代表编号为 i 的节点的父 亲节点 p 和权值 x。这里的 i 从 2 依次数到 n。数据保证输入的 p 小于当前的 i, 且互为兄弟的两个节点的权值 x 不同。
    第 n+1 行一个整数 m(1≤m≤n), 表示询问组数。
    第 n+2 行有 m 个整数,每个整数 ki(1≤ki≤n)代表该组询问中手机的位置。

    ★数据输出

    输出 m 行,每行一个整数,代表 Bibi 找到手机需要花费的单位时间数量。

    输入示例 输出示例
    3
    1 20
    1 30
    3
    1
    2
    3
    0 3 1

    思路

    建立一个递归过程来模拟这个搜索过程:

    1.用一个变量sum来保存当前走了多少步

    2.建立结构体(用父节点表示法建立数组)

    struct Tree
    {
    	int value;          //保存当前节点的权值
    	int step;           //记录走到该节点的步数
    	int left;           //左儿子编号
    	int right;          //右儿子编号
    };
    

    3.递归函数

    void search(int i)
    {
    	tree[i].step = sum;                                                   //更新该节点的step值
    	if (tree[i].left == 0 && tree[i].right == 0)			//判断该节点是否为叶节点		
    	{																 
    		sum++;								//返回上一个节点步数+1 
    		return;
    	}
    	if (tree[tree[i].left].value>tree[tree[i].right].value)	//左儿子权值大于右儿子 
    	{
    		//tree[i].step += sum++;
    		sum++;								//即将搜索左儿子步数+1 
    		search(tree[i].left);						//搜索左儿子 
    		if (tree[tree[i].right].value)				//判断是否存在右儿子 
    		{
    			sum++;		        				//即将搜索右儿子步数+1 
    			search(tree[i].right);					//搜索右儿子 
    		}
    	}
    	else
    	{
    		//tree[i].step += sum++;
    		sum++;
    		search(tree[i].right);
    		if (tree[tree[i].left].value)
    		{
    			sum++;
    			search(tree[i].left);
    		}
    	}
    	sum++;									//左右儿子搜索完毕之后返回上个节点步数+1 
    }
    

    4.递归函数之后每个节点的step值都会被更新,这样我们只要输入节点编号,访问step值就能知道找到这个节点要走多少步了。

    Code

     
                #include<stdio.h>
    #include<iostream>
    #include<string.h>
    using namespace std;
    struct Tree
    {
    	int value;
    	int step;
    	int left;
    	int right;
    };
    Tree tree[100001] = { 0 };
    int sum = 0;
    void search(int i)
    {
    	tree[i].step = sum;
    	if (tree[i].left == 0 && tree[i].right == 0)
    	{
    		sum++;
    		return;
    	}
    	if (tree[tree[i].left].value>tree[tree[i].right].value)
    	{
    		//tree[i].step += sum++;
    		sum++;
    		search(tree[i].left);
    		if (tree[tree[i].right].value)
    		{
    			sum++;
    			search(tree[i].right);
    		}
    	}
    	else
    	{
    		//tree[i].step += sum++;
    		sum++;
    		search(tree[i].right);
    		if (tree[tree[i].left].value)
    		{
    			sum++;
    			search(tree[i].left);
    		}
    	}
    	sum++;
    }
    int main()
    {
    	int n;
    	int m;
    	int x;
    	int y;
    	int i;
    	int k;
    	//printf("%d
    ", tree[0].value);
    	scanf("%d", &n);
    	tree[1].value = 0;
    	tree[1].step = 0;
    	for (i = 2; i <= n; i++)
    	{
    		scanf("%d %d", &x, &y);
    		if (!tree[x].left)
    		{
    			tree[x].left = i;
    			tree[i].value = y;
    		}
    		else
    		{
    			tree[x].right = i;
    			tree[i].value = y;
    		}
    	}
    	search(1);
    	scanf("%d", &m);
    	for (i = 1; i <= m; i++)
    	{
    		scanf("%d", &k);
    		printf("%d", tree[k].step);
    		if (i<n)printf("
    ");
    	}
    	return 0;
    }
    
            
    
  • 相关阅读:
    SLF4J + logback 实现日志输出和记录
    Log4j配置文件
    通过maven的<profile>标签,打包不同配置的变量包
    单点登录(SSO)原理
    MyBatis拦截器(插件)分页
    导航栏pop拦截
    swift 基础小结01 --delegate、Optional、GCD的使用、request请求、网络加载图片并保存到沙箱、闭包以及桥接
    转载-iOS SDK开发
    leaks工具查找内存泄露
    weex stream 之fetch的get、post获取Json数据
  • 原文地址:https://www.cnblogs.com/031602523liu/p/7816028.html
Copyright © 2011-2022 走看看