#include<stdio.h>
#include<stdlib.h>
#include<iostream.h>
using namespace std;
typedef struct _TreeNode{
int data;
_TreeNode* right;
_TreeNode* left;
} TreeNode;
TreeNode* CreateTree()
{
TreeNode* node=(TreeNode*)malloc(sizeof(TreeNode));
memset(node,0,sizeof(TreeNode));
return node;
}
TreeNode* FindDataInTree(TreeNode* TreeRoot,int number)
{
if(TreeRoot==NULL)
return NULL;
TreeNode* node=TreeRoot;
while(node)
{
if(node->data==number)
return node;
if(numberdata)
node=node->left;
if(number>node->data)
node=node->right;
}
return NULL;
}
bool InsertDataIntoTree(TreeNode* <span style="color:#ff0000;">&</span>TreeRoot,int number)
{
<span style="color:#ff0000;">if(TreeRoot==NULL)
return NULL;</span>
if(NULL!=FindDataInTree(TreeRoot,number))
return false;
<span style="color:#ff0000;">TreeNode* node=TreeRoot;
while(node)
{
if(numberdata)
node=node->left;
if(number>node->data)
node=node->right;
}
node=(TreeNode*)malloc(sizeof(TreeNode));
node->data=number;</span>
return true;
}
void traverse(TreeNode* node)
{
if(node)
{
cout<<node->data<<" ";
traverse(node->left);
traverse(node->right);
}
}
int main()
{
TreeNode* TreeRoot=CreateTree();
InsertDataIntoTree(TreeRoot,5);
InsertDataIntoTree(TreeRoot,4);
InsertDataIntoTree(TreeRoot,6);
InsertDataIntoTree(TreeRoot,3);
InsertDataIntoTree(TreeRoot,8);
InsertDataIntoTree(TreeRoot,1);
InsertDataIntoTree(TreeRoot,2);
InsertDataIntoTree(TreeRoot,9);
InsertDataIntoTree(TreeRoot,7);
traverse(TreeRoot);
return 0;
}
问题
1.首先是链表blog中有的函数参数问题,加一个&变为引用即可。
2.当TreeRoot==NULL时需要是树中没有一个节点的情况,需要插入数据,代码改为如下:
if(TreeRoot==NULL)
{
TreeRoot=(TreeNode*)malloc(sizeof(TreeNode));
TreeRoot->data=number;
TreeRoot->left=NULL;
TreeRoot->right=NULL;
}
3.就是插入的问题,这里我们声明了一个TreeNode* node去访问和操作对空间中的数据结构,当我们找到需要插入的树节点之后,比如我们插入的是4,找到5这个节点,所以我们需要在5这个节点的做子树上插入元素4,我之前的做法是node=node->left;将node赋值为5节点的左子树,这是实际上是node->left==NULL,所以我的语句等同于node=NULL,然后创建空间返回给node指针等等所有才操作都是通过node进行的,与5节点的左子树的指针完全脱离了关系,所以不可能通过头结点访问到新插入的节点。这里需要将新创建的节点的地址赋值个5节点的左子树这个操作。这里有两个思路:
(1)创建一个TreeNode* p指针几下开始插入操作之前的节点,在创建空间和赋值操作完成之后,使用
p->left=node进行赋值,但是这里我感觉要多声明一个指针,而且在执行p->left=node时还要进行一次判断才能知道到底是在左子树插入还是右子树插入,所以我采用了下一种方法:
(2)当找到需要插入的前一个节点之后,即
node=5这个树节点之后,直接在node即
5这个树节点
上进行操作,
代码如下:
while(node)
{
if(numberdata)
{
if(node->left==NULL)
{
node->left=(TreeNode*)malloc(sizeof(TreeNode));
node->left->data=number;
node->left->left=NULL;
node->left->right=NULL;
return true;
}
else
node=node->left;
}
else if(number>node->data)
{
if(node->right==NULL)
{
node->right=(TreeNode*)malloc(sizeof(TreeNode));
node->right->data=number;
node->right->left=NULL;
node->right->right=NULL;
return true;
}
else
node=node->right;
}
}
指针与内存
1.指针的定义如下形式
类型名* 指针名
如
char* p;
表示声明一个指向char类型变量的指针。
一个语句声明多个指针时*号不能省。如
char *p1,*p2;
而不能char* p1,p2;
2.在写数据结构时,我们要明白,我们创建的储存数据结构的内存空间是堆,而我们在程序中用于操作数据结构的指针通常是在main函数中声明的局部变量,即是储存在栈中的变量,而这个指针储存的是堆中的地址,而我们通过指针去操作数据结构,就是通过栈中的指针变量去访问和操作堆中的数据,这一点我们必须要明白。我们通常能操作的变量只有栈中的变量,在写数据结构时通常只用保证一个或几个变量作为数据结构的入口,而堆中的数据结构必须成为一个完整的数据结构。