【递归前中后序遍历二叉树】
【求树的结点数,叶子数,第k层结点数,深度】
【求树中某个结点】
【判断是否为完全二叉树】
【层序遍历二叉树】
首先得有最基础的函数,创建新的结点,创建二叉树
typedef int BTDataType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* _left;//左子树
struct BinaryTreeNode* _right;//右子树
BTDataType _data;//数据域,关键码
}BTNode;
BTNode* BuyBTNode(BTDataType x)// 创建二叉树
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->_left = NULL;
node->_right = NULL;
node->_data = x;
return node;
}
//这里的下标pIndex要传地址(指针),来使得下标随着递归的次数改变而改变
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid)// 创建二叉树
{
assert(a);
BTNode* root = NULL;
while (a[*pIndex] != invalid)
{
root = BuyBTNode(a[*pIndex]);
++(*pIndex);
root->_left=CreateBTree(a, &pIndex, invalid);
++(*pIndex);
root->_right=CreateBTree(a, &pIndex, invalid);
}
return root;
}
【递归前中后序遍历二叉树】
//前序遍历二叉树
void BTreePrevOrder(BTNode* root)
{
if (root == NULL)
return;
printf("%d", root->_data);
BTreePrevOrder(root->_left);
BTreePrevOrder(root->_right);
}
//中序遍历二叉树
void BTreeInOrder(BTNode* root)
{
if (root == NULL)
return;
BTreeInOrder(root->_left);
printf("%d", root->_data);
BTreeInOrder(root->_right);
}
//后序遍历二叉树
void BTreePostOrder(BTNode* root)
{
if (root == NULL)
return;
BTreePostOrder(root->_left);
BTreePostOrder(root->_right);
printf("%d", root->_data);
}
//不难看出这三种排序的区别只是printf的位置不一样
【求树的结点数,叶子数,第k层结点数,深度】
//求树的结点数
//遍历一遍二叉树,递归一次计数器就加一
size_t BTreeSize(BTNode* root)
{
if (root == NULL)
return 0;
return BTreeSize(root->_left) + BTreeSize(root->_right) + 1;
}
//求树的叶子数
//在上一个加入限制条件,当该结点的左子树和右子树同时为空,即为叶子的时候计数器加一
size_t BTreeLeafSize(BTNode* root)
{
if (root == NULL)
return 0;
if (root->_left == root->_right == NULL)
return 1;
return BTreeLeafSize(root->_left) + BTreeLeafSize(root->_right);
}
//求树的第k层的结点数
//从根往下走,走k层,K在这个过程中不停自减,当k走到1的时候代表走到第k层,这个也相当于是遍历了一遍,只是在第K层的结点计数器才加一
size_t BTreeKLevelSize(BTNode* root, size_t k)
{
if (root == NULL)
return 0;
if (k == 1)
return 1;
return BTreeKLevelSize(root->_left, k - 1) + BTreeKLevelSize(root->_right, k - 1);
}
//求树的深度
size_t BTreeDepth(BTNode* root)
{
if (root == NULL)
return 0;
size_t leftDepth = BTreeDepth(root->_left);
size_t rightDepth = BTreeDepth(root->_right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;//取大的内个加一
}
【求树中某个结点】
//求树中某个结点
//定义两个变量接收查找的结果再用if判断的好处就是,如果找到了,就不再往下递归了,提高效率
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
BTNode* leftNode = BTreeFind(root->_left, x);
if (leftNode->_data == x)
return leftNode;
BTNode* rightNode = BTreeFind(root->_right, x);
if (rightNode->_data == x)
return rightNode;
return NULL;
}
【层序遍历二叉树】
//层序遍历二叉树
void BTreeLevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root != NULL)
QueuePush(&q, root);
while (QueueEmpty(&q))
{
BTNode* Front = QueueFront(q);
printf("%d", Front->_data);
QueuePop(&q);
if (Front->_left != NULL)
QueuePush(&q, Front->_left);
if (Front->_right != NULL)
QueuePush(&q, Front->_right);
}
printf("\n");
}
【判断是否为完全二叉树】
// 判断完全二叉树
int IsCompleteBTree(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root != NULL)
QueuePush(&q, root);
while (QueueEmpty(q))
{
BTNode* Front = QueueFront(q);
QueuePop(&q);//出队时,检测到队头为NULL后停止遍历,再判断队是否为空
if (Front == NULL)
break;
else
{
QueuePush(&q, Front->_left);
QueuePush(&q, Front->_right);
}
}
//如果队为空,则是完全二叉树,反之,开始检查队内数据是否完全为NULL,是则是完全二叉树,不是,即不是
//因为完全二叉树的第n层从左往右是连续的,则层序遍历后数据与数据之间不可能存在NULL
while (QueueEmpty(q))
{
BTNode* Front = QueueFront(q);
if (Front != NULL)
return 0;
QueuePop(&q);
}
return 1;
}
如果有什么不对的地方,可以评论告诉我,望指导!