赞
踩
在介绍二叉树的基本操作前,需先要创建一棵二叉树,然后才能了解其相关的基本操作。由于二叉树的创建比较难理解,所以我们先手动创建一个链式二叉树,等到本文后面再介绍链式二叉树的创建方法。
手动创建链式二叉树:
typedef int BTDataType; typedef struct BinaryTreeNode { BTDataType _data; struct BinaryTreeNode* _left; struct BinaryTreeNode* _right; }BTNode; BTNode* CreatBinaryTree() { BTNode* node1 = BuyNode(1); BTNode* node2 = BuyNode(2); BTNode* node3 = BuyNode(3); BTNode* node4 = BuyNode(4); BTNode* node5 = BuyNode(5); BTNode* node6 = BuyNode(6); node1->_left = node2; node1->_right = node4; node2->_left = node3; node4->_left = node5; node4->_right = node6; return node1; }
注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式本文后面会介绍。
学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。
按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。
// 二叉树前序遍历 void BinaryTreePrevOrder(BTNode* root) { if (root == NULL) { printf("# "); return; } printf("%c ", root->data); BinaryTreePrevOrder(root->left); BinaryTreePrevOrder(root->right); } // 二叉树中序遍历 // 二叉树中序遍历 void BinaryTreeInOrder(BTNode* root) { if (root == NULL) { printf("# "); return; } BinaryTreeInOrder(root->left); printf("%c ", root->data); BinaryTreeInOrder(root->right); } // 二叉树后序遍历 void BinaryTreePostOrder(BTNode* root) { if (root == NULL) { printf("# "); return; } BinaryTreePostOrder(root->left); BinaryTreePostOrder(root->right); printf("%c ", root->data); }
下面主要分析前序递归遍历,中序与后序图解类似。
前序遍历递归图解:
前序遍历结果:1 2 3 4 5 6
中序遍历结果:3 2 1 5 4 6
后序遍历结果:3 2 5 6 4 1
层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
层序遍历的实现要借助队列来实现,首先在队列中插入根节点,然后删除根结点的同时带入根节点的两个子节点,一直循环删除节点的同时带入子节点的操作,直到队列为空。
// 层序遍历 void BinaryTreeLevelOrder(BTNode* root) { Queue a; QueueInit(&a); QueuePush(&a, root); while (!QueueEmpty(&a)) { BTNode* tmp = QueueFront(&a); if (tmp == NULL) { printf("# "); QueuePop(&a); continue; } printf("%c ", tmp->data); QueuePush(&a, tmp->left); QueuePush(&a, tmp->right); QueuePop(&a); } }
int BinaryTreeLevelKSize(BTNode* root, int k)
{
if (root == NULL)
return 0;
if (k == 1)
return 1;
return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}
int BinaryTreeLeafSize(BTNode* root)
{
if (root->left == NULL && root->right == NULL)
return 1;
if (root->left == NULL)
return BinaryTreeLeafSize(root->right);
if (root->right == NULL)
return BinaryTreeLeafSize(root->left);
return BinaryTreeLeafSize(root->right) + BinaryTreeLeafSize(root->left);
}
int BinaryTreeLevelKSize(BTNode* root, int k)
{
if (root == NULL)
return 0;
if (k == 1)
return 1;
return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}
BTNode* BinaryTreeFind(BTNode* root, BTDataType x) { if (root == NULL) return NULL; if (root->data == x) return root; BTNode* left = BinaryTreeFind(root->left, x); if (left != NULL) return left; BTNode* right = BinaryTreeFind(root->right, x); if (right != NULL) return right; return NULL; }
bool isUnivalTree(struct TreeNode* root) {
if(root == NULL)
return true;
if(root->left == NULL && root->right == NULL)
return true;
if(root->left != NULL && root->val != root->left->val)
return false;
if(root->right != NULL && root->val != root->right->val)
return false;
return isUnivalTree(root->left)&&isUnivalTree(root->right);
}
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
if(p == NULL && q == NULL)
return true;
if(p == NULL || q == NULL)
return false;
if(p->val != q->val)
return false;
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
bool _isSymmetric(struct TreeNode* left, struct TreeNode* right) { if(left == NULL && right == NULL) return true; if(left == NULL || right == NULL) return false; if(left->val != right->val) return false; return _isSymmetric(left->left,right->right)&&_isSymmetric(left->right,right->left); } bool isSymmetric(struct TreeNode* root) { return _isSymmetric(root->left,root->right); }
void _preorderTraversal(struct TreeNode* root, int* returnSize,int* a) { if (root == NULL) return; a[*returnSize] = root->val; (*returnSize)++; _preorderTraversal(root->left,returnSize, a); _preorderTraversal(root->right,returnSize, a); } int* preorderTraversal(struct TreeNode* root, int* returnSize) { if (root == NULL) { *returnSize = 0; return NULL; } int* a = (int*)malloc(sizeof(int) * 100); *returnSize = 0; _preorderTraversal(root, returnSize, a); return a; }
bool isSameTree(struct TreeNode* p, struct TreeNode* q) { if(p == NULL && q == NULL) return true; if(p == NULL || q == NULL) return false; if(p->val != q->val) return false; return isSameTree(p->left,q->left) && isSameTree(p->right,q->right); } bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){ if(root == NULL) return false; if(isSameTree(root,subRoot)) return true; return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot); }
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 BTNode* BinaryTreeCreate(BTDataType* a, int* pi) { if (a[*pi] == '#') { (*pi)++; return NULL; } BTNode* root = (BTNode*)malloc(sizeof(BTNode)); root->data = a[*pi]; (*pi)++; root->left = BinaryTreeCreate(a, pi); root->right = BinaryTreeCreate(a, pi); return root; }
// 二叉树销毁
void BinaryTreeDestory(BTNode** root)
{
if (*root == NULL)
return;
BinaryTreeDestory(&(*root)->left);
BinaryTreeDestory(&(*root)->right);
free(*root);
*root = NULL;
}
// 判断二叉树是否是完全二叉树 bool BinaryTreeComplete(BTNode* root) { Queue a; QueueInit(&a); QueuePush(&a, root); int judge = 0; while (!QueueEmpty(&a)) { if (judge == 0) { BTNode* tmp = QueueFront(&a); if (tmp == NULL) { judge = 1; QueuePop(&a); continue; } QueuePush(&a, tmp->left); QueuePush(&a, tmp->right); QueuePop(&a); } else { BTNode* tmp = QueueFront(&a); if (tmp == NULL) { QueuePop(&a); continue; } QueueDestroy(&a); return false; } } QueueDestroy(&a); return true; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。