问题描述实验要求
基于教材内容,实现二叉树。
基本要求
需要基于左子结点/右兄弟结点表示法或二叉链表来实现二叉树ADT
需要实现二叉树的各个基本操作。
一、简要分析:
实现二叉树的方式比较多,因为二叉树的种类就蛮多的,本人是基于BST的规则来实现的,二叉树的基本操作有:查找和插入。删除比较复杂,删除的话需要调整二叉树,使得它平衡,本人这里没有实现删除这一操作。查找分为:前序遍历、中序遍历、后序遍历、层次遍历。
二、具体实现:
如何构造一棵二叉树呢?
建树函数的具体实现如下:
void Btree::create_Btree(int x)
{
tree *newnode=new tree;
newnode->data=x;
newnode->right=newnode->left=NULL;
if(root==NULL)
root=newnode;
else
{
tree *back;//指向下一个子节点的父节点位置
tree *current=root;//前一个节点 作为当前位置
while(current!=NULL)
{
back=current;//先记录父节点的位置
if(current->data<x)//如果父节点的数据 小于待插入数据元素
current=current->left;//curr 往左边走,反之往右边走
else
current=current->right;
}
if(back->data<x)//比较与父节点数据元素与待插入数据元素的大小
back->left=newnode;//把元素大的插在左边,反之插在右边
else
back->right=newnode;
}
}
不懂这个规则可以先去了解一下BST树。
下面是四种遍历的实现:
前序遍历就是:父-->左子树-->右子树 简记为:根左右
中序遍历就是:左根右
后序遍历:左右根
层序遍历我就不多说啦,按层遍历。
void BTree::PreorderTravel_tree(tree* temp)//前序
{
if(temp!=NULL)
{
cout<<temp->data<<" ";
PreorderTravel_tree(temp->left_node);
this->PreorderTravel_tree(temp->right_node);
}
else return ;
}
void BTree::InorderTravel_tree(tree* temp)//中序
{
if(temp!=NULL)
{
this->InorderTravel_tree(temp->left_node);
cout<<temp->data<<" ";
this->InorderTravel_tree(temp->right_node);
}
else return ;
}
void BTree::PosorderTravel_tree(tree* temp)//后序
{
if(temp!=NULL)
{
this->PosorderTravel_tree(temp->left_node);
this->PosorderTravel_tree(temp->right_node);
cout<<temp->data<<" ";
}
else return ;
}
int BTree::CenciTravel_tree(tree* temp,int level)//层次
{
if(temp==NULL|| level<0)
{
return 0;
}
else if(level == 0)
{
cout<<temp->data<<" ";
return 1;
}
else
{
return CenciTravel_tree(temp->left_node,level-1)+CenciTravel_tree(temp->right_node,level-1);
}
}
插入一个节点:
实现思路:先判断新节点的值与根节点的大小关系,决定新节点放在左子树还是右子树。依此比较下去,直到找到可以放的位置,嗅到了递归的味道,emmm其实就是用递归。我们建树的时候就是这样干的,所以插入新节点只需调用前面的creat函数即可。
下面附完整代码:
//main.cpp
#include<iostream>
#include<cstring>
#include"BTree.h"
using namespace std;
int main()
{
BTree btree;//定义一个对象
int ch[]={100,100,4,3,15,35,6,1};
int len=sizeof(ch)/sizeof(ch[0]);
cout<<"待插入节点排序:"<<endl;
for(int i=0;i<len;i++)
{
cout<<ch[i]<<" ";
btree.Create_BTree(ch[i]);
}
cout<<endl;
cout<<"前序遍历:"<<endl;
btree.Display_Pre();
cout<<"中序遍历:"<<endl;
btree.Display_In();
cout<<"后序遍历:"<<endl;
btree.Display_Pos();
cout<<"节点个数:"<<endl;
cout<<btree.count_node(btree.root)<<endl;
cout<<"叶子个数:"<<endl;
cout<<btree.count_leaf(btree.root)<<endl;
cout<<"层次遍历:"<<endl;
int h = btree.Gethight(btree.root);
btree.CenciTravel_tree(btree.root,h);
btree.LevelOrder(btree.root);
return 0;
}
//BTree.h
#ifndef _BTREE_INCLUDE_
#define _BTREE_INCLUDE_
#include<iostream>
using namespace std;
class tree{
public:
int data;
tree* left_node;
tree* right_node;
};
class BTree{
private:
static int node_count;
static int leaf_count;
public:
tree* root;
BTree(){ root = NULL;}
void Create_BTree(int);
void PreorderTravel_tree(tree*);
void InorderTravel_tree(tree*);
void PosorderTravel_tree(tree*);
int CenciTravel_tree(tree*,int);
int count_node(tree*);
int count_leaf(tree*);
int count_node_DP(tree*,int);
void Display_Pre(){ this->PreorderTravel_tree(root);cout<<endl;}
void Display_In(){this->InorderTravel_tree(root);cout<<endl;}
void Display_Pos(){this->PosorderTravel_tree(root);cout<<endl;}
int Gethight(tree*);
void LevelOrder(tree*);
};
#endif
//BTree.cpp
#include"BTree.h"
int BTree::node_count=0;
int BTree::leaf_count=0;
void BTree::Create_BTree(int ch)
{
tree* newnode = new tree;
newnode->data = ch;
newnode->left_node=newnode->right_node = NULL;
if(root==NULL)
{
root = newnode;
}
else
{
tree* current = root;
tree* back;
while(current!=NULL)
{
back = current;
if(ch > current->data)
{
current=current->left_node;
}
else
{
current=current->right_node;
}
}
if(ch > back->data)
{
back->left_node = newnode;
}
else
{
back->right_node = newnode;
}
}
}
void BTree::PreorderTravel_tree(tree* temp)
{
if(temp!=NULL)
{
cout<<temp->data<<" ";
PreorderTravel_tree(temp->left_node);
this->PreorderTravel_tree(temp->right_node);
}
else return ;
}
void BTree::InorderTravel_tree(tree* temp)
{
if(temp!=NULL)
{
this->InorderTravel_tree(temp->left_node);
cout<<temp->data<<" ";
this->InorderTravel_tree(temp->right_node);
}
else return ;
}
void BTree::PosorderTravel_tree(tree* temp)
{
if(temp!=NULL)
{
this->PosorderTravel_tree(temp->left_node);
this->PosorderTravel_tree(temp->right_node);
cout<<temp->data<<" ";
}
else return ;
}
int BTree::CenciTravel_tree(tree* temp,int level)
{
if(temp==NULL|| level<0)
{
return 0;
}
else if(level == 0)
{
cout<<temp->data<<" ";
return 1;
}
else
{
return CenciTravel_tree(temp->left_node,level-1)+CenciTravel_tree(temp->right_node,level-1);
}
}
int BTree::count_node(tree* temp)
{
if(temp==NULL) return 0;
else
return this->count_node(temp->left_node)+this->count_node(temp->right_node)+1;
}
int BTree::count_leaf(tree* temp)
{
if(temp==NULL) return 0;
else
{
if(temp->left_node==NULL&&temp->right_node==NULL) return leaf_count+=1;
else
{
this->count_leaf(temp->left_node);
this->count_leaf(temp->right_node);
}
return leaf_count;
}
}
int BTree::Gethight(tree* temp)
{
if(temp==NULL) return 0;
int lefthight = Gethight(temp->left_node);
int righthight = Gethight(temp->right_node);
if(lefthight > righthight)
{
return lefthight+1;
}
return righthight+1;
}
void BTree::LevelOrder(tree* temp)
{
for(int i=0;i<this->Gethight(root);i++)
{
cout<<"µÚ"<<i+1<<"²ã£º";
if(!this->CenciTravel_tree(root,i))
break;
cout<<endl;
}
}