在二叉树中添加节点时使用指针指向Struct的指针

时间:2013-06-20 17:10:52

标签: c pointers tree traversal

我想知道为什么我们在二叉树中插入节点时使用指针指针。 但是,在遍历二叉树时,我们只需通过指向根节点的简单指针来引用树。但是为什么在插入节点时呢?

任何人都可以帮助我提供原因或参考链接,以了解它为何指针指针。

/*This program clears out all the three methods of traversal */

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

/* Let us basically describe how a particular node looks in the binary tree .... Every node in the tree has three major elements , left child, right child, and  and the data. */

struct  TreeNode {
int data;
struct TreeNode *leftChild;
struct TreeNode *rightChild;
};

void inorder(struct TreeNode *bt);
void preorder(struct TreeNode *bt);
void postorder(struct TreeNode *bt);
int insert(struct TreeNode **bt,int num);

main()
{
int num,elements;
struct TreeNode *bt;
int i;

printf("Enter number of elements to be inserted in the tree");
scanf("%d",&num);

printf("Enter the elements to be inserted inside the tree");
for(i=0;i<num;i++)
{
scanf("%d",&elements);
insert(&bt,elements);
printf("\n");
}

printf("In Order Traversal \n");
inorder(bt);

printf("Pre Order Traversal \n");
preorder(bt);

printf("Post Order Traversal \n");
postorder(bt);

return 0;
}

int insert(struct TreeNode **bt,int num)
{
if(*bt==NULL)
{
*bt= malloc(sizeof(struct TreeNode));

(*bt)->leftChild=NULL;
(*bt)->data=num;
(*bt)->rightChild=NULL;

return;
}
else{
/* */
if(num < (*bt)->data)
{
insert(&((*bt)->leftChild),num);
}
else
{
insert(&((*bt)->rightChild),num);
}
}
return;
}

void inorder(struct TreeNode *bt){
if(bt!=NULL){


//Process the left node
inorder(bt->leftChild);

/*print the data of the parent node */
//printf(" %d ", bt->data);

/*process the right node */
inorder(bt->rightChild);
}

}

void preorder(struct TreeNode *bt){
if(bt)
{
//Process the parent node first
printf("%d",bt->data);

//Process the left node.
preorder(bt->leftChild);

//Process the right node.
preorder(bt->rightChild);


}

}


void postorder(struct TreeNode *bt){

if(bt)
{
//process the left child
postorder(bt->leftChild);

//process the right child
postorder(bt->rightChild);


//process the parent node
printf("%d",bt->data);


}
}

3 个答案:

答案 0 :(得分:3)

"I want to know the reason why do we use, pointer to pointer while inserting nodes in the binary tree. But, While traversing the binary tree, we just refer the tree by simple pointer to the root node. But why while inserting node?"

我们实际上甚至不需要代码来回答这个问题。如果要在C中的外部函数中修改(写入)数据,则需要具有数据的地址。就像:

main() {
   int x = 2;
   change_me(x);
   printf("%d\n", x); // prints 2
}

void change_me(int x){
   x++;
}

没有意义。您(在此示例中)获取可修改的本地副本,对该值所做的任何更改仅在本地范围内。如果您希望这些更改传播回调用函数,则需要以下地址:

main() {
   int x = 2;
   change_me(&x);
   printf("%d\n", x); // prints 3
}

void change_me(int* x){
   (*x)++;
}

这同样适用于指针。在链表的示例中,如果我想打印值,我需要遍历树并读取数据。我不需要改变任何东西,只需指针就能做到。但是,如果我想修改树:

struct node{
   int val;
   sturct node* next;
};

main() {
  struct node* head = malloc(sizeof(struct node));
  head->val = 3;
  insert_a_node_in_front(head);
}

insert_a_node_in_front(node * ptr) {
    struct node* temp = ptr;
    ptr = malloc(sizeof(struct node));
    ptr->val = 5;
    ptr->next = temp;
}
嗯,猜猜怎么着?我们实际上并没有插入该节点,因为head的值永远不会改变。它仍指向具有val==3的原始节点。原因与以前一样,我们试图改变参数的本地副本的值。如果我们希望这些更改坚持下去,则需要原始副本的地址:

  insert_a_node_in_front(&head);
}

insert_a_node_in_front(node ** ptr) {
    struct node* temp = (*ptr);
    (*ptr) = malloc(sizeof(struct node));
    (*ptr)->val = 5;
    (*ptr)->next = temp;
}

答案 1 :(得分:2)

这是因为插入的第一部分是mallocs一个新的struct treenode。如果你只传入了一个struct treenode *,这将是这样的:

int insert(struct TreeNode *bt,int num)
{
   if(bt==NULL)
   {
       bt= malloc(sizeof(struct TreeNode));

       (bt)->leftChild=NULL;
       (bt)->data=num;
       (bt)->rightChild=NULL;

   return;
   }
  ...
}

问题在于bt是本地插入的,因此main中的bt将保持不变。所以你传入一个指向main的bt的指针,它允许插入来改变它。

答案 2 :(得分:1)

这里给出了一个关于使用指针的非常好的提示: 试试这个基础: -

http://www.geeksforgeeks.org/how-to-write-functions-that-modify-the-head-pointer-of-a-linked-list/