简体   繁体   English

二叉树和传递参数

[英]Binary trees and passing arguments

I have a binary tree program in C++ ,which parses a string of characters and then forms a binary tree depending on it.I have a problem with transmitting parameters to my functions . 我有一个用C ++编写的二叉树程序,该程序解析一个字符串,然后根据它构成一个二叉树。我在向函数传递参数时遇到问题。 I tried reading tutorial on passing arguments to functions in c ,and changed my code ,but it doesn't seem to work.I would like someone to help me fix the passing of arguments. 我尝试阅读有关在c语言中将参数传递给函数的教程,并更改了我的代码,但它似乎不起作用。我希望有人帮助我解决参数传递问题。

The header : 标头:

     #define NULL 0

 struct TreeEl {

   char inf;
struct TreeEl * st, * dr;

};

typedef struct TreeEl root;


root* add(root *r, char st[], int &pos, int &n);
root* create(root *r, char st[100], int n);

void visit(root*);
void preorder(root *r, void visit(root*));
void inorder(root *r, void visit(root*));
void postorder(root *r, void visit(root*));

And the code : 和代码:

    #include "arbore_binar.h"
#include <stdio.h>



using namespace std;

void visit(root *r)
    {

    printf("Node %c",r->inf);

    }


root* add(root *r, char st[], int &pos, int &n)
{

int done=0;

do
{
    pos++;
    printf(" procesing character:,%c \n",st[pos]);
    switch (st[pos])
    {
        case '(':
        {
            add(r->st, st, pos, n);
            break;
        }
        case ')':
        {
            done=1;
            break;
        }
        case ',':
        {
            add(r->dr, st, pos, n);
            break;
        }
        case '$':
        {
            if (st[pos+1]==',')
                done=1;
            if (st[pos+1]==')')
                done=1;
            break;
        }
        default:
        {
            if ((st[pos]>=65)&&(st[pos]<=90))
             {
                 printf(" Added: ,%c \n" ,st[pos]);

                 root *p;
                 p = new root;
                 p->inf=st[pos];
                 p->st=NULL;
                 p->dr=NULL;
                 r=p;
                 if (st[pos+1]==',')
                    done=1;
                 if (st[pos+1]==')')

                    done=1;




             }
             else
                printf("Error,unknown character: %d ",st[pos]);
        }
    }
} while ((done==0)&&(pos<n));
return r;
}

root* create(root *r, char st[100], int n)
{

    int pos=-1;
    root* nod = add(r, st, pos, n);
    return nod;
}
void preorder(root *v, void visit(root*))
{
  if (v == NULL)

      return;


else {
visit(v);
preorder(v->st, visit);
preorder(v->dr, visit);
}
}
void inorder(root *v, void visit(root*))
{
  if (v == NULL) return;
else {
inorder(v->st, visit);
visit(v);
inorder(v->dr, visit);
}
}
void postorder(root *v, void visit(root*))
{
  if (v == NULL) return;
else {
postorder(v->st, visit);
postorder(v->dr, visit);
visit(v);
}
}



void print(root* x)
{
    printf("%c" , x->inf ,"  " );
}

int main()
{
//char a[100] = "A(B(J,$),C(X,D(E,F($,Y))))";
//char a[100] = "A(B,C(X,D(E,F($,Y))))";
char a[100] = "A(B(C(M,$),D),E(F(X,$),G($,Y)))";
root *r;
r=NULL;
r=create(r, a, 31);

printf("Preorder traversal:" );
preorder(r, print);
printf("\n");
printf("Inorder traversal: ");
inorder(r, print);
printf("\n");
printf("Postorder traversal: ");
postorder

(r, print); (r,打印); printf("\\n"); 的printf( “\\ n”);

getchar(); 的getchar(); return 0; 返回0;

}

Remember that C passes pointers by value. 请记住,C按值传递指针。 So code like root *p;r=p; 所以像root *p;r=p;这样的代码 does not modify the value of root that is present outside the function. 不会修改函数外部存在的root值。

In functions where you are going to reassign r , you might want to pass it as a pointer to pointer, or root **r . 在要重新分配r ,您可能希望将其作为指向指针的指针或root **r传递。 You would call such functions as create(&r, a, 31); 您将调用诸如create(&r,a,31);之类的函数。 to pass the address of the pointer variable to the function as a pointer to the r pointer. 将指针变量的地址作为r指针的指针传递给r

The trouble you are facing is related to the passing of arguments through by-value and by-reference semantics. 您面临的麻烦与通过按值和按引用语义传递参数有关。 In C, all variables are passed by value . 在C语言中, 所有变量都按value传递 Pointers are often referred to as being passed "by-reference", but they are not. 指针通常被称为“通过引用”传递,但事实并非如此。 Instead they enable the modification of other values, in a way which is similar to by-reference semantics. 相反,它们使修改其他值的方式类似于按引用语义。

The issue is that you have the add function: 问题是您具有添加功能:

void create(root *r, char st[100], int n);

create takes a root* as its first argument. createroot*作为第一个参数。 Thus, it can make changes to the memory pointed to by this parameter. 因此,它可以更改此参数指向的内存。 After execution of the function, the memory pointed to by r may be different, but r itself will have the same value - that is, the pointer variable r will always point to the same place. 函数执行后, r指向的内存可能会不同,但是r本身将具有相同的值-也就是说,指针变量r将始终指向相同的位置。

Why is this relevant? 为什么这是相关的? Look at your main function and note that the initial value of r is NULL . 查看您的main函数,请注意r的初始值为NULL After passing r to the create function, r must still be NULL . r传递给create函数之后, r 必须仍然为 NULL Therefore, you never have a pointer to the tree at all! 因此,您根本没有指向树的指针!

This probably does not seem like the case to you because in the create function, you assign a value to r (specifically the line r=p ). 在您看来,这种情况似乎不一样,因为在create函数中,您为r分配了一个值(特别是行r=p )。 Unfortunately, that line only modifies the function-local copy of r , so the changes are not reflected in main . 不幸的是,该行仅修改了r函数局部副本 ,因此更改未反映在main

How could you fix this? 您该如何解决? Instead of trying to modify the main -local copy of r within the create function, you could change the create function to return root* instead of void . 无需尝试在create函数中修改rmain local副本,您可以将create函数更改为返回root*而不是void Then, in main , change your calling of the function to this: 然后,在main ,将对函数的调用更改为:

r = create(r, a, 31);

Provided create returns a pointer to the root of the tree, you will now be able to maintain a reference to your tree everywhere, and it should work properly with your other functions. 提供的create将返回指向树根的指针,现在您将能够在任何地方维护对树的引用,并且该树应该与您的其他功能一起正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM