C++算法之 判断是否为平衡二叉树 求二叉树的镜像

1:判断是否为平衡二叉树:

//方法1:
int TreeDepth(BTree* pRoot)
{
	if (pRoot == NULL)
		return 0;
	int nLeftDepth = TreeDepth(pRoot->m_pLeft);
	int nRightDepth = TreeDepth(pRoot->m_pRight);

	return (nLeftDepth > nRightDepth)? (nLeftDepth+1):(nRightDepth+1);
}

bool IsBalanced(BTree* pRoot)
{
	if (pRoot == NULL)
		return true;
	int nLeftDepth = TreeDepth(pRoot->m_pLeft);
	int nRightDepth = TreeDepth(pRoot->m_pRight);
	int diff = nRightDepth - nLeftDepth;
	if (diff > 1 || diff < -1)
		return false;

	return IsBalanced(pRoot->m_pLeft)&&IsBalanced(pRoot->m_pRight);

}
/*
上面的方法:在求该节点的左右子树的深度的时候遍历一遍树,再次判断子树的平衡性的时候又要遍历
一遍树结构,造成遍历多次!
*/
bool IsBalanced3(BTree* pRoot, int& depth)
{
	if(pRoot== NULL)
	{
		depth = 0;
		return true;
	}

	int nLeftDepth;
	bool bLeft= IsBalanced3(pRoot->m_pLeft, nLeftDepth);
	int nRightDepth;
	bool bRight = IsBalanced3(pRoot->m_pRight, nRightDepth);

	if (bLeft && bRight && abs(nLeftDepth - nRightDepth) <=1)
	{
		depth = 1+(nLeftDepth > nRightDepth ? nLeftDepth : nRightDepth);
		return true;
	}
	else
	{
		return false;
	}
}

bool IsBalanced3(BTree* pRoot)
{
	int depth = 0;
	return IsBalanced3(pRoot, depth);
}

2:求二叉树的镜像

/*
求二叉树的镜像:

方法1: 前序遍历每个节点,如果遍历到的节点有子节点,就交换它的两个子节点。(先交换左子树和右子树,再对左子树和右子树进行镜像操作)
方法2: 如果二叉树不为空,求左子树和右子树的镜像,然后再交换左子树和右子树

*/

void Mirror(BTree* &pRoot)
{
	if(pRoot == NULL)
		return;
	if(pRoot->m_pLeft ==NULL && pRoot->m_pRight == NULL)
		return;

	BTree* pTemp = pRoot->m_pLeft;
	pRoot->m_pLeft = pRoot->m_pRight;
	pRoot->m_pRight = pTemp;

	if(pRoot->m_pLeft)
		Mirror(pRoot->m_pLeft);
	if(pRoot->m_pRight)
		Mirror(pRoot->m_pRight);
}

BTree* Mirror2(BTree* pRoot)
{
	if(pRoot == NULL)
		return NULL;

	BTree*  pLeft = Mirror2(pRoot->m_pLeft);
	BTree*  pRight = Mirror2(pRoot->m_pRight);

	pRoot->m_pLeft = pRight;
	pRoot->m_pRight = pLeft;

	return pRoot;
}

完整测试代码:

// BalanceOfBT.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

class BTree
{
public:
	int     m_nValue;
	BTree*  m_pLeft;
	BTree*  m_pRight;

	BTree(int m):m_nValue(m)
	{
		m_pLeft = m_pRight = NULL;
	}

};
//二叉树的插入实现
void Insert(int value, BTree* &root)
{
	if (root == NULL)
	{
		root = new BTree(value);
	}
	else if(value < root->m_nValue)
		Insert(value,root->m_pLeft);
	else if(value > root->m_nValue)
		Insert(value,root->m_pRight);
	else
		;
}

//方法1:
int TreeDepth(BTree* pRoot)
{
	if (pRoot == NULL)
		return 0;
	int nLeftDepth = TreeDepth(pRoot->m_pLeft);
	int nRightDepth = TreeDepth(pRoot->m_pRight);

	return (nLeftDepth > nRightDepth)? (nLeftDepth+1):(nRightDepth+1);
}

bool IsBalanced(BTree* pRoot)
{
	if (pRoot == NULL)
		return true;
	int nLeftDepth = TreeDepth(pRoot->m_pLeft);
	int nRightDepth = TreeDepth(pRoot->m_pRight);
	int diff = nRightDepth - nLeftDepth;
	if (diff > 1 || diff < -1)
		return false;

	return IsBalanced(pRoot->m_pLeft)&&IsBalanced(pRoot->m_pRight);

}
/*
上面的方法:在求该节点的左右子树的深度的时候遍历一遍树,再次判断子树的平衡性的时候又要遍历
一遍树结构,造成遍历多次!
*/
bool IsBalanced3(BTree* pRoot, int& depth)
{
	if(pRoot== NULL)
	{
		depth = 0;
		return true;
	}

	int nLeftDepth;
	bool bLeft= IsBalanced3(pRoot->m_pLeft, nLeftDepth);
	int nRightDepth;
	bool bRight = IsBalanced3(pRoot->m_pRight, nRightDepth);

	if (bLeft && bRight && abs(nLeftDepth - nRightDepth) <=1)
	{
		depth = 1+(nLeftDepth > nRightDepth ? nLeftDepth : nRightDepth);
		return true;
	}
	else
	{
		return false;
	}
}

bool IsBalanced3(BTree* pRoot)
{
	int depth = 0;
	return IsBalanced3(pRoot, depth);
}

/*
求二叉树的镜像:

方法1: 前序遍历每个节点,如果遍历到的节点有子节点,就交换它的两个子节点。(先交换左子树和右子树,再对左子树和右子树进行镜像操作)
方法2: 如果二叉树不为空,求左子树和右子树的镜像,然后再交换左子树和右子树

*/

void Mirror(BTree* &pRoot)
{
	if(pRoot == NULL)
		return;
	if(pRoot->m_pLeft ==NULL && pRoot->m_pRight == NULL)
		return;

	BTree* pTemp = pRoot->m_pLeft;
	pRoot->m_pLeft = pRoot->m_pRight;
	pRoot->m_pRight = pTemp;

	if(pRoot->m_pLeft)
		Mirror(pRoot->m_pLeft);
	if(pRoot->m_pRight)
		Mirror(pRoot->m_pRight);
}

BTree* Mirror2(BTree* pRoot)
{
	if(pRoot == NULL)
		return NULL;

	BTree*  pLeft = Mirror2(pRoot->m_pLeft);
	BTree*  pRight = Mirror2(pRoot->m_pRight);

	pRoot->m_pLeft = pRight;
	pRoot->m_pRight = pLeft;

	return pRoot;
}

void PrintPrev(BTree* pRoot)
{
	if(pRoot == NULL)
		return;

	cout<<pRoot->m_nValue<<" ";
	PrintPrev(pRoot->m_pLeft);
	PrintPrev(pRoot->m_pRight);
}

int _tmain(int argc, _TCHAR* argv[])
{

	BTree* m_pRoot = new BTree(9);
	Insert(3,m_pRoot);
	Insert(6,m_pRoot);
	Insert(1,m_pRoot);
	Insert(2,m_pRoot);
	Insert(5,m_pRoot);
	Insert(8,m_pRoot);
	Insert(7,m_pRoot);
	Insert(10,m_pRoot);

	cout<<IsBalanced(m_pRoot)<<endl;
	cout<<"原来的树:"<<endl;
	PrintPrev(m_pRoot);
	cout<<endl<<"镜像的树:"<<endl;
	Mirror(m_pRoot);
	//Mirror2(m_pRoot);
	PrintPrev(m_pRoot);

	/*
	BTree* m_pRoot2 = new BTree(96);
	Insert(3,m_pRoot2);
	Insert(6,m_pRoot2);
	Insert(1,m_pRoot2);
	Insert(2,m_pRoot2);
	Insert(5,m_pRoot2);
	Insert(8,m_pRoot2);
	Insert(7,m_pRoot2);
	Insert(10,m_pRoot2);
	int depth;
	cout<<endl<<IsBalanced3(m_pRoot2)<<endl;
	*/

	getchar();
	return 0;
}
时间: 2024-12-10 13:08:30

C++算法之 判断是否为平衡二叉树 求二叉树的镜像的相关文章

求二叉树的镜像

求二叉树的镜像: void MirrorBiTree(BiTree* pNode) { if(pNode == NULL||pNode->leftChild ==NULL || pNode->rightChild ==NULL) return ; ListNode* temp; temp = pNode->leftChild; pNode->leftChild  =  pNode->rightChild; pNode->rightChild = temp; if( pN

二叉树(11)----求二叉树的镜像,递归和非递归方式

1.二叉树定义: typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 2.求二叉树镜像 比如: A                    

设计一个算法,判断给定的一棵二叉树是否是二叉排序树(二叉树的所有关键字均为正整数)

思想:对二叉排序树来说,其中序遍历序列为一个递增有序序列,因此,对给定的二叉树进行中序遍历,如果始终能保持前一个值比后一个值小,则说明该二叉树是一棵二叉排序树.算法如下: KeyType predt=0;//predt为全局变量,保存当前节点中序前趋的值,初值为最小值 int judgeBST(BSTNode *bt) { //返回1表示是一颗二叉排序树,返回0表示不是 int b1,b2; if(bt==NULL)  return 1; else { b1=judgeBST(bt->lchil

《剑指offer》:[39-1]判断是否为平衡二叉树

题目:输入一棵二叉树的结点,判断该树是不是平衡二叉树.如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树. 上图中的二叉树就是一棵平衡二叉树. 分析:有了求二叉树深度的思路后,我们很快就能找到求解该问题的方法,就是从根结点开始开始判断其左右子结点的深度之差是否为1.如果从根结点开始到叶子结点的每一个结点的左右子树的深度相差都不超过1,则说明该二叉树是平衡二叉树.但是其时间复杂度接近O(N*N),因为里面有重复的遍历和访问.例如我们在判断8这个根结点是否是平衡的时候,我们

经典算法之判断一个整数是否为素数

经典算法之判断一个整数是否为素数 1 /** 2 判断一个数是否为素数 如: 3 输入: 任意一个数 12 4 输出: 1或0(1表示为素数) 0 5 */ 6 /**************被称为笨蛋的做法************/ 7 #include <stdio.h> 8 9 int main() 10 { 11 12 int i,n; //i为计数数,n为存储用户输入的数 13 14 do //循环检测用户输入的数据>0为合法 15 scanf("%d",&

已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或者后序遍历的最后一个结点,查找对应在中序遍历中的位置,就可以确定左子树包含的元素和右子树包含的元素,最后通过递归来实现就可以了. 二叉树的表示形式为 //二叉树的结构表示为 class TreeNode { int val; TreeNode left; TreeNode right; TreeNo

1119: 零起点学算法26——判断奇偶数

1119: 零起点学算法26--判断奇偶数 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 2419  Accepted: 1508[Submit][Status][Web Board] Description 输入一个整数,判断是奇数还是偶数 Input 输入1个正整数(多组数据) Output 如果是奇数,输出odd否则输出even(每组数据一行) Sample Input 2 Sample O

1120: 零起点学算法27——判断是否直角三角形

1120: 零起点学算法27--判断是否直角三角形 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 5747  Accepted: 1519[Submit][Status][Web Board] Description 输入三个整数,分别代表三角形的三条边长度,判断能否构成直角三角形 Input 输入3个整数a,b,c(多组数据,-5000000<a,b,c<5000000) Output 如果能

1121: 零起点学算法28——判断是否闰年

1121: 零起点学算法28--判断是否闰年 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 3988  Accepted: 2204[Submit][Status][Web Board] Description 输入年份,判断是否闰年 Input 输入一个整数n(多组数据) Output 如果是闰年,输出yes,否则输出no(每组数据一行) Sample Input 2000 Sample Out