二叉树总结

二叉树的部分总结,主函数在最下面,其中注明了有哪些二叉树的性质 ,所有的代码都是经过验证的均没有问题只是代码格式需要调整

#include<iostream>

#include<vector>

#include<stack>

#include<queue>

#include<algorithm>

#include<string>

#include<math.h>

using namespace std;

//创建树所使用的结构体

typedef struct BinaryTree

{

int val;

BinaryTree* lchild;

BinaryTree* rchild;

}binarytree,*BINARYTREE;

//创建二叉树

void creat_tree(BINARYTREE &root)

{

char ch;

ch = getchar();

if (ch == '#')

{

root = NULL;

}

else

{

root = new BinaryTree;

root->val = (ch-'0');

creat_tree(root->lchild);

creat_tree(root->rchild);

}

}

//层序遍历二叉树

BINARYTREE Sequence_travel(BINARYTREE root,int data)

{

if (root == NULL)

return root;

queue<BINARYTREE> que;

BINARYTREE p = NULL;

que.push(root);

while (!que.empty())

{

p = que.front();

if (p->val == data)

{

return p;

}

if (p->lchild != NULL)

{

que.push(p->lchild);

}

if (p->rchild != NULL)

{

que.push(p->rchild);

}

que.pop();

}

return NULL;

}

//前序遍历递归法

void Pre_Recursion(BINARYTREE root)

{

if (root == NULL)

return;

if (root != NULL)

{

cout << root->val << " ";

if (root->lchild != NULL)

{

Pre_Recursion(root->lchild);

}

if (root->rchild != NULL)

{

Pre_Recursion(root->rchild);

}

}

//cout << endl;

return;

}

//中序遍历递归法

void Mid_Recursion(BINARYTREE root)

{

if (root == NULL)

return;

if (root != NULL)

{

if (root->lchild != NULL)

{

Mid_Recursion(root->lchild);

}

cout << root->val << " ";

if (root->rchild != NULL)

{

Mid_Recursion(root->rchild);

}

}

return;

}

//后序遍历递归法

void Back_Recursion(BINARYTREE root)

{

if (root == NULL)

return;

if (root != NULL)

{

if (root->lchild != NULL)

{

Back_Recursion(root->lchild);

}

if (root->rchild != NULL)

{

Back_Recursion(root->rchild);

}

cout << root->val << " ";

}

return;

}

//前序遍历非递归法

void Pre_Not_Recursion(BINARYTREE root)

{

if (root == NULL)

return;

stack<BINARYTREE> sta;

BINARYTREE p = root;

while (!sta.empty() || p != NULL)

{

while (p)

{

cout << p->val << " ";

sta.push(p);

p = p->lchild;

}

if (!sta.empty())

{

p = sta.top();

sta.pop();

p = p->rchild;

}

}

return;

}

//中序遍历非递归法

void Mid_Not_Recursion(BINARYTREE root)

{

if (root == NULL)

return;

BINARYTREE p = root;

stack<BINARYTREE> sta;

while (!sta.empty() || p != NULL)

{

while (p)

{

sta.push(p);

p = p->lchild;

}

if (!sta.empty())

{

p = sta.top();

sta.pop();

cout << p->val << " ";

p = p->rchild;

}

}

return;

}

//后序遍历非递归法

void Back_Not_Recursion(BINARYTREE root)

{

if (root == NULL)

return;

stack<BINARYTREE> sta;

BINARYTREE cur, last_node;//一个表示当前值,一个表示最近刚访问的值

cur = root;

last_node = NULL;

while (cur)

{

sta.push(cur);

cur = cur->lchild;

}

while (!sta.empty())

{

cur = sta.top();

sta.pop();

//根节点被访问有两种情况,一种是没有右子数,另一种是右子树刚被访问

if (cur->rchild == NULL || cur->rchild == last_node)

{

cout << cur->val << " ";

last_node = cur;

}

else

{

//右子树要被访问则根节点需要再次入栈

sta.push(cur);

cur = cur->rchild;

while (cur)

{

sta.push(cur);

cur = cur->lchild;

}

}

}

return;

}

//二叉搜索树求公共祖先

void BinarySearchGetLastCommonAncestor(BINARYTREE root,BINARYTREE p,BINARYTREE q)

{

if (root == NULL || p == NULL || q == NULL)

{

cout << "不存在公共祖先" << endl;

return;

}

while (root != NULL)

{

if (root->val < p->val&&root->val < q->val)//p和q都在右子数

{

root = root->rchild;

}

else if (root->val > p->val&&root->val > q->val)//p和q都在左子数

{

root = root->lchild;

}

else

{

break;

}

}

cout << root->val << endl;

return;

}

//二叉树求公共祖先

BINARYTREE GetLastCommonAncestor(BINARYTREE root, BINARYTREE p, BINARYTREE q)

{

if (root == NULL || p == NULL || q == NULL)

{

return NULL;

}

if (p == root || q == root)

{

return root;

}

BINARYTREE left_node = GetLastCommonAncestor(root->lchild, p, q);

BINARYTREE right_node = GetLastCommonAncestor(root->rchild, p, q);

if (left_node&&right_node)

{

return root;

}

if (left_node == NULL)

{

return right_node;

}

else

{

return left_node;

}

}

//计算树的高度

int heigh(BINARYTREE root)

{

if (root == NULL)

return 0;

if (root->lchild == NULL&&root->rchild == NULL)

return 1;

return max(heigh(root->lchild), heigh(root->rchild)) + 1;

}

//二叉树节点最大距离

int TreeDistance(BINARYTREE root)

{

if (root == NULL)//节点为空,高度为0

return 0;

return max(heigh(root->lchild) + heigh(root->rchild) + 1, max(TreeDistance(root->lchild), TreeDistance(root->rchild)));

}

//打印双向链表

void print_two_list(BINARYTREE root)

{

BINARYTREE pre = NULL;

cout << "从前往后" << endl;

while (root != NULL)

{

pre = root;

cout << root->val << " ";

root = root->rchild;

}

cout << endl;

cout << "从后往前" << endl;

while (pre != NULL)

{

cout << pre->val << " ";

pre = pre->lchild;

}

cout << endl;

return;

}

//二叉树转双向链表的被调函数

void conver2list(BINARYTREE root, BINARYTREE &pointer)

{

if (root == NULL)

return;

if (root->lchild != NULL)

{

conver2list(root->lchild, pointer);

 

}

root->lchild = pointer;

if (pointer != NULL)

{

pointer->rchild = root;

}

pointer = root;

if (root->rchild != NULL)

{

conver2list(root->rchild, pointer);

}

}

//二叉树转双向链表

BINARYTREE conver(BINARYTREE root)

{

if (root == NULL)

return NULL;

BINARYTREE pointer = NULL;

conver2list(root, pointer);

while (pointer->lchild != NULL)

{

pointer = pointer->lchild;

}

return pointer;

}

//打印二叉树的所有路径

void print_binary_tree_all_path(vector<string> &res)

{

for (int i = 0; i < res.size(); i++)

{

cout << res[i] << endl;

}

return;

}

//二叉树所有路径的被调函数

void binaryTreePathsCore(BINARYTREE root, vector<string> &str, string strpath)

{

if (root == NULL)

{

return;

}

if (root->lchild == NULL&&root->rchild == NULL)

{

str.push_back(strpath);

return;

}

if (root->lchild != NULL)

{

binaryTreePathsCore(root->lchild, str, strpath + "->" + to_string(root->lchild->val));

}

if (root->rchild != NULL)

{

binaryTreePathsCore(root->rchild, str, strpath + "->" + to_string(root->rchild->val));

}

}

//二叉树的所有路径

vector<string> Binary_Tree_all_path(BINARYTREE root)

{

vector<string> result;

if (root == NULL)

return result;

binaryTreePathsCore(root, result, to_string(root->val));

return result;

}

 

//打印二叉树每层最大值

void print_per_layer_maxval(vector<int>&result)

{

if (result.size() == 0)

return;

cout << "每层的最大值" << endl;

for (int i = 0; i < result.size() - 1; i++)

{

cout << result[i] << " ";

}

cout << result[result.size() - 1] << endl;

return;

}

//二叉树每层的最大值

vector<int> binary_tree_per_layer_maxvalue(BinaryTree* root)

{

queue<BinaryTree*> que;

vector<int> result;

if (root == NULL)

return result;

que.push(root);

while (!que.empty())

{

int mid = que.size();

int max_val = INT_MIN;

for (int i = 0; i < mid; i++)

{

BinaryTree* node = que.front();

if (node->val > max_val)

max_val = node->val;

if (node->lchild)

que.push(node->lchild);

if (node->rchild)

que.push(node->rchild);

que.pop();

}

result.push_back(max_val);

}

return result;

}

//树的最大深度

int max_deepth(BINARYTREE root)

{

if (root == NULL)

return 0;

int leftDepth = max_deepth(root->lchild);

int rightDepth = max_deepth(root->rchild);

return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;

}

//树的最小深度

int min_deepth(BINARYTREE root)

{

if (root == NULL)

return 0;

if (root->lchild == NULL)

{

return min_deepth(root->rchild) + 1;

}

else if (root->rchild == NULL)

{

return min_deepth(root->lchild) + 1;

}

int leftDepth = min_deepth(root->lchild) + 1;

int rightDepth = min_deepth(root->rchild) + 1;

return leftDepth > rightDepth ? rightDepth : leftDepth;

 

}

//叶子节点的数量

void leaf_node_num(BINARYTREE root, int &k)

{

if (root == NULL)

return;

else

{

if (root->lchild == NULL&&root->rchild == NULL)

{

k++;

}

if (root->lchild)

{

leaf_node_num(root->lchild, k);

}

if (root->rchild)

{

leaf_node_num(root->rchild, k);

}

}

}

//判断二叉树是否为完全二叉树

bool IsComplete(BINARYTREE root)

{

if (root == NULL)

return false;

queue<BINARYTREE> que;

que.push(root);

while (!que.empty())

{

BINARYTREE p = que.front();

//如果该节点的两个孩子都在,则直接pop

if (p->lchild&&p->rchild)

{

que.pop();

que.push(p->lchild);

que.push(p->rchild);

}

//如果该节点的左孩子为空,右孩子不为空,则返回false

if (p->lchild == NULL&&p->rchild != NULL)

{

return false;

}

//如果左孩子不为空,右孩子为空或该节点为叶子节点,则该节点后面的节点都是叶子节点

if ((p->lchild&&p->rchild == NULL) || (p->lchild == NULL&&p->rchild == NULL))

{

que.pop();

//则该节点之后的所有节点都是叶子节点

while (!que.empty())

{

p = que.front();

if (p->lchild == NULL&&p->rchild == NULL)

{

que.pop();

}

else

{

return false;

}

}

return true;

}

}

return true;

}

//非递归求二叉树的深度

int deepth_not_recusion(BINARYTREE root)

{

queue<BINARYTREE>que;

if (root == NULL)

return 0;

que.push(root);

int result = 0;

while (!que.empty())

{

        int len = que.size();

        result++;

    while (len--)

    {

         BINARYTREE temp = que.front();

        que.pop();

        if (temp->lchild)

               que.push(temp->lchild);

       if (temp->rchild)

              que.push(temp->rchild);

       }

}

return result;

}

//求一棵树的最大宽度

void getTreeMaxWidth(BINARYTREE root, int &height, int &width)

{

if (root == NULL)

{

        height = 0;

        width = 0;

}

int max_val = -1;

height = 0;

width = 0;

queue<BINARYTREE> que;

BINARYTREE p = NULL;

BINARYTREE q = root;

que.push(root);

while (!que.empty())

{

        p = que.front();//返回队列中的第一个元素

        width++;

        if (p)

        {

            que.pop();

            if (p->lchild)

            que.push(p->lchild);

            if (p->rchild)

            que.push(p->rchild);

            if (p == q)

            {

                  if (!que.empty())

                  {

                           q = que.back();

                   }

                   height++;

                  if (width > max_val)

                   {

                            max_val = width;

                            width = 0;

                   }

           }

      }

}

width = max_val;

cout << width << endl;

}

int main(void)

{

/**************创建一棵二叉树***********/

注意:本例使用的创建树的方式为前序遍历的方式创建

例如:一棵树为:

则输入的时候按照前序遍历的方式输入,即:620##43##5##87##9##,其中#代表叶子节点0,3,5,7,9的左右孩子,其为空。

BinaryTree* root = NULL;

creat_tree(root);

/**************前序遍历递归法***********/

Pre_Recursion(root);

cout << endl;

/**************中序遍历递归法***********/

Mid_Recursion(root);

cout << endl;

/**************后序遍历递归法***********/

Back_Recursion(root);

cout << endl;

/**************前序遍历非递归法***********/

Pre_Not_Recursion(root);

cout << endl;

/**************中序遍历非递归法***********/

Mid_Not_Recursion(root);

cout << endl;

/**************后序遍历非递归法***********/

Back_Not_Recursion(root);

cout << endl;

/**************二叉搜索树最近公共祖先***********/

BINARYTREE p, q;

p = Sequence_travel(root, 6);

q = Sequence_travel(root, 6);

BinarySearchGetLastCommonAncestor(root, p, q);

/**************二叉树最近公共祖先***********/

BINARYTREE p1, q1, pq;

p1 = Sequence_travel(root, 0);

q1 = Sequence_travel(root, 9);

pq=GetLastCommonAncestor(root, p1, q1);

if (pq == NULL)

        cout << "不存在公共祖先" << endl;

else

        cout << "二叉树最近公共祖先:" << pq->val << endl;

/**************二叉树节点最大距离***********/

cout << "二叉树节点最大距离:" << TreeDistance(root) << endl;

/**************二叉树转双向链表***********/(注意:此项必须单独运行,因为已经转换为了双向链表就不具备二叉树的性质)

//BINARYTREE pq1;

//pq1=conver(root);

//print_two_list(pq1);

/**************二叉树的所有路径***********/

vector<string> all_path;

all_path=Binary_Tree_all_path(root);

print_binary_tree_all_path(all_path);

/**************二叉树每一层中最大值***********/

vector<int> max_value;

max_value = binary_tree_per_layer_maxvalue(root);

print_per_layer_maxval(max_value);

/**************二叉树最大深度***********/

cout << "二叉树最大深度:" << max_deepth(root) << endl;

/**************二叉树最小深度***********/

cout << "二叉树最小深度:" << min_deepth(root) << endl;

/**************二叉树深度非递归***********/

cout <<"二叉树深度:"<< deepth_not_recusion(root) <<endl;

/**************叶子节点的数量***********/

int k = 0;

leaf_node_num(root,k);

cout << "叶子节点数量:" << k << endl;

/**************判断一棵树是否为完全二叉树***********/

        if (IsComplete(root))

        {

            cout << "true" << endl;

        }

        else

        {

            cout << "false" << endl;

        }

/**************求一棵树的宽度***********/

        int height, width;//定义树的高度和最大宽度

        getTreeMaxWidth(root, height, width);

        cout << "高度为:" << height << endl;

        cout << "最大宽度为:" << width << endl;

        return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值