• 实现二叉树(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

    解题过程:

    暂时个人认为二叉树其实更好实现,因为之前对于儿子个数不确定的树需要用链表很不熟悉(不过现在感觉用动态数组vector可以好多了),而二叉树每个节点有两个儿子实现就比较简单;

    解题思路:

    通过深搜的方法实现,用递归回溯的思想对走的步数(即时间)进行计算并同步存储,这题还需要我们同时对每个节点的时间存储,因为访问的次数可能会很多容易超时。

    代码:

    给我帮助的同学的代码(通过vector写):

    
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<vector>
    #include<algorithm>
    #define MAX_SIZE 100005
    
    using namespace std;
    struct node
    {
    	int quan, bu;
    	bool vis;
    }tree[MAX_SIZE];
    
    vector <int> v[MAX_SIZE];
    
    int cnt = -1;
    int n;
    
    void dfs(int ge)
    {
    	cnt++;
    	if (tree[ge].vis == false)
    	{
    		tree[ge].vis = true;
    		tree[ge].bu = cnt;
    	}
    	if (!v[ge].empty())
    	{
    		vector<int>::iterator it;
    		for (it = v[ge].begin(); it != v[ge].end(); it++)
    			dfs(*it);
    	}
    	cnt++;
    }
    
    int main()
    {
    	int i, j;
    	scanf("%d", &n);
    	for (i = 1; i <= n; i++)
    		v[i].clear();
    	for (i = 2; i <= n; i++)
    	{
    		int a, b;
    		scanf("%d%d", &a, &b);
    		tree[i].quan = b;
    		tree[i].vis = false;
    		v[a].push_back(i);
    	}
    	for (i = 1; i <= n; i++)
    	{
    		if (!v[i].empty() && v[i].size()>1)
    		{
    			if (tree[v[i][0]].quan<tree[v[i][1]].quan)
    				swap(v[i][0], v[i][1]);
    		}
    	}
    	dfs(1);
    	int m;
    	scanf("%d", &m);
    	for (i = 1; i <= m; i++)
    	{
    		int a;
    		scanf("%d", &a);
    		printf("%d
    ", tree[a].bu);
    	}
    	//    system("pause");
    	return 0;
    }
    
    
    

    之后对我之前用数组实现的代码的改进实现:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<vector>
    #define MAX_SIZE 100005
    
    using namespace std;
    int cnt = -1;
    
    struct Node
    {
    	int ele;
    	int son1, son2;
    	int vis;
    	int ste;
    }node[MAX_SIZE];
    
    void dfs(int loca)
    {
    	cnt++;
    	if (node[loca].vis == 0)
    	{
    		node[loca].vis = 1;
    		node[loca].ste = cnt;
    	}
    	if (node[node[loca].son1].vis == 0 && node[loca].son1 != 0)
    	{
    		dfs(node[loca].son1);
    		cnt++;
    	}
    	if (node[node[loca].son2].vis == 0 && node[loca].son2 != 0)
    	{
    		dfs(node[loca].son2);
    		cnt++;
    	}
    }
    
    int main()
    {
    	int n, i, j;
    	cin >> n;
    	for (i = 2; i <= n; i++)
    	{
    		int father;
    		cin >> father >> node[i].ele;
    		if (node[father].son1 == 0)node[father].son1 = i;
    		else
    		{
    			if (node[node[father].son1].ele < node[i].ele)
    			{
    				node[father].son2 = node[father].son1;
    				node[father].son1 = i;
    			}
    			else node[father].son2 = i;
    		}
    		node[i].vis = 0;
    	}
    	dfs(1);
    	int m;
    	cin >> m;
    	for (i = 1; i <= m; i++)
    	{
    		int tmp;
    		cin >> tmp;
    		cout << node[tmp].ste << endl;
    	}
    	return 0;
    }
    

    题目收获:二叉树可以方便的通过数组实现,而树其实也不会很难,可以通过vector动态数组实现就行。

  • 相关阅读:
    Struts2获取参数的几种方式
    Struts2的Action中访问servletAPI方式
    struts2中常用配置
    struts2发送ajax的几个问题(不使用struts2-json-plugin的情况下)
    深入Struts2的过滤器FilterDispatcher--中文乱码及字符编码过滤器
    Ironic 裸金属实例的部署流程
    Ironic 裸金属管理服务的底层技术支撑
    Cinder AZ 与 Nova AZ 的同步问题
    OpenStack 对接 Ceph 环境可以创建卷但不能挂载卷的问题
    OpenStack 节点重启后无法联网的问题
  • 原文地址:https://www.cnblogs.com/heihuifei/p/7803623.html
Copyright © 2020-2023  润新知