二叉树的一些基本操作

一、遍历二叉树

1.前序遍历

        前序遍历,是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。

                        

void PreOrder(BTNode* root) {
	if (!root) {
		printf("NULL ");
		return;
	}
	printf("%c ", root->date);
	PreOrder(root->left);
	PreOrder(root->right);

}

   2.中序遍历

        中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。代码与前序类似。

                                     

 3.后序遍历

        后序遍历(LRD)是二叉树遍历的一种,后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点,代码与前序类似。

                                   

4.层序遍历

        逐层从左到右访问所有节点,先遍历第一层,然后再遍历第二层的,依次下去到最后一层。

                          

        思想:利用数据结构队列的性质,先把根节点插入到队列,再把当前节点带出并把非空孩子节点带入队列,队列为空说明遍历结束。

//队列的构建这里不列出
void LevelOrder(BTNode* root) {
	QE qe;//建立队列
	QueueInit(&qe);
	QueuePush(&qe, root);//插入根节点
    //队列为空遍历完成
	while (!QueueEmpty(&qe)) {
		BTNode* front = QueueFront(&qe);
		QueuePop(&qe);
		printf("%c", front->date);
        //带入非空孩子节点
		if (front->left) {
			QueuePush(&qe, front->left);
		}
		if (front->right) {
			QueuePush(&qe, front->right);
		}
	}
	QueueDestroy(&qe);
}

 二、二叉树的基本操作

        1.求二叉树节点的数量

int BinaryTreeSize(BTNode* root) {
	if (!root) {
		return 0;
	}
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right)+1 ;
}

        2.求二叉树叶子节点的数量

int BinaryTreeLeafSize(BTNode* root) {
	if (!root) {
		return 0;
	}
	if (!root->left && !root->right) {
		return 1;
	}
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

        3.求二叉树第K层节点数量

int BinaryTreeLeavelKSize(BTNode* root,int k) {
	if (!root) {
		return 0;
	}
	if (k == 1) {
		return 1;
	}
	return BinaryTreeLeavelKSize(root->left, k - 1) + BinaryTreeLeavelKSize(root->right, k - 1);
}

           4.求二叉树的深度

int BinaryTreeDepth(BTNode* root){
    if(!root){
        return 0;
    }
    int left= BinaryTreeDepth(root->left);
    int right=BinaryTreeDepth(root->right);
    return left>right?left+1:right+1;
}

           5.根据值查找二叉树的节点并返回

BTNode* BinaryTreeFind(BTNode* root, BTDateType x) {
	if (root == NULL) {
		return NULL;
	}
	if (root->date == x) {
		return root;
	}
	
	BTNode* left = BinaryTreeFind(root->left, x);
	if (left) {
		return left;
	}
	BTNode* right = BinaryTreeFind(root->right, x);
	if (right) {
		return right;
	} 
		return NULL;
}

         6.判断二叉树是否为完全二叉树

        思想:与二叉树的层序遍历类似,先把根节点插入到队列,再把当前节点带出并把孩子节点带入队列(孩子节点为空也要带入),当队列首元素为空判断队列内元素是否有非空元素,有则为非完全二叉树,没有则为完全二叉树。

bool IsCmpBinaryTree(BTNode* root) {
	QE qe;
	QueueInit(&qe);
	QueuePush(&qe, root);
	while (QueueFront(&qe)) {
		BTNode* front = QueueFront(&qe);
		QueuePop(&qe);
		QueuePush(&qe,front->left);
		QueuePush(&qe,front->right);
	}
	while (!QueueEmpty(&qe)) {
		BTNode* front = QueueFront(&qe);
		QueuePop(&qe);
		if (front) {
			return false;
		}
	}
	QueueDestroy(&qe);
	return true;
}

        7.判断二叉树是否为单值二叉树

思想:从根开始判断与左右节点是否相等

bool isUnivalTree(struct TreeNode* root)
{
    if(!root){
        return true;
    }
    if(root->left&&root->val!=root->left->val)
    {
        return false;
    }
    if(root->right&&root->val!=root->right->val)
    {
        return false;
    }
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

        8.将二叉树前序遍历的值放入数组

int TreeSize(struct TreeNode* root){
    if(root==NULL){
        return 0;
    }
    return TreeSize(root->left)+TreeSize(root->right)+1;
}

void _preorderTraversal(struct TreeNode* root,int*a,int*i){
    if(root==NULL){
    return ;
}
    a[(*i)++]=root->val;
    _preorderTraversal(root->left,a,i);
    _preorderTraversal(root->right,a,i);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int size=TreeSize(root);//计算树节点个数
    int*a=malloc(sizeof(int)*size);
    int i=0;
    _preorderTraversal(root,a,&i);
    *returnSize=size;
    return a;
}

        9.判断一棵树是否为另一棵树的子树

bool isSame(struct TreeNode* root1, struct TreeNode* root2){
    if(root1==root2){
        return true;
    }
    if(!root1||!root2||root1->val!=root2->val){
        return false;
    }
    return isSame(root1->left,root2->left)&&isSame(root1->right,root2->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(!root){
        return false;
    }

    if(isSame(root,subRoot)){
        return true;
    }
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值