54.对称的二叉树

对称的二叉树

题目描述

请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
考虑测试用例:

上代码:
// 53.cpp : 定义控制台应用程序的入口点。
//

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

struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};

class Solution {
public:
	bool isSymmetrical(TreeNode* pRoot) {
		if (pRoot == NULL) return true;

		vector<int> leftVec;
		vector<int> rightVec;

		travLeft(pRoot, leftVec);
		travRight(pRoot, rightVec);

		if (leftVec.size() != rightVec.size()) return false;

		bool retVal = true;
		for (int i = 0; i < leftVec.size(); i++) {
			if (leftVec[i] != rightVec[i]) {
				retVal = false;
				break;
			}
		}
		return retVal;
	}

	void travLeft(TreeNode* pNode, vector<int>& leftVec) {
		//if (pNode == NULL) {
		//	leftVec.push_back(-1);
		//	return;
		//}

		leftVec.push_back(pNode->val);
		if (pNode->left)
			travLeft(pNode->left, leftVec);
		else{
			leftVec.push_back(-1);
			return;
		}
		if (pNode->right)
			travLeft(pNode->right, leftVec);
		else{
			leftVec.push_back(-1);
			return;
		}
	}
	void travRight(TreeNode* pNode, vector<int>& rightVec) {
		//if (pNode == NULL) {
		//	rightVec.push_back(-1);
		//	return;
		//}

		rightVec.push_back(pNode->val);
		if (pNode->right)
			travRight(pNode->right, rightVec);
		else{
			rightVec.push_back(-1);
			return;
		}
		if (pNode->left)
			travRight(pNode->left, rightVec);
		else{
			rightVec.push_back(-1);
			return;
		}
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	TreeNode p1(5);
	TreeNode p2(5);
	TreeNode p3(5);
	TreeNode p4(5);
	TreeNode p5(5);
	TreeNode p6(5);

	p1.left = &p2;
	p1.right = &p3;
	p2.left = &p4;
	p2.right = &p5;
	p3.left = &p6;

	Solution s;
	bool result = s.isSymmetrical(&p1);
	return 0;
}

思路:
1.对二叉树做前序遍历,把前序遍历的结果装入leftVec中,注意,一般遍历到叶节就返回了,但是这里我们要再进一步,遍历到叶节点的下一位,叶节点的下一位为NULL,如果节点为NULL,就把-1压入leftVec;
2.对二叉树做前序遍历的对称遍历,即先遍历根节点,然后遍历左子节点,再遍历右子节点,把对称遍历的结果装入rightVec ,注意,一般遍历到叶节就返回了,但是这里我们要再进一步,遍历到叶节点的下一位,叶节点的下一位为NULL,如果节点为NULL,就把-1压入rightVec
3.如果leftVec和rightVec的长度不同,必然退出二叉树不对称,直接返回false;
4.依次对比leftVec和rightVec每个元素值,如果全部相同,说明二叉树对称,否则二叉树不对称;

   travLeft()函数对二叉树做前序遍历,并把前序遍历的结果存入leftVec,先构建二叉树前序遍历的框架:

	void travLeft(TreeNode* pNode, vector<int>& leftVec) {
		leftVec.push_back(pNode->val);
		if (pNode->left).............
		if (pNode->right)............
	}

   再丰富框架:

	void travLeft(TreeNode* pNode, vector<int>& leftVec) {
		leftVec.push_back(pNode->val);
		if (pNode->left)
			travLeft(pNode->left, leftVec);
		else{
			leftVec.push_back(-1); // 我们要遍历到叶子节点的下一位
			return;
		}
		if (pNode->right)
			travLeft(pNode->right, leftVec);
		else{
			leftVec.push_back(-1); // 我们要遍历到叶子节点的下一位
			return;
		}
	}

   travRight()函数对二叉树做对称前序遍历,并把对称前序遍历的结果存入rightVec,先构建二叉树对称前序遍历的框架:

	void travRight(TreeNode* pNode, vector<int>& rightVec) {
		rightVec.push_back(pNode->val);
		if (pNode->right)....
		if (pNode->left).......
	}
   再丰富框架:

	void travRight(TreeNode* pNode, vector<int>& rightVec) {
		rightVec.push_back(pNode->val);
		if (pNode->right)
			travRight(pNode->right, rightVec);
		else{
			rightVec.push_back(-1);// 我们要遍历到叶子节点的下一位
			return;
		}
		if (pNode->left)
			travRight(pNode->left, rightVec);
		else{
			rightVec.push_back(-1); // 我们要遍历到叶子节点的下一位
			return;
		}
	}


第二次做,之前看过一个源码,里面提倡一种理念:函数只有一个出口,第二次做我就采用了这种理念,使用 goto 语句跳转~

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot) {
    	if ( pRoot == NULL ) return true ;
        
        bool rc = false ;
        vector<int> leftVec ;
        vector<int> rightVec ;
        
        startLeft( leftVec, pRoot ) ;
        startRight( rightVec, pRoot ) ;
        
        if ( leftVec.size() != rightVec.size() ) {
            goto done ;
        }
        
        for ( int i = 0; i < leftVec.size(); ++ i ) {
            if ( leftVec[i] != rightVec[i] ) {
                goto done ;
            }
        }
        
        rc = true ;
        
        error :
        	goto done ;
        done :
        	return rc ;
    }
    
    void startLeft( vector<int>& leftVec, TreeNode* pNode ) {
        
        leftVec.push_back( pNode->val ) ;
        
        if ( pNode->left != NULL ) {
            startLeft( leftVec, pNode->left ) ;
        } else {
            leftVec.push_back( -1 ) ;
            return ;
        }
        
        if ( pNode->right != NULL ) {
            startLeft( leftVec, pNode->right ) ;
        } else {
            leftVec.push_back( -1 ) ;
            return ;
        }
    }
    
    void startRight( vector<int>& rightVec, TreeNode* pNode ) {
        
        rightVec.push_back( pNode->val ) ;
        
        if ( pNode->right != NULL ) {
            startRight( rightVec, pNode->right ) ;
        } else {
            rightVec.push_back( -1 ) ;
            return ;
        }
        
        if ( pNode->left != NULL ) {
            startRight( rightVec, pNode->left ) ;
        } else {
            rightVec.push_back( -1 ) ;
            return ;
        }
    }

};


第三次做,一杆过~

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot) {
    	if ( pRoot == NULL ) return true ;
        
        vector<int> vec_left ;
        vector<int> vec_right ;
        
        trav_left( pRoot, vec_left ) ;
        trav_right( pRoot, vec_right ) ;
        
        if ( vec_left.size() != vec_right.size() ) return false ;
        
        for ( int i = 0; i < vec_left.size(); ++ i ) {
            if ( vec_left[i] != vec_right[i] ) return false ;
        }
        return true ;
    }
    
    void trav_left( TreeNode* node, vector<int>& vec_left ) {
        vec_left.push_back( node->val ) ;
        if ( node->left ) trav_left( node->left, vec_left ) ;
        else {
            vec_left.push_back( -1 ) ;
            return ;
        }
        if ( node->right ) trav_left( node->right, vec_left ) ;
        else {
            vec_left.push_back( -1 ) ;
            return ;
        }
    }

    void trav_right( TreeNode* node, vector<int>& vec_right ) {
        vec_right.push_back( node->val ) ;
        if ( node->right ) trav_right( node->right, vec_right ) ;
        else {
            vec_right.push_back( -1 ) ;
            return ;
        }
        if ( node->left ) trav_right( node->left, vec_right ) ;
        else {
            vec_right.push_back( -1 ) ;
            return ;
        }
    }
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值