• 由一道面试题“打印二叉树中和为某一值的路径”想到的二叉树的创建问题。


    今年要找工作了,前两天看了下面试题,其中有一道打印二叉树中和为某一值的路径面试题目,猛然想起很有必要吧二叉树的创建问题好好看看,正好今天周六,实验室没什么事情,就写了一上午代码,把这个问题好好理解下,希望各位大牛看到后,能给点指导意见补充或者纠正下,谢谢各位支持。好了 饿的不行了 吃饭去了。

    View Code
      1 // 二叉树中和为某一值.cpp : 定义控制台应用程序的入口点。
    2 //
    3
    4 /***********************************************************************
    5 题目:输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径
    6 从树的根节点开始往下一直到叶节点所经过的结点形成一条路径。
    7 // 10
    8 // / \
    9 // 5 12
    10 // /\
    11 // 4 7
    12 // 有两条路径上的结点和为22 一条是10-5-7 另外一条是10-12
    13
    14 对于 递归构建二叉树 输入序列为10 5 4 0 0 7 0 0 12 0 0
    15 *************************************************************************/
    16
    17
    18
    19 #include "stdafx.h"
    20 #include <vector>
    21 #include <stdlib.h>
    22 #include <iostream>
    23 using namespace std;
    24
    25 struct BinaryTreeNode
    26 {
    27 int m_nValue;
    28 BinaryTreeNode *m_pLeft;
    29 BinaryTreeNode *m_pRight;
    30 };
    31
    32
    33
    34 /************************************************分割线****************************************************/
    35 /******************** 第一种创建二叉树方法 ****************************/
    36 /************************************************分割线*****************************************************/
    37 /************************************************************************************************************
    38 此种方法借鉴了何海涛老师的方法,这种方法有点类似第四种方案,插入创建二叉树。他的特点是用户保证输入的正确性
    39 是一种非常简练的测试用创建二叉树方案。
    40 ***********************************************************************************************************/
    41 BinaryTreeNode* CreatBinaryTreeNode(int value)
    42 {
    43 BinaryTreeNode* pnode=new BinaryTreeNode();
    44 pnode->m_nValue=value;
    45 pnode->m_pLeft=NULL;
    46 pnode->m_pRight=NULL;
    47 return pnode;
    48 }
    49
    50 void ConnectBinaryTreeNode(BinaryTreeNode *pparent,BinaryTreeNode *pleft,BinaryTreeNode* pright)
    51 {
    52 if(pparent!=NULL)
    53 {
    54 pparent->m_pLeft=pleft;
    55 pparent->m_pRight=pright;
    56 }
    57 }
    58
    59
    60 /************************************************分割线****************************************************/
    61 /******************** 第二种创建二叉树方法 ****************************/
    62 /************************************************分割线*****************************************************/
    63 /*********************************************************************************************************
    64 这种方案网上有人称之为无参数创建,其实创建二叉树思路可以归结为两点:
    65 1 没有参数传递,这种方案一般都是要在返回值上下文章,返回根节点。
    66 2 有参数传递, 但是无返回值。这一种其实比较难点,因为指针传值和内存传递过程中
    67 有可能没搞清楚怎么回事就已经被释放或成为非法指针。
    68 **********************************************************************************************************/
    69 BinaryTreeNode* CreateBinaryTreeNode()
    70 {
    71 int value;
    72 cout<<"请输入节点值: ";
    73 cin>>value;
    74 cout<<endl;
    75 if(!value) return NULL;
    76 BinaryTreeNode* pRoot=new BinaryTreeNode();
    77 pRoot->m_nValue=value;
    78 pRoot->m_pLeft=CreateBinaryTreeNode();
    79 pRoot->m_pRight=CreateBinaryTreeNode();
    80 return pRoot;
    81 }
    82 /************************************************分割线****************************************************/
    83 /******************** 第三种创建二叉树方法 ****************************/
    84 /************************************************分割线*****************************************************/
    85 /********************************************************************************************************
    86 这种方案就是难了点,传递过程我们要始终保证改变的是实参的指针值。
    87 *********************************************************************************************************/
    88 void CreateBinaryTreeNode(BinaryTreeNode **t)
    89 {
    90 int value;
    91 cout<<"请输入节点值: ";
    92 cin>>value;
    93 cout<<endl;
    94 if(!value)
    95 {
    96 *t=NULL; //此处一定要加此条语句,不然后面再遍历时报错。
    97 return;
    98 }
    99 *t=(BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));
    100 if(*t==NULL)
    101 {
    102 cerr<<"out of memory"<<endl;
    103 exit(1);
    104 }
    105 (*t)->m_nValue=value;
    106 //&t=pRoot;
    107 CreateBinaryTreeNode(&((*t)->m_pLeft));
    108 CreateBinaryTreeNode(&((*t)->m_pRight));
    109 }
    110 /************************************************分割线****************************************************/
    111 /******************** 第四种创建二叉树方法 ****************************/
    112 /************************************************分割线*****************************************************/
    113
    114 /*****************************************************************************************************
    115 第四种这种方案比较理想化,建议采用这种方案。
    116 *****************************************************************************************************/
    117 //第四种方法有两个函数构成一个是BinaryTreeNode* CreatBinaryTreeNode(int value) 因为这个函数上述已经实现 故不再赘述
    118 //另一个函数是下面实现的插入函数。
    119 void insert(BinaryTreeNode **pRoot,int value)
    120 {
    121 if(!value) return;
    122 BinaryTreeNode *pnode=CreatBinaryTreeNode(value);
    123 if(!pnode)
    124 {
    125 cerr<<"out of memory"<<endl;
    126 exit(1);
    127 }
    128 if(!(*pRoot))
    129 {
    130 *pRoot=pnode;
    131 }
    132 else if(pnode->m_nValue>(*pRoot)->m_nValue)
    133 insert(&((*pRoot)->m_pRight),pnode->m_nValue);
    134 else
    135 insert(&((*pRoot)->m_pLeft),pnode->m_nValue);
    136
    137 }
    138
    139
    140 /***************************************创建方法完毕****************************************/
    141 /*******************************************************************************************/
    142
    143
    144
    145
    146
    147
    148 void DestroyTree(BinaryTreeNode* pRoot) //销毁指针函数
    149 {
    150 if(pRoot != NULL)
    151 {
    152 BinaryTreeNode* pLeft = pRoot->m_pLeft;
    153 BinaryTreeNode* pRight = pRoot->m_pRight;
    154
    155 delete pRoot;
    156 pRoot = NULL;
    157
    158 DestroyTree(pLeft);
    159 DestroyTree(pRight);
    160 }
    161 }
    162
    163
    164 void FindPath(BinaryTreeNode *pRoot,int expectedsum,vector<int> path,int currentsum);
    165 void FindPath(BinaryTreeNode *pRoot,int expectedsum)
    166 {
    167 if(pRoot==NULL)
    168 return;
    169 int currentsum=0;
    170 vector<int> path;
    171 FindPath(pRoot,expectedsum,path,currentsum);
    172 }
    173 //下面这个为查找二叉树中和为定值的函数
    174 void FindPath(BinaryTreeNode *pRoot,int expectedsum,vector<int> path,int currentsum)
    175 {
    176 currentsum+=pRoot->m_nValue;
    177 cout<<pRoot->m_nValue<<" being visited"<<endl;
    178 path.push_back(pRoot->m_nValue);
    179 bool isLeaf=pRoot->m_pLeft==NULL&&pRoot->m_pRight==NULL; //判断是否为叶子节点
    180 if(currentsum==expectedsum&&isLeaf)
    181 {
    182 cout<<"we have find path list: "<<endl;
    183 vector<int>::iterator iter=path.begin();
    184 for(;iter!=path.end();iter++)
    185 cout<<*iter<<"\t";
    186 cout<<endl;
    187 }
    188 if(currentsum>=expectedsum) //对树进行剪枝 =也在剪枝范围内。见test1
    189 return;
    190 if(pRoot->m_pLeft!=NULL)
    191 FindPath(pRoot->m_pLeft,expectedsum,path,currentsum);
    192 if(pRoot->m_pRight!=NULL)
    193 FindPath(pRoot->m_pRight,expectedsum,path,currentsum);
    194 currentsum-=pRoot->m_nValue;
    195 path.pop_back();
    196
    197 }
    198
    199
    200 void Test(const char* str,BinaryTreeNode *pRoot,int expectedsum)
    201 {
    202 cout<<str<<" have begin: "<<endl;
    203 FindPath(pRoot,expectedsum);
    204 cout<<endl;
    205 }
    206
    207 void Test1()
    208 {
    209 BinaryTreeNode *pNode10=CreatBinaryTreeNode(10);
    210 BinaryTreeNode *pNode5=CreatBinaryTreeNode(5);
    211 BinaryTreeNode *pNode12=CreatBinaryTreeNode(12);
    212 BinaryTreeNode *pNode4=CreatBinaryTreeNode(4);
    213 BinaryTreeNode *pNode7=CreatBinaryTreeNode(7);
    214 BinaryTreeNode *pNode11=CreatBinaryTreeNode(11);
    215 BinaryTreeNode *pNode13=CreatBinaryTreeNode(13);
    216 ConnectBinaryTreeNode(pNode10,pNode5,pNode12);
    217 ConnectBinaryTreeNode(pNode5,pNode4,pNode7);
    218 ConnectBinaryTreeNode(pNode12,pNode11,pNode13);
    219 Test("test1",pNode10,22);
    220 DestroyTree(pNode10);
    221
    222 }
    223
    224
    225 void Test2()
    226 {
    227 cout<<"方法二创建二叉树"<<endl;
    228 BinaryTreeNode* pnode=CreateBinaryTreeNode();
    229 Test("test2",pnode,22);
    230 DestroyTree(pnode);
    231 }
    232
    233 void Test3()
    234 {
    235 cout<<"方法三创建二叉树"<<endl;
    236 BinaryTreeNode *t=NULL;
    237 CreateBinaryTreeNode(&t);
    238 Test("test3",t,22);
    239 DestroyTree(t);
    240
    241 }
    242
    243 void Test4()
    244 {
    245 cout<<"方法四创建二叉树"<<endl;
    246 BinaryTreeNode *pRoot=CreatBinaryTreeNode(10);
    247 insert(&pRoot,5);
    248 insert(&pRoot,12);
    249 insert(&pRoot,4);
    250 insert(&pRoot,7);
    251 Test("test4",pRoot,22);
    252 DestroyTree(pRoot);
    253
    254 }
    255 int _tmain(int argc, _TCHAR* argv[])
    256 {
    257
    258 Test1();
    259 Test2();
    260 Test3();
    261 Test4();
    262
    263 return 0;
    264 }
  • 相关阅读:
    【Java高级工程师蜕变之路】008 Spring核心思想
    【Java高级工程师蜕变之路】003 MyBatis高级进阶
    【Java高级工程师蜕变之路】007 Spring基础回顾
    【Java高级工程师蜕变之路】006 ErrorContext的机制分析
    【Java高级工程师蜕变之路】002 自定义持久层框架
    【Java高级工程师蜕变之路】001 JDBC的问题分析
    如何配置mac环境下的JAVA_HOME
    【Java高级工程师蜕变之路】005 MyBatis插件及其应用
    【Java高级工程师蜕变之路】004 MyBatis源码剖析
    ConcurrentHashMap中的2的n次方幂上舍入方法
  • 原文地址:https://www.cnblogs.com/cslave/p/2388905.html
Copyright © 2020-2023  润新知