将树的每个节点存储在数组中

时间:2019-01-11 19:57:26

标签: generics recursion binary-tree binary-search-tree ada

我必须存储可以由任何类型组成的通用树的每个节点。我必须在ADA中执行此操作,但我只需要思考方式。

我必须将每个节点存储在通用元素的数组中。 这样的方式是数组没有诸如Ada中的加法之类的操作, 我的意思是我不能做:

Array3:=Array1+Array2;

例如,“ +”运算符对于递归计数非常有用。

有一种方法可以通过将每个结果存储在数组上而不使用任何运算符来递归地完成它?

还是迭代进行算法更方便?

谢谢。

EDIT我尝试使用数组的串联运算符的ADA中的代码

function Get_all_nodes (Current_Node : in Tree) return Something_Concatenation.Element_Array is 
array_of_results:Something_Concatenation.Element_Array(1..50);
begin
if (Tree_is_null(Current_Node)) then
    return array_of_results;
else
array_of_results(1):=Get_value_of_node(Current_Node);
array_of_results:= array_of_results & Get_all_nodes(Get_access_to_parent1(Current_Node));
array_of_results:= array_of_results & Get_all_nodes(Get_access_to_parent1(Current_Node));
end if;
return array_of_results;
end Get_all_nodes;

致谢

2 个答案:

答案 0 :(得分:1)

在Ada中,concatenation operator&符号。数组可以串联在一起。如果愿意,可以使用它进行递归调用,但是由于堆栈使用情况,我不建议这样做。编译器可能会对其进行优化,但是由于您将返回不受约束的类型,因此可能不会。

您没有指定树类型或提供任何代码,因此我无法帮助您如何从树类型中获取元素,但这是使用泛型进行数组连接的示例:

with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is

    -- Generic, since you asked about it in a generic context
    generic
        type Element_Type is limited private;
    package Concatenation is
        type Element_Array is array(Positive range <>) of Element_Type;
    end Concatenation;

    -- Integer example
    package Integer_Concatenation is new Concatenation(Integer);
    use type Integer_Concatenation.Element_Array;

    a1 : Integer_Concatenation.Element_Array(1..4) := (others => 1);
    a2 : Integer_Concatenation.Element_Array(1..5) := (others => 2);
    a3 : Integer_Concatenation.Element_Array := a1 & a2;
    a4 : Integer_Concatenation.Element_Array := 1 & 2 & 3 & 4 & 5;

    -- Custom record type
    type Something is null record;
    package Something_Concatenation is new Concatenation(Something);
    use type Something_Concatenation.Element_Array;

    a5 : Something_Concatenation.Element_Array(1..4) := (others => <>);
    a6 : Something_Concatenation.Element_Array(1..5) := (others => <>);
    a7 : Something_Concatenation.Element_Array := a5 & a6;

    s1,s2,s3,s4,s5 : Something;
    a8 : Something_Concatenation.Element_Array := s1 & s2 & s3 & s4 & s5;
begin
    -- Show the integer array results
    Put_Line("Hello, world!");
    for E of a3 loop
        Put(Integer'Image(E));
    end loop;
    New_Line;
    for E of a4 loop
        Put(Integer'Image(E));
    end loop;
    New_Line;
end Hello;

编辑:您尝试递归来编辑问题。这是递归的替代示例,因此您可以看到一些语法和设置选项。因为您提供的内容不多,所以我不得不整理一堆东西。另外,之前我通过泛型提供了数组类型,因为您的原始问题是在泛型的上下文中提出的。在现实生活中,我不会只为数组类型创建泛型(可以在任何地方完成)。取而代之的是,您将为树使用通用名称,并且此答案中提到的所有内容都将在该通用名称的上下文中完成。由于您没有提供任何基本的通用代码,因此我不想提出一个完整的示例。我只是想向您展示,串联将适用于通过泛型创建的类型。

    function Get_all_nodes (Current_Node : in Tree) return 
        Something_Concatenation.Element_Array 
    is 
        use Something_Concatenation;
        use type Element_Array;
        Next_Node : Tree;
    begin
        if (Tree_is_null(Current_Node)) then
            return (1..0 => <>);  -- returns a null array
        else
            -- for the next call, get the node after this one
            -- or replace this with a call for the previous one
            -- or whatever your mechanism for getting a new
            -- node is.  You can also call Get_Next_Node
            -- in the return statement.  I Pulled it out
            -- here so you would see the step
            Next_Node := Get_Next_Node(Current_Node);

            -- here you need to figure out the order of nodes
            -- and how you want to traverse them.  This is
            -- just a basic (probably logically wrong) example
            -- to show you the syntax you were trying to emulate.
            -- you might also have to alter the order of these
            -- elements to get the array element order you want
            return Element_Array'(1 => Get_Value_of_Node(Current_Node))
                & Get_All_Nodes(Next_Node);

            -- Alternate with no "Next_Node" variable:
            -- return Element_Array'(1 => Get_Value_of_Node(Current_Node))
            --    & Get_All_Nodes(Get_Next_Node(Current_Node));
        end if;
    end Get_all_nodes;

答案 1 :(得分:0)

因此,我尝试了递归和迭代版本。 在迭代版本中,我得到了类似的结果,我使用了在我的情况下允许的堆栈

WordPress

此时我在某些地方出错了

function get_all_nodes(Current_Node:in Tree) return Stack is
--declarations
My_Stack: Stack;
copy:Tree;
finished: Boolean:=False;
begin
--Initialisation

copy:=Current_Node;
My_Stack:=Initialisation;
--beginning by pushing the first node on the stack

push_on_stack(stack,copy.all.elt);

while(copy/=null or finished =False) loop
--check that we can put the first parent on stack
    if(copy.all.parent1/=null and not Found_in_Stack(My_Stack,copy.all.parent1.all.elt)) then
        copy:=copy.all.parent1;
        push_on_stack(stack,copy.all.elt);
    end if;
--check that we can put the second parent on stack
    if(copy.all.parent2/=null and not Found_in_Stack(My_Stack,copy.all.parent2.all.elt)) then
        copy:=copy.all.parent2;
        push_on_stack(stack,copy.all.elt);
    end if;
--check we are on case where both parents are already on stack or both null
    if(copy.all.parent1=null and copy.all.parent2=null) or 
    (Found_in_Stack(My_Stack,copy.all.parent1.all.elt) and (Found_in_Stack(My_Stack,copy.all.parent2.all.elt))) then
    --check we are on case where we are back to first node and then it's finished 
        if(copy.all.elt=Current_Node.all.elt) then
            finished:=True;
        else
        --go back to previous node thanks to stack
            copy:= First_Element_after_top_of_stack(My_Stack);
        end if;
    end if;
end loop;
return My_Stack;
end get_all_nodes;

似乎在第一个条件之后执行第二个条件,并且我得到了错误,因为copy.all.parent2.all.elt = null而不是堆栈和树上的通用元素。

我通过以下代码尝试了递归版本:

copy.all.parent2/=null and not Found_in_Stack(My_Stack,copy.all.parent2.all.elt)

我有一个CONSTRAINT_ERROR的长度检查失败。

现在,我将通过阅读scrapgod链接来检查如何最小化长度问题,否则我将检查是否可以使用Ada容器。

再次感谢大家的帮助。 问候。