在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序数。二叉树的每个结点至多只有二棵子树(不存在出度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为
c++代码实现基本操作:
//二叉树
#include<cstdio>
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
#define max(a,b) (((a)>(b))?(a):(b))
const int MAX = 50;
struct Node
{
char data;//数据
Node *lchild;//左孩子
Node *rchild;//右孩子
Node(){
lchild = rchild = NULL;
}
};
class Tree
{
public:
Tree()
{
root = createTree();
}
~Tree(void)//析构
{
destroyTree(root);
root = NULL;
}
Node* getRoot()const //返回根
{
return root;
}
void destroyTree(Node *&h);//摧毁
Node* createTree();//构造
void preOrder(Node* &p);//前序
void inOrder(Node* &p);//中序
void postOrder(Node* &p);//后序
void preOrderN(Node* p);//非递归前序,栈模拟
void inOrderN(Node* p);//非递归中序
void postOrderN(Node* p);//非递归后序
void levelOrder(Node* &p);//层序
void printInTree(Node* &p, int level);//树状打印
int treeHeight(Node* &p);//树高度
int numOfLeaf(Node* &p);//叶子节点数目
int numOfNode(Node* &p);//节点数目
int numOfNLeaf(Node* &p);//非叶子节点数目
private:
Node *root;
};
Node* Tree::createTree()//前序建立
{
Node *root;
char ch;
cin >> ch;
if(ch == '#')
root = NULL;
else
{
root = new Node;
root->data = ch;
root->lchild = createTree();
root->rchild = createTree();
}
return root;
}
void Tree::preOrder(Node* &p)//前序
{
if(p!=NULL)
{
printf("%c ",p->data);
preOrder(p->lchild);
preOrder(p->rchild);
}
else
return;
}
void Tree::inOrder(Node* &p)//中序
{
if(p!=NULL)
{
inOrder(p->lchild);
printf("%c ",p->data);
inOrder(p->rchild);
}
else
return;
}
void Tree::postOrder(Node* &p)//后序
{
if(p!=NULL)
{
postOrder(p->lchild);
postOrder(p->rchild);
printf("%c ",p->data);
}
else
return;
}
void Tree::levelOrder(Node* &p)//层序
{
queue<Node*> qnode;
if(p!=NULL)
qnode.push(p);
while(!qnode.empty())
{
Node* tmp;
tmp = qnode.front();
printf("%c ",tmp->data);
if(tmp->lchild)
qnode.push(tmp->lchild);
if(tmp->rchild)
qnode.push(tmp->rchild);
qnode.pop();
}
}
void Tree::inOrderN(Node* p)//中序非递归
{
stack<Node*> st;
while(p!=NULL || !st.empty())
{
while(p)
{
st.push(p);
p = p->lchild;
}
if(!st.empty())
{
p = st.top();
st.pop();
printf("%2c", p->data);
p = p->rchild;
}
}
}
void Tree::preOrderN(Node* p)//前序非递归
{
stack<Node*> st;
while(p!=NULL || !st.empty())
{
while(p)
{
printf("%2c", p->data);
st.push(p);
p = p->lchild;
}
if(!st.empty())
{
p =st.top();
st.pop();
p = p->rchild;
}
}
}
void Tree::postOrderN(Node* p)//后序非递归
{
stack<Node*> st;
Node *q;
q = NULL;
while(p!=NULL || !st.empty())
{
while(p)//p不为空访问根节点 遍历左子树
{
st.push(p);
p = p->lchild;
}
if(!st.empty())
{
p = st.top();
if(p->rchild==NULL || p->rchild==q)//没有左子树或者已经访问过左子树
{
printf("%2c", p->data);
q= p;
p = NULL;
st.pop();
}
else
p = p->rchild;
}
}
}
void Tree::printInTree(Node* &p, int level)//树状打印
{
int i;
if(p == NULL)
return;
printInTree(p->rchild,level+1);//打印右子树
for(i=0; i<level; ++i)
{
printf(" ");
}
printf("%c\n", p->data);
printInTree(p->lchild, level+1);
}
void Tree::destroyTree(Node* &h)
{
if(h!=NULL)
{
destroyTree(h->lchild);
destroyTree(h->rchild);
delete h;
}
}
int Tree::treeHeight(Node* &p)//树高
{
if(p==NULL)
return 0;
else
return 1+max(treeHeight(p->lchild),treeHeight(p->rchild));
}
int Tree::numOfLeaf(Node* &p)//叶子几点数目
{
if(p==NULL)
return 0;
else if(p->lchild==NULL && p->rchild==NULL)
return 1;
else
return numOfLeaf(p->lchild)+numOfLeaf(p->rchild);
}
int Tree::numOfNode(Node* &p)//节点数目
{
if(p==NULL)
return 0;
else
return 1+numOfNode(p->lchild)+numOfNode(p->rchild);
}
int Tree::numOfNLeaf(Node* &p)//非叶子节点数目
{
if(p==NULL || (p->rchild==NULL && p->lchild==NULL))
return 0;
else
return 1+numOfNLeaf(p->rchild) + numOfNLeaf(p->rchild);
}
int
main(void)
{
Tree t;
Node *root = t.getRoot();
printf("前序递归为");
t.preOrder(root);
printf("\n前序非递归为");
t.preOrderN(root);
printf("\n中序递归为");
t.inOrder(root);
printf("\n中序非递归为");
t.inOrderN(root);
printf("\n后序递归为");
t.postOrder(root);
printf("\n后序非递归为");
t.postOrderN(root);
printf("\n层序为");
t.levelOrder(root);
printf("\n左转90后树状打印\n");
t.printInTree(root,1);
printf("\n树高%d", t.treeHeight(root));
printf("\n叶子节点数目%d", t.numOfLeaf(root));
printf("\n节点数目%d", t.numOfNode(root));
printf("\n非叶子节点数目%d", t.numOfNLeaf(root));
return 0;
}
本文介绍了二叉树的基本概念,包括左子树和右子树的定义,以及二叉树在数据结构中的应用,如二叉查找树和二叉堆。同时,文章提供了使用C++实现二叉树基本操作的示例。

1万+

被折叠的 条评论
为什么被折叠?



