当前位置: 首页 > 知识库问答 >
问题:

二元三阶访问类的线性算法

戴鸿羲
2023-03-14

我必须用C写一个算法,接受输入二叉查找树。该练习将从子树根开始并尽可能长时间向左的访问定义为“向左访问”。同样,它定义了“正确的访问”。该练习要求打印三个键,其中左访问严格大于右访问。它还要求按升序打印这个密钥,算法必须在线性时间内工作,所以我必须实现一个类似于按顺序访问的算法。现在,我已经写了一个算法,可以在线性时间内工作,但在某些情况下,它不能按顺序访问,所以打印的密钥不是按升序排列的,但我不知道如何克服这个障碍。如果不首先在左边和右边实现递归,我如何比较左边和右边的访问呢?

#include<stdio.h>
#include<stdlib.h>


typedef struct _node {
        int dato;
    struct _node *left;
        struct _node *right;
}node;


typedef struct _ret {
        int sin;
        int des;
        }res;


node *inserisci(node *root, int insert)
{
 if(root==NULL) {
        node * new=(node*)malloc(sizeof(node));
        new->left=NULL;
        new->right=NULL;
        new->dato=insert;
        return new;
}
 if(root->dato < insert) root->right =inserisci(root->right,insert);
 else root->left = inserisci(root->left,insert);
 return root;
}


res somma(node * u)
{
res ret; res ciao_sx; res ciao_dx;

if(u==NULL) return;

if(u->left==NULL && u->right==NULL)
        {
        ret.sin=0;
        ret.des=0;
        return ret;
        }

if(u->left!=NULL && u->right!=NULL)
        {
        ciao_sx=somma(u->left);
        ret.sin= ciao_sx.sin+1;
        ciao_dx=somma(u->right);
        ret.des= ciao_dx.des+1;

        if(ret.sin > ret.des )
                {
                printf("%d\n",u->dato);
                }
        return ret;
        }

if(u->left!=NULL && u->right==NULL)
        {
        ciao_sx=somma(u->left);
        ret.sin= ciao_sx.sin+1;
        ret.des= 0;
        printf("%d\n",u->dato);

        return ret;
        }

if(u->left==NULL && u->right !=NULL)
        {
        ciao_dx=somma(u->right);
        ret.des= ciao_dx.des +1;
        ret.sin=0;
        return ret;

        }
}





int main()
{
int n,i,x;
scanf("%d",&n);
node *root=NULL;
for(i=0;i<n;i++) {
        scanf("%d",&x);
        root=inserisci(root,x);
}

somma(root);

return 0;
}

共有1个答案

柳深
2023-03-14

这个问题可以在线性时间内解决。

诀窍是以底部向上的方式计算左访问和右访问值,以便我们可以执行以下操作:

left_visit of node = left_visit of its left child + 1

right_visit of node = right_visit of its right child + 1

条件是:

if(node is null)
 left_vist is 0 as well as right_visit is also 0.

由于我们可以很容易地使用inorder遍历以自下而上的方式跟踪此路径,因此我们将使用它计算left_visit和right_visit的值。

主要理念

我们知道我们可以很容易地编写递归无序遍历。

我们知道,当我们遇到一个没有左子节点的节点时,我们已经到达了底部,所以这是我们开始使用上面指定的规则计算值的地方。

这样做的原因是,当对一个节点的左子节点的顺序遍历的递归调用完成时,它的左子节点将计算它的left_visit,我们所要做的就是加1来计算当前节点的left_visit值,同样的逻辑也适用于right vist。

时间复杂度是O(N),这是线性的,因为顺序遍历是在线性时间内完成的。

使用上面的算法,这里是C代码:

#include <stdio.h>
#include <stdlib.h>
typedef struct tree tree;
struct tree{
   int value;
   tree *left;
   tree *right;       
   int lv;
   int rv;
};
tree *insert(tree *ptr,int x)
{
    if(ptr==NULL)
    {
        ptr=(tree *)malloc(sizeof(tree));
        ptr->left=NULL;
        ptr->right=NULL;
        ptr->value=x;            
        return ptr;
    }
    else if(ptr->value>x)
        {ptr->left=insert(ptr->left,x);return ptr;}
    else { ptr->right=insert(ptr->right,x);return ptr;}
}
void compute_values(tree *ptr)
{
    if(ptr==NULL)
    return;
    compute_values(ptr->left);
    if(ptr->left==NULL)
     ptr->lv=0;
    else ptr->lv=ptr->left->lv+1;    
    compute_values(ptr->right);
    if(ptr->right==NULL)
     ptr->rv=0;
    else ptr->rv=ptr->right->rv+1;   
}
void iot(tree *ptr)
{
    if(ptr==NULL)
     return;
    iot(ptr->left);  
      if(ptr->lv > ptr->rv)
       printf("%d ",ptr->value);
    iot(ptr->right);
}
int main()
{
    tree *root=NULL;
    int i;
    /*insert 6  elements*/        
     root=insert(root,4);
     root=insert(root,5);
     root=insert(root,3);
     root=insert(root,1);
     root=insert(root,2);
     root=insert(root,0);
     root=insert(root,6);
     compute_values(root);/*compute the left and right visit.*/
     printf("the nodes which have left visit strictly > than right visit\n");
     iot(root);/*inorder traversal*/   
}
 类似资料:
  • 这个问题真的很奇怪。 我正在将一个例程转换为SIMD指令(我对SIMD编程非常陌生),但遇到以下代码位的问题: 问题:假设有一个SIMD实现,我只是试图计算一个正确的向量进行处理,那么处理依赖于它以前的值的正确方法是什么? 反过来,类似于函数编程的折叠实现也同样有用,因为我试图理解如何更好地提升数据依赖性,而不是为了优化而进行优化。 最后,如果你能推荐一些文献,请做。不知道如何谷歌这个话题。

  • 我正在尝试访问HTML代码中特定的元素。 定义元素的代码部分如下所示 。 在下面的第二行代码之后,我尝试声明表达式和,它们都返回java.lang.String类型的“oddrow cellcont” 但是,我尝试了下面的代码片段,它不能工作,因为循环中的条件返回false。我还尝试使用和、、、...以所有可能的组合使用if条件。 我肯定被困住了;我需要帮助。

  • 9.6. 访问元素属性 XML 元素可以有一个或者多个属性,一旦你已经解析了一个 XML 文档,访问它们就太简单了。 在这部分中,将使用 binary.xml 语法文件,你在上一节中已经看到过了。 这部分由于某个涵义重叠的术语可能让人有点糊涂。在一个 XML 文档中,元素可以有属性,而 Python 对象也有属性。当你解析一个 XML 文档时,你得到了一组 Python 对象,它们代表 XML 文

  • 问题内容: 与我的其他问题略相关:以下内容之间有什么区别: 同样,最后2个之间的差异是我最感兴趣的。 问题答案: 任何包中的类都可以访问公共类。 具有默认访问权限()的类仅对同一包中的其他类可见。 private和protected修饰符只能应用于内部类。 私有类仅对其封闭类以及同一封闭类中的其他内部类可见。 受保护的类对于同一包中的其他类以及扩展该封闭类的类都是可见的。

  • 有没有可能改变这一点: 到三元运算符?

  • 模板可以支持三元运算符,如: {$status?'发布':'下线'} {$vo.status?'发布':'下线'} {$vo['status']?'发布':'下线'} 支持条件判断表达式: {$a==$b ? 'yes' : 'no'} 条件运算符可以是==、===、!=、!==、>=、<=