标签:oid nod asto sizeof create temp 二叉树 遍历 put
本二叉树的功能为:创建二叉树,递归先根,中根,后根遍历,二叉树节点总数目,二叉树深度,二叉树叶子节点数,复制二叉树,寻找某节点是否存在并输出,交换左右子树,插入某节点。
下面介绍每种算法的主要思路:
1.创建二叉树:首先引入申请空间的指针节点。设叶子节点的左右子树均为零,每当遇到输入的数字为零时,将指针赋值为NULL,否则依次创建左右子树。
2.递归遍历:如根节点不为空,则依次访问其左右子树。
3.二叉树节点总数:根节点为空返回零,否则返回1+左右子树节点总数。
4.二叉树深度:根节点为空返回零,否则返回1+左右子树中深的那棵树的深度。
5.二叉树叶子节点总数:递归有两个出口,若根节点为空,返回零;若根节点的左右子树均为空,返回1。否则返回左右子树之和。
6.复制二叉树:类似创建二叉树。
7.寻找节点是否存在:重点!
Node*Find(Node*root,int item){
Node*p=NULL; //需要引入一个空指针
if(root==NULL) return NULL;
if(root->data==item) {
return root;
}
p=Find(root->Left,item); //用指针p来储存左子树的寻找结果
if(p!=NULL) return p; //若p不为空,说明在左子树中找到该节点,返回该节点
return Find(root->Right,item); //否则返回右子树的寻找结果(无论是该节点指针或者NULL,最终将会有一个被返回)
}
(1)错误示范:警示!
Node*Find(Node*root,int item){
if(root==NULL) return NULL;
if(root->data==item) {
return root;
}
return Find(root->Left,item);
return Find(root->Right,item);
}
错误原因:该算法最终由于第一个return的存在,最终只能返回左子树左面的那部分。
(2)错误示范:警示!
Node*Find(Node*root,int item){
if(root==NULL) return NULL;
if(root->data==item) {
return root;
}
Find(root->Left,item);
Find(root->Right,item);
}
错误原因:因为没有return导致递归不能正常进行。
8.交换左右子树:左右子树只要有一个不为空就交换其左右子树,若左子树不为空,交换左子树;若右子树不为空,交换右子树。
9.插入节点:利用Find函数找到相应节点并返回其指针,进行插入。
Node*Addition(Node*root,int item){ //截取插入函数的一部分
Node*r=root;
Node*p=NULL;
Node*q=NULL;
q = (Node*)malloc(sizeof(Node));
q->data=item;
q->Left=p->Left;
p->Left=q; //重点!p->Left=q而不是q=p->Left
q->Right=NULL;
}
以下是完整代码:
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct BinaryTreeNode
{
int data;
struct BinaryTreeNode *Left;
struct BinaryTreeNode *Right;
}Node;
//创建二叉树,顺序依次为中间节点->左子树->右子树
Node* createBinaryTree()
{
Node *p;
int ch;
cin>>ch;
if(ch == 0) //如果到了叶子节点,接下来的左、右子树分别赋值为0
{
p = NULL;
}
else
{
p = (Node*)malloc(sizeof(Node));
p->data = ch;
p->Left = createBinaryTree(); //递归创建左子树
p->Right = createBinaryTree(); //递归创建右子树
}
return p;
}
//先序遍历
void preOrderTraverse(Node* root)
{
if( root )
{
cout<<root->data<<‘ ‘;
preOrderTraverse(root->Left);
preOrderTraverse(root->Right);
}
}
//中序遍历
void inOrderTraverse(Node* root)
{
if( root )
{
inOrderTraverse(root->Left);
cout<<root->data<<‘ ‘;
inOrderTraverse(root->Right);
}
}
//后序遍历
void lastOrderTraverse(Node* root)
{
if( root )
{
lastOrderTraverse(root->Left);
lastOrderTraverse(root->Right);
cout<<root->data<<‘ ‘;
}
}
//二叉树节点总数目
int Nodenum(Node* root)
{
if(root == NULL)
{
return 0;
}
else
{
return 1+Nodenum(root->Left)+Nodenum(root->Right);
}
}
//二叉树的深度
int DepthOfTree(Node* root)
{
if(root)
{
return DepthOfTree(root->Left)>DepthOfTree(root->Right)?DepthOfTree(root->Left)+1:DepthOfTree(root->Right)+1;
}
if( root == NULL )
{
return 0;
}
}
//二叉树叶子节点数
int Leafnum(Node* root)
{
if(!root)
{
return 0;
}
else if( (root->Left == NULL) && (root->Right == NULL) )
{
return 1;
}
else
{
return (Leafnum(root->Left) + Leafnum(root->Right)) ;
}
}
//复制二叉树
Node*Copy(Node*copy){
Node*p;
if(copy==NULL) p=NULL;
else{
p=(Node*)malloc(sizeof(Node));
p->data=copy->data;
p->Left=Copy(copy->Left);
p->Right=Copy(copy->Right);
return p;
}
}
//寻找节点
Node*Find(Node*root,int item){
Node*p=NULL;
if(root==NULL) return NULL;
if(root->data==item) {
return root;
}
p=Find(root->Left,item);
if(p!=NULL) return p;
return Find(root->Right,item);
}
//输出是否存在该节点
void Output(Node*root){
if(root!=NULL) cout<<"Find it";
else cout<<"No find";
}
//交换左右子树
Node*Exchange(Node*root){
if(root->Left!=NULL||root->Right!=NULL){
Node*temp=root->Left;
root->Left=root->Right;
root->Right=temp;
}
if(root->Left) Exchange(root->Left);
if(root->Right) Exchange(root->Right);
return root;
}
//插入某节点
Node*Addition(Node*root,int item){
int location;
Node*r=root;
Node*p=NULL;
Node*q=NULL;
if(root==NULL) return NULL;
if(item==0){
cout<<"无法插入该节点";
return root;
}
cout<<"请输入要插入节点的位置";
cin>>location;
p=Find(r,location);
if(p==NULL){
cout<<"不存在该节点要插入的位置";
cout<<endl;
return root;
}
q = (Node*)malloc(sizeof(Node));
q->data=item;
q->Left=p->Left;
p->Left=q;
q->Right=NULL;
return root;
}
//主函数
int main()
{
int number=2;
int number1=9;
Node *addition=NULL;
Node *output=NULL;
Node *exchange=NULL;
Node *root = NULL;
Node *example=NULL;
Node *example_addition=NULL;
Node *example_exchange=NULL;
root = createBinaryTree();
example=Copy(root);
example_addition=Copy(root);
example_exchange=Copy(root);
addition=Addition(example_addition,number1);
exchange=Exchange(example_exchange);
printf("二叉树建立成功");
cout<<endl;
cout<<"二叉树总节点数为:"<<Nodenum(root)<<endl;
cout<<"二叉树深度为:"<<DepthOfTree(root)<<endl;
cout<<"二叉树叶子节点数为:"<<Leafnum(root)<<endl;
cout<<"前序遍历结果:"<<endl;
preOrderTraverse(root);
cout<<endl;
cout<<"中序遍历结果:"<<endl;
inOrderTraverse(root);
cout<<endl;
cout<<"后序遍历结果:"<<endl;
lastOrderTraverse(root);
cout<<endl;
cout<<"添加后前序遍历结果:"<<endl;
preOrderTraverse(addition);
cout<<endl;
cout<<"添加后中序遍历结果:"<<endl;
inOrderTraverse(addition);
cout<<endl;
cout<<"添加后后序遍历结果:"<<endl;
lastOrderTraverse(addition);
cout<<endl;
cout<<"复制二叉树前序遍历结果:"<<endl;
preOrderTraverse(example);
cout<<endl;
cout<<"复制二叉树中序遍历结果:"<<endl;
inOrderTraverse(example);
cout<<endl;
cout<<"复制二叉树后序遍历结果:"<<endl;
lastOrderTraverse(example);
cout<<endl;
cout<<"交换后二叉树前序遍历结果:"<<endl;
preOrderTraverse(exchange);
cout<<endl;
cout<<"交换后二叉树中序遍历结果:"<<endl;
inOrderTraverse(exchange);
cout<<endl;
cout<<"交换后二叉树后序遍历结果:"<<endl;
lastOrderTraverse(exchange);
cout<<endl;
output=Find(root,number);
Output(output);
return 0;
}
标签:oid nod asto sizeof create temp 二叉树 遍历 put
原文地址:https://www.cnblogs.com/xiaoshuita/p/10080767.html