赞
踩
学二叉树就是学递归,多画图,多画图
对一颗二叉树的操作,就是对当前结点的操作,结合需求,进行递归。
树,一个根节点,有多个子节点:
每个子结点也可以作为双亲(根)节点,有多个子节点。
当两个孩子(子)节点有一个共同的双亲结点,则称这两个节点互为兄弟节点。
一个双亲节点所拥有的孩子节点个数,称为该节点的“度”。
度不为0的节点,也称为为分支节点;度时0的节点,叫做叶节点或者终端节点。
根节点所在的层一般称为第一层;该树最多有几层,称作树的高度或者深度。–h或k
根节点以下的所有节点都是根节点的子孙节点;
多棵不相交的树的集合称作森林。
从一个根节点出发到最后一层的子孙节点,这一条路径称作该根节点的子树。
经典表示法,每个节点都有一个孩子节点指向自己第一个的孩子,有一个兄弟节点指向自己的兄弟。
应用场景,文件系统等。
typedef int DataType;
struct Node
{
struct Node* _firstChild1; 第一个孩子结点
struct Node* _pNextBrother; 指向其下一个兄弟结点
DataType _data; 结点中的数据域
};
每个节点最多有两个节点的树。
以上都是将二叉树的根节点作为第一层的性质。
先把二叉树填充至满二叉树,空的用空表示。
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> //数据 typedef char BinaryTrDataType; typedef struct BinaryTreeNode { struct BinaryTreeNode* _left; 指向左孩子 struct BinaryTreeNode* _right; 指向右孩子 BinaryTrDataType data; }BTNode; 二叉树结点类型 //申请并初始化一个二叉树节点 BTNode* AskBinTreeNode(BinaryTrDataType x) { BTNode* root = (BTNode*)malloc(sizeof(BTNode)); if (root == NULL) { printf("AskBTNode Failed\n"); exit(-1); } root->_left = root->_right = NULL; root->data = x; return root; }
BTNode* CreateBinTree()
{
BTNode* ra = AskBinTreeNode('A');
BTNode* rb = AskBinTreeNode('B');
BTNode* rc = AskBinTreeNode('C');
BTNode* rd = AskBinTreeNode('D');
BTNode* re = AskBinTreeNode('E');
BTNode* rf = AskBinTreeNode('F');
ra->_left = rb;
ra->_right = rc;
rb->_left = rd;
rb->_right = re;
rc->_right = rf;
return ra;
}
int main() { //创建一个二叉树 BTNode* root = CreateBinTree(); printf("二叉树的前序遍历:\n"); BinTreeFrontErgodic(root); printf("\n"); printf("\n"); printf("二叉树的中序遍历:\n"); BinTreeCentralErgodic(root); printf("\n"); printf("\n"); printf("二叉树的后序遍历:\n"); BinTreeRearErgodic(root); printf("\n"); printf("\n"); return 0; }
void BinTreeFrontErgodic(BTNode* root)
{
递归结束的标志,遍历整个树,最后那个节点
的左右孩子都为空就停止搜寻。
if (root == NULL)
{
printf("NULL ");
return;
}
如果根节点不为空,则打印根存放的数据
printf("%c ", root->data);
BinTreeFrontErgodic(root->_left);
BinTreeFrontErgodic(root->_right);
}
void BinTreeCentralErgodic(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
BinTreeCentralErgodic(root->_left);
printf("%c ", root->data);
BinTreeCentralErgodic(root->_right);
}
void BinTreeRearErgodic(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
看他左孩子是不是空
BinTreeRearErgodic(root->_left);
左孩子找完,则找右孩子
BinTreeRearErgodic(root->_right);
此函数的节点永远是这一层的根,最后打印
printf("%c ", root->data);
}
int BinTreeNodeSize(BTNode* root) { //若根结点为空,返回0 if (root == NULL) { return 0; } /若根不是空,则统计它左右孩子结点的个数; /如果我左右孩子结点都为空,证明下面没有节点了,只有我一个根节点。 if (root->_left == NULL && root->_right == NULL) { return 1; } return 1 + BinTreeNodeSize(root->_left) + BinTreeNodeSize(root->_right); /return root == NULL ? 0: 1 +BinTreeNodeSize(root->_left) + BinTreeNodeSize(root->_right); }
我当前根结点为空就返回0,
当我的左右孩子为空,则只有一层;否则就每访问到一次我的孩子结点就加一层;
然后比较左子树和右子树,谁访问的层数多,就返回谁。
int BinTreeTiers(BTNode* root)
{
if (root == NULL)
{
return 0;
}
return (root->_left == NULL ? 0 : 1 + BinTreeTiers(root->_left)) >
(root->_right == NULL ? 0 : 1 + BinTreeTiers(root->_right)) ?
1 + BinTreeTiers(root->_left) : 1 + BinTreeTiers(root->_right);
}
等于找K-1层左子树孩子结点个数 加上 k-1 层右孩子节点个数。
二叉树一个节点最多两个分支,
int BTKTierNodeNumber(BTNode* root, int k)
{
if (root == NULL)
{
return 0;
}
if (k==1)
{
return 1;
}
/第k层结点个数 等于 k-1层 左子树结点个数 + k-1层右子树结点个数
return BTKTierNodeNumber(root->_left, k - 1) +
BTKTierNodeNumber(root->_left, k - 1);
}
BTNode* BinTreeFindData(BTNode* root, int x) { if (root == NULL) { return NULL; } if (root->data == x) { return root; } /对一棵二叉树的操作就是对一个节点的操作,因为二叉树的结点类型相同,其他结点递归调用即可 /则找我左树有没有,没有再去找我的右子树, BTNode* retl = BinTreeFindData(root->_left, x); if (retl) { return retl; } /走到这里说明,左子树没有,直接返回右子树即可。 return BinTreeFindData(root->_right, x); }
结果论:
void BinTreeTierErgodic(BTNode* root) { QL bt; QueInit(&bt); if (root) { QuePush(&bt, root); } while (!QueueEmpty(&bt)) { BTNode* front = QueFront(&bt); QuePop(&bt); printf("%c ", front->data); if (front->_left) { QuePush(&bt, front->_left); } if (front->_right) { QuePush(&bt, front->_right); } } QueDestory(&bt); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。