//也可以参考该文章:https://blog.youkuaiyun.com/guojz049/article/details/51597834
定义二叉树结构体
typedef struct BinaryTreeNode
{
TelemType data;
struct BinaryTreeNode *Left;
struct BinaryTreeNode *Right;
}Node;
创建二叉树
Node* createBinaryTree()
{
Node *p;
TelemType 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;
}
二叉树节点总数目(递归)
int Nodenum(Node* root)
{
if(root == NULL)
{
return 0;
}
else
{
return 1+Nodenum(root->Left)+Nodenum(root->Right);
}
}
二叉树的深度(递归)
int DepthOfTree(Node* root) //递归判断左子树与右子树的度,取大的一边+1
{
if(root)
{
return DepthOfTree(root->Left)>DepthOfTree(root->Right)?DepthOfTree(root->Left)+1:DepthOfTree(root->Right)+1;
}
if( root == NULL )
{
return 0;
}
}
二叉树的深度(非递归-广度遍历思想)
int DepthOfTree(TreeNode* pRoot)
{
if (pRoot == NULL)
return 0;
queue<TreeNode *> q;
q.push(pRoot);
int res = 0;
while (!q.empty())
{
int size = q.size();
for (int i = 0; i < size; ++i)
{
TreeNode *tmp = q.front();
q.pop();
if (tmp->left)
{
q.push(tmp->left);
}
if (tmp->right)
{
q.push(tmp->right);
}
}
res++;
}
return res;
二叉树的叶子节点数(递归)
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)) ;
}
}
二叉树的叶子节点数(非递归方式)
在遍历二叉树( 前序、中序、后序、按层遍历)时,判断当前访问的节点是不是叶子节点,然后对叶子节点求和即可。
二叉树遍历(递归与非递归栈方法)
1.先序遍历(根左右)
void preOrderTraverse(Node* root)
{
if( root )
{
cout<<root->data<<' '; //打印输出在前
preOrderTraverse(root->Left);
preOrderTraverse(root->Right);
}
}
2.中序遍历(左根右)
void inOrderTraverse(Node* root)
{
if( root )
{
inOrderTraverse(root->Left);
cout<<root->data<<' '; //打印输出在中
inOrderTraverse(root->Right);
}
}
3.后序遍历(左右根)
void lastOrderTraverse(Node* root)
{
if( root )
{
lastOrderTraverse(root->Left);
lastOrderTraverse(root->Right);
cout<<root->data<<' '; //打印输出在后
}
}
1.中序遍历
void midPrint_l(TreeNode* root)
{
stack<TreeNode*> s;
TreeNode *cur = root;
while(!s.empty() || cur != NULL) //判断栈与节点是否为空
{
while(cur != NULL)
{
s.push(cur); //一直遍历左子树,并将节点压入栈中
cur = cur->left;
}
cur = s.top(); //左子树遍历完之后,再将节点弹出栈,并且打印
s.pop();
cout<<cur->val<<" ";
cur = cur->right; //最后在遍历右节点
}
}
2.前序遍历
void prePrint_l(TreeNode* root)
{
stack<TreeNode*> s;
TreeNode *cur = root;
while(!s.empty() || cur != NULL)
{
while(cur != NULL)
{
cout<<cur->var<<" ";
s.push(cur);
cur = cur->left;
}
cur = s.top();
s.pop();
cur = cur->right;
}
}
3.后序遍历
//1. p如果是叶子节点,直接输出
//2. p如果不是叶子节点,且孩子都已经访问过(即前一个访问的结点是当前结点的左孩子或者右孩子),直接输出
//3. p如果不是叶子节点,且孩子都没有访问过,则按照右孩子,左孩子的顺序依次入栈
public static void postOrder(TreeNode root) {
if(root==null) return;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode current = null;
TreeNode pre = null;
stack.push(root);
while(!stack.isEmpty()) {
current = stack.peek();
if((current.left==null && current.right==null) || (pre!=null && (pre == current.left || pre == current.right))) {
System.out.println(current.val);
stack.pop();
pre = current;
}
else {
if(current.right!=null) {
stack.push(current.right);
}
if(current.left != null) {
stack.push(current.left);
}
}
}
}
二叉树的层序遍历
队列实现:首先从根节点开始,将根节点入队,然后执行循环:节点出队,访问该节点,其左右儿子入队
/*二叉树结构体,并且构建了有参构造函数*/
struct BinaryTree{
int vec;
BinaryTree* left;
BinaryTree* right;
BinaryTree(int data)
:vec(data), left(nullptr), right(nullptr){
}
};
/*队列实现层序遍历*/
void printTree(BinaryTree* arr[])
{
queue<BinaryTree*> rel; //定义一个队列,数据类型是二叉树指针
rel.push(arr[0]); //首先将根节点入队
while (!rel.empty()) //循环做三件事
{
BinaryTree* front = rel.front(); //1.节点出队
printf("%d\n", front->vec); //2.访问该节点
rel.pop(); //3.其左右儿子入队
if (front->left != nullptr) //判断最前面的左节点是否为空,不是则放入队列
rel.push(front->left);
if (front->right != nullptr)//判断最前面的右节点是否为空,不是则放入队列
rel.push(front->right);
}
}