首页 > 代码库 > [原创]二叉树相关笔试题代码

[原创]二叉树相关笔试题代码

   1 //二叉树问题集:   2 //20140822   3    4 #include <iostream>   5 #include <cstdio>   6 #include <cstdlib>   7 #include <queue>   8 #include <stack>   9 #include <list>  10 using namespace std;  11   12   13 typedef int ElementType;  14 typedef struct TreeNode  15 {  16     ElementType data;  17     struct TreeNode* pLeft;  18     struct TreeNode* pRight;  19 }TreeNode;  20   21 typedef struct TreeNode* PtrNode;  22 typedef struct TreeNode* BinaryTree;  23   24   25 //建立二叉树:  26 PtrNode CreateBinaryTreeNode(ElementType val)  27 {  28     PtrNode ptrNode = new TreeNode;  29     ptrNode->data =http://www.mamicode.com/ val;  30     ptrNode->pLeft = NULL;  31     ptrNode->pRight = NULL;  32     return ptrNode;  33 }  34   35 void ConnectTreeNodes(PtrNode pNode1, PtrNode pNode2, PtrNode pNode3)  36 {  37     if (pNode1 == NULL)  38     {  39         return ;  40     }  41     pNode1->pLeft = pNode2;  42     pNode1->pRight = pNode3;  43 }  44   45 BinaryTree CreateBinaryTree()  46 {  47     PtrNode pNode1 = CreateBinaryTreeNode(1);  48     PtrNode pNode2 = CreateBinaryTreeNode(2);  49     PtrNode pNode3 = CreateBinaryTreeNode(3);  50     PtrNode pNode4 = CreateBinaryTreeNode(4);  51     PtrNode pNode5 = CreateBinaryTreeNode(5);  52     PtrNode pNode6 = CreateBinaryTreeNode(6);  53     PtrNode pNode7 = CreateBinaryTreeNode(7);  54     PtrNode pNode8 = CreateBinaryTreeNode(8);  55     PtrNode pNode9 = CreateBinaryTreeNode(9);  56     PtrNode pNode10 = CreateBinaryTreeNode(10);  57     PtrNode pNode11 = CreateBinaryTreeNode(11);  58     PtrNode pNode12 = CreateBinaryTreeNode(12);  59   60     ConnectTreeNodes(pNode1, pNode2, pNode3);  61     ConnectTreeNodes(pNode2, pNode4, pNode5);  62     ConnectTreeNodes(pNode3, pNode6, pNode7);  63     ConnectTreeNodes(pNode4, pNode8, pNode9);  64     ConnectTreeNodes(pNode8, pNode10, pNode11);  65   66     return pNode1;  67 }  68 BinaryTree CreateBinaryTree2()  69 {  70     PtrNode pNode1 = CreateBinaryTreeNode(1);  71     PtrNode pNode2 = CreateBinaryTreeNode(2);  72     PtrNode pNode3 = CreateBinaryTreeNode(3);  73     PtrNode pNode4 = CreateBinaryTreeNode(4);  74     PtrNode pNode5 = CreateBinaryTreeNode(5);  75     PtrNode pNode6 = CreateBinaryTreeNode(6);  76     PtrNode pNode7 = CreateBinaryTreeNode(7);  77     PtrNode pNode8 = CreateBinaryTreeNode(8);  78     PtrNode pNode9 = CreateBinaryTreeNode(9);  79     PtrNode pNode10 = CreateBinaryTreeNode(10);  80     PtrNode pNode11 = CreateBinaryTreeNode(11);  81     PtrNode pNode12 = CreateBinaryTreeNode(12);  82   83     ConnectTreeNodes(pNode1, pNode2, pNode3);  84     ConnectTreeNodes(pNode2, pNode4, pNode5);  85     ConnectTreeNodes(pNode3, pNode6, pNode7);  86     ConnectTreeNodes(pNode4, pNode8, pNode9);  87     ConnectTreeNodes(pNode8, pNode10, NULL);  88   89     return pNode1;  90 }  91   92 BinaryTree CreateBinaryTree3()  93 {  94     PtrNode pNode1 = CreateBinaryTreeNode(10);  95     PtrNode pNode2 = CreateBinaryTreeNode(5);  96     PtrNode pNode3 = CreateBinaryTreeNode(12);  97     PtrNode pNode4 = CreateBinaryTreeNode(4);  98     PtrNode pNode5 = CreateBinaryTreeNode(7);  99     ConnectTreeNodes(pNode1, pNode2, pNode3); 100     ConnectTreeNodes(pNode2, pNode4, pNode5); 101  102     return pNode1; 103 } 104  105 BinaryTree CreateBinaryTree4() 106 { 107     PtrNode pNode1 = CreateBinaryTreeNode(1); 108     PtrNode pNode2 = CreateBinaryTreeNode(2); 109     PtrNode pNode3 = CreateBinaryTreeNode(3); 110     PtrNode pNode4 = CreateBinaryTreeNode(4); 111     PtrNode pNode5 = CreateBinaryTreeNode(5); 112     PtrNode pNode6 = CreateBinaryTreeNode(6); 113     PtrNode pNode7 = CreateBinaryTreeNode(7); 114     PtrNode pNode8 = CreateBinaryTreeNode(8); 115     PtrNode pNode9 = CreateBinaryTreeNode(9); 116     PtrNode pNode10 = CreateBinaryTreeNode(10); 117     PtrNode pNode11 = CreateBinaryTreeNode(11); 118     PtrNode pNode12 = CreateBinaryTreeNode(12); 119  120     //ConnectTreeNodes(pNode1, pNode2, pNode3); 121     //ConnectTreeNodes(pNode2, pNode4, pNode5); 122     ConnectTreeNodes(pNode3, pNode6, pNode7); 123     ConnectTreeNodes(pNode4, pNode8, pNode9); 124     //ConnectTreeNodes(pNode8, pNode10, pNode11); 125  126     return pNode1; 127 } 128  129 //先序遍历:递归 130 void PerOrderPrint(BinaryTree Tree) 131 { 132     if (Tree == NULL) 133     { 134         return ; 135     } 136  137     cout << Tree->data << " "; 138     PerOrderPrint(Tree->pLeft); 139     PerOrderPrint(Tree->pRight); 140  141 } 142  143 //中序遍历:递归 144 void InOrderPrint(BinaryTree Tree) 145 { 146     if (Tree == NULL) 147     { 148         return; 149     } 150     InOrderPrint(Tree->pLeft); 151     cout << Tree->data << " "; 152     InOrderPrint(Tree->pRight); 153 } 154  155 //后序遍历:递归 156 void PostOrderPrint(BinaryTree Tree) 157 { 158     if (Tree == NULL) 159     { 160         return; 161     } 162     PostOrderPrint(Tree->pLeft); 163     PostOrderPrint(Tree->pRight); 164     cout << Tree->data << " "; 165 } 166  167 /************************************************************************/ 168 /* 二叉树的非递归遍历:先序,中序、后序、及层序遍历 169 /************************************************************************/ 170 /************************************************************************ 171 * 非递归先序遍历: 172 * 方法:用栈结构, 173 *    1.先让右子树节点进栈,再让左子树节点进栈 174 *    2.如果栈非空,则进行出栈操作 175 *    类似于层序遍历 176 ************************************************************************/ 177 void PerOrderPrintNoRecursive(BinaryTree Tree) 178 { 179     if (Tree == NULL) 180     { 181         return; 182     } 183     PtrNode ptrNode = Tree; 184     stack<PtrNode> s; 185     s.push(ptrNode); 186     while (!s.empty()) 187     { 188         ptrNode = s.top(); 189         cout << ptrNode->data << " "; 190         s.pop(); 191         if (ptrNode->pRight != NULL) //注意:先序遍历先让右子树节点入栈 192         { 193             s.push(ptrNode->pRight); 194         } 195         if (ptrNode->pLeft != NULL) 196         { 197             s.push(ptrNode->pLeft); 198         } 199     } 200 } 201  202  203 /************************************************************************ 204 * 非递归中序遍历: 205 * 方法:用栈结构, 206 *    1. 207 *    2. 208 ************************************************************************/ 209 void InOrderPrintNoRecursive(BinaryTree Tree) 210 { 211     if (Tree == NULL) 212     { 213         return; 214     } 215  216     PtrNode ptrCurrent = Tree; //指明当前要检测的数据,此时根节点不要先入栈 217     stack<PtrNode> s; 218     while (ptrCurrent != NULL || !s.empty()) 219     { 220         while (ptrCurrent != NULL) 221         { 222             s.push(ptrCurrent); 223             ptrCurrent = ptrCurrent->pLeft; 224         } 225         if (!s.empty()) 226         { 227             ptrCurrent = s.top(); 228             cout << ptrCurrent->data << " "; 229             s.pop(); 230             ptrCurrent = ptrCurrent->pRight; 231         } 232     } 233 } 234  235  236 /************************************************************************ 237 * 非递归后序遍历: 238 * 方法:用栈结构, 239 ************************************************************************/ 240 //void PostOrderNoRecursive(BinaryTree Tree) 241 //{ 242 //    if (Tree == NULL) 243 //    { 244 //        return ; 245 //    } 246  247 //    PtrNode ptrCurr = Tree; 248 //    stack<PtrNode> s; 249 //    s.push(ptrCurr); 250 //    while (ptrCurr != NULL || !s.empty()) 251 //    { 252 //        while (ptrCurr != NULL) 253 //        { 254 //            ptrCurr = s.top(); 255 //            if (ptrCurr->pLeft != NULL) 256 //            { 257 //                s.push(ptrCurr->pLeft); 258 //            } 259 //            if (ptrCurr->pRight != NULL) 260 //            { 261 //                s.push(ptrCurr->pRight); 262 //            } 263 //        } 264  265 //    } 266  267 //} 268  269  270  271 //层序遍历二叉树 272 void LayerOrderPrint(BinaryTree Tree) 273 { 274     if (Tree == NULL) 275     { 276         return ; 277     } 278  279     int nodeNumInTree = 0; //  记录节点的个数 280     queue<PtrNode> Queue; 281     PtrNode ptrNode = Tree; 282     Queue.push(ptrNode); 283     while (!Queue.empty()) 284     { 285         ptrNode = Queue.front(); 286         cout << ptrNode->data << " " ; 287         nodeNumInTree++; 288         Queue.pop(); 289         if (ptrNode->pLeft != NULL) 290         { 291             Queue.push(ptrNode->pLeft); 292         } 293         if (ptrNode->pRight != NULL) 294         { 295             Queue.push(ptrNode->pRight); 296         } 297     } 298  299     //cout << endl; 300     //cout << "节点的个数: " << nodeNumInTree; 301  302     return ; 303 } 304  305  306 //求书中结点的个数 307 int GetNodeNumber(BinaryTree Tree) 308 { 309     if (Tree == NULL) 310     { 311         return 0; 312     } 313     return GetNodeNumber(Tree->pLeft) + GetNodeNumber(Tree->pRight) + 1; 314 } 315  316 //求叶子节点的个数: 317 int GetLeavesNumber(BinaryTree Tree) 318 { 319     if (Tree == NULL) 320     { 321         return 0; 322     } 323     static int leavesNum = 0; 324  325     if (Tree->pLeft == NULL && Tree->pRight == NULL) 326     { 327         leavesNum++; 328     } 329     GetLeavesNumber(Tree->pLeft); 330     GetLeavesNumber(Tree->pRight); 331  332     return leavesNum; 333 } 334  335 //求二叉树深度 336 int GetTreeDepth(BinaryTree Tree) 337 { 338     if (Tree == NULL) 339     { 340         return 0; 341     } 342     int leftDepth = GetTreeDepth(Tree->pLeft); 343     int rightDepth = GetTreeDepth(Tree->pRight); 344  345     return leftDepth >= rightDepth?leftDepth+1:rightDepth+1; 346 } 347  348 //将二叉树变为有序的双向链表 剑指offer27题 349 void ConvertToDoubleList(BinaryTree Tree, PtrNode* listNode); 350 BinaryTree ConvertToList(BinaryTree Tree) 351 { 352     if (Tree == NULL) 353     { 354         return NULL; 355     } 356  357     PtrNode listNode = NULL; 358     ConvertToDoubleList(Tree, &listNode); 359  360     //返回头结点: 361     PtrNode lastNode = listNode; 362     while (lastNode != NULL && lastNode->pLeft != NULL) 363     { 364         lastNode = lastNode->pLeft; 365     } 366  367  368  369     return lastNode; 370 } 371 void ConvertToDoubleList(BinaryTree Tree, PtrNode* listNode) 372 { 373     if (Tree == NULL) 374     { 375         return ; 376     } 377  378     PtrNode pCurrent = Tree; 379     if (pCurrent->pLeft != NULL) 380     { 381         ConvertToDoubleList(pCurrent->pLeft, listNode); 382     } 383  384     pCurrent->pLeft = *listNode; 385     if (*listNode != NULL) 386     { 387         (*listNode)->pRight = pCurrent; 388     } 389     *listNode = pCurrent; 390  391     if (pCurrent->pRight != NULL) 392     { 393         ConvertToDoubleList(pCurrent->pRight, listNode); 394     } 395 } 396  397 void PrintList(BinaryTree ListTree) 398 { 399     if (ListTree == NULL) 400     { 401         return; 402     } 403     PtrNode p = ListTree; 404     while (p != NULL) 405     { 406         cout << p->data << " "; 407         p = p->pRight; 408     } 409     cout << endl; 410 } 411 //转换成双向链表完 412  413  414 /********************************************************* 415 * 求二叉树第K层的节点数 416 * 1.如果树为空或者K<1,返回0 417 * 2.如果K == 1, 返回1 418 * 3.如果K>1, 节点数等于左子树第K-1层节点与右子树第K-1层之和 419 **********************************************************/ 420 //递归 421 int GetNodeNumInLayerK(BinaryTree Tree, int k) 422 { 423     if (Tree == NULL || k < 1) 424     { 425         return 0; 426     } 427     if (k == 1) 428     { 429         return 1; 430     } 431  432     return GetNodeNumInLayerK(Tree->pLeft, k - 1) + GetNodeNumInLayerK(Tree->pRight, k - 1); 433 } 434 //非递归,根据层序遍历,求出第K层节点数 435 int GetNodeNumInLayerKByLayerPrint(BinaryTree Tree, int k) 436 { 437     if (Tree == NULL || k < 1) 438     { 439         return 0; 440     } 441 //    if (k == 1) 442 //    { 443 //        return 1; 444 //    } 445  446     PtrNode ptrNode = Tree; 447     queue<PtrNode> q; 448     q.push(ptrNode); 449     while (q.size()) 450     { 451         --k; 452         if (k <= 0) break; 453         int nodeNumInQ = q.size(); 454         while (nodeNumInQ--) 455         { 456             ptrNode = q.front(); 457             q.pop(); 458             if (ptrNode->pLeft != NULL) 459             { 460                 q.push(ptrNode->pLeft); 461             } 462             if (ptrNode->pRight != NULL) 463             { 464                 q.push(ptrNode->pRight); 465             } 466         } 467     } 468     return q.size(); 469 } 470  471  472 /********************************************************* 473 * 判断两个树结构是否结构相同  474 * 1.如果两个树都为空,返回true; 475 * 2.如果一个为空,一个不为空, 返回flase 476 * 3.如果都不为空, 则判断对应的左右子树是否结构相同,  477 **********************************************************/ 478 bool StructureCmp(BinaryTree Tree1, BinaryTree Tree2) 479 { 480     if (Tree1 == NULL && Tree2 == NULL) 481     { 482         return true; 483     } 484     if (Tree1 == NULL && Tree2 != NULL || Tree1 != NULL && Tree2 == NULL) 485     { 486         return false; 487     } 488  489     bool left = StructureCmp(Tree1->pLeft, Tree2->pLeft); 490     bool right = StructureCmp(Tree1->pRight, Tree2->pRight); 491     return (left && right); 492 } 493  494  495 /********************************************************* 496 * 判断树的子结构  497 * 输入两个树A和B,判断树B是否是树A的子结构 498 * 1.如果两个树都为空,返回false; 499 * 2.如果一个为空,一个不为空, 返回flase 500 * 3.如果都不为空, 则判断对应的是否是子结构,  501 * 4.步骤: 502 *    1)在A中找到和B的根节点的值相同的节点R 503 *    2)判断树A中以R为根节点的子树是不是包含和树B一样的结构 504 * 剑指offer,第18题 505 **********************************************************/ 506 bool DoesTreeAHaveTreeB(BinaryTree TreeA, BinaryTree TreeB); 507 bool HasSubtree(BinaryTree TreeA, BinaryTree TreeB) 508 { 509     bool result = false; 510     if (TreeA != NULL && TreeB != NULL) 511     { 512         if (TreeA->data =http://www.mamicode.com/= TreeB->data) 513         { 514             result = DoesTreeAHaveTreeB(TreeA,TreeB); 515         } 516         if (!result) 517         { 518             result = HasSubtree(TreeA->pLeft, TreeB); 519         } 520         if (!result) 521         { 522             result = HasSubtree(TreeA->pRight, TreeB); 523         } 524     } 525     return result; 526 } 527  528 bool DoesTreeAHaveTreeB(BinaryTree TreeA, BinaryTree TreeB) 529 { 530     if (TreeA == NULL) 531     { 532         return false; 533     } 534     if (TreeB == NULL) 535     { 536         return true; 537     } 538  539     return DoesTreeAHaveTreeB(TreeA->pLeft, TreeB->pLeft) && DoesTreeAHaveTreeB(TreeA->pRight,  540         TreeB->pRight); 541 } 542  543  544  545  546 /********************************************************* 547 * 判断树是否是平衡二叉树 548 * 1.如果树为空,返回true; 549 * 2.如果不为空, 则判断左右子树是否都是AVL,且左右子树高度相差不大于1,则返回true,其他返回false,  550 **********************************************************/ 551 bool IsAVL(BinaryTree Tree, int& Height) 552 { 553     if (Tree == NULL) 554     { 555         return true; 556     } 557  558     int leftHeight = 0; 559     int rightHeight = 0; 560     bool isLeftAVL = IsAVL(Tree->pLeft, leftHeight); 561     bool isRightAVL = IsAVL(Tree->pRight, rightHeight); 562     Height = leftHeight >= rightHeight?leftHeight+1:rightHeight+1; 563  564     if (isLeftAVL && isRightAVL && abs(leftHeight - rightHeight) <= 1) 565     { 566         return true; 567     } 568     else 569     { 570         return false; 571     } 572  573 } 574  575  576  577 /********************************************************* 578 * 求二叉树的镜像  579 * 1.左右子树交换; 580 **********************************************************/ 581 void TreeMirror(BinaryTree Tree) 582 { 583     if (Tree == NULL) 584     { 585         return ; 586     } 587     PtrNode ptrNode = NULL; 588     ptrNode = Tree->pLeft; 589     Tree->pLeft = Tree->pRight; 590     Tree->pRight = ptrNode; 591  592     TreeMirror(Tree->pLeft); 593     TreeMirror(Tree->pRight); 594 } 595  596 /********************************************************* 597 * 重建二叉树 598 * 根据二叉树的先序及中序遍历,重建二叉树 599 * 剑指offer 6题;编程之美3.9 600 **********************************************************/ 601 PtrNode ConstructBinaryTree(int* startPerOrder, int* endPerOrder, int* startInOrder, int* endInOrder); 602 BinaryTree RebuildTree(int* PerOrder, int* InOrder, int length) 603 { 604     if (PerOrder == NULL || InOrder == NULL || length <= 0) 605     { 606         return NULL; 607     } 608  609     BinaryTree rebuildTree = NULL; 610     rebuildTree = ConstructBinaryTree(PerOrder, PerOrder+length-1, InOrder, InOrder+length-1); 611  612     return rebuildTree; 613 } 614 PtrNode ConstructBinaryTree(int* startPerOrder, int* endPerOrder, int* startInOrder, int* endInOrder) 615 { 616     PtrNode rootNode = new TreeNode;  617     rootNode->pLeft = rootNode->pRight = NULL; 618     rootNode->data = http://www.mamicode.com/startPerOrder[0]; 619  620     int* ptrInOrder = startInOrder; 621     while (*ptrInOrder != rootNode->data && ptrInOrder <= endInOrder) 622         ++ptrInOrder; 623     int leftLen = ptrInOrder - startInOrder; 624  625     if (leftLen > 0) 626     { 627         rootNode->pLeft = ConstructBinaryTree(startPerOrder+1, startPerOrder+leftLen, 628             startInOrder, startInOrder+leftLen-1); 629     } 630     if (leftLen < endPerOrder - startPerOrder) 631     { 632         rootNode->pRight = ConstructBinaryTree(startPerOrder+leftLen+1, endPerOrder, 633             startInOrder+leftLen+1, endInOrder); 634     } 635  636     return rootNode; 637 } 638  639  640  641 /********************************************************* 642 * 找最低公共祖先  643 * 1.如果两个节点为根节点的左右子节点,则返回根节点 644 * 2.如果都在左子树,则递归处理左子树,如果都在右子树,则递归处理右子树 645 **********************************************************/ 646 bool FindNode(BinaryTree Tree, PtrNode pNode) 647 { 648     if (Tree == NULL) 649     { 650         return false; 651     } 652     if (Tree == pNode) 653     { 654         return true; 655     } 656     bool found = FindNode(Tree->pLeft, pNode); 657     if (!found) 658     { 659         found = FindNode(Tree->pRight, pNode); 660     } 661  662     return found; 663 } 664 PtrNode GetLastCommonParent(BinaryTree Tree, PtrNode pNode1, PtrNode pNode2) 665 { 666     if (Tree == NULL || pNode1 == NULL || pNode2 == NULL) 667     { 668         return NULL; 669     } 670     if (FindNode(Tree->pLeft, pNode1)) 671     { 672         if (FindNode(Tree->pRight, pNode2)) 673         { 674             return Tree; 675         } 676         else 677             return GetLastCommonParent(Tree->pLeft, pNode1, pNode2); 678     } 679     else if (FindNode(Tree->pRight, pNode1)) 680     { 681         if (FindNode(Tree->pLeft, pNode2)) 682         { 683             return Tree; 684         } 685         else 686             return GetLastCommonParent(Tree->pRight, pNode1, pNode2); 687     } 688 } 689  690 //递归解法二: 691 PtrNode GetLCA(BinaryTree Tree, PtrNode pNode1, PtrNode pNode2) 692 { 693     if (Tree == NULL) 694     { 695         return NULL; 696     } 697     if (Tree == pNode1 || Tree == pNode2) 698     { 699         return Tree; 700     } 701      702     PtrNode leftNode = GetLCA(Tree->pLeft, pNode1, pNode2); 703     PtrNode rightNode = GetLCA(Tree->pRight, pNode1, pNode2); 704  705     if (leftNode != NULL && rightNode != NULL) 706     { 707         return Tree; 708     } 709     else if (leftNode != NULL) 710     { 711         return leftNode; 712     } 713     else if (rightNode != NULL) 714     { 715         return rightNode; 716     } 717     else 718         return NULL; 719 } 720  721 //非递归解法:先求出两个节点从根节点开始的路径,然后比较路径节点,最后一个相同的就是公共祖先节点 722 bool GetNodePath(BinaryTree Tree, PtrNode pNode, list<PtrNode>& path) 723 { 724     if (Tree == NULL) 725     { 726         return false; 727     } 728     path.push_back(Tree); 729     if (Tree == pNode) 730     { 731         return true; 732     } 733  734     bool found = GetNodePath(Tree->pLeft, pNode, path); 735     if (!found) 736     { 737         found = GetNodePath(Tree->pRight, pNode, path); 738     } 739  740     if (!found) 741     { 742         path.pop_back(); 743     } 744  745     return found; 746 } 747 PtrNode GetLastCommonParentNoRecur(BinaryTree Tree, PtrNode pNode1, PtrNode pNode2) 748 { 749     if (Tree == NULL) 750     { 751         return NULL; 752     } 753     list<PtrNode> path1; 754     bool foundNode1 = GetNodePath(Tree, pNode1, path1); 755     list<PtrNode> path2; 756     bool foundNode2 = GetNodePath(Tree, pNode2, path2); 757     if (!foundNode1 || !foundNode2) 758     { 759         return NULL; 760     } 761  762     PtrNode lastCommonNode = NULL; 763     list<PtrNode>::iterator iter1 = path1.begin(); 764     list<PtrNode>::iterator iter2 = path2.begin(); 765     while (iter1 != path1.end() && iter2 != path2.end()) 766     { 767         if (*iter1 == *iter2) 768         { 769             lastCommonNode = *iter1; 770         } 771         else 772             break; 773         iter1++; 774         iter2++; 775     } 776     return lastCommonNode; 777 } 778  779  780  781 /********************************************************* 782 * 求二叉树中节点的最大距离 783 * 1.如果为空,则最大距离就为0,同时左右子树的最大深度为0 784 * 2.如果不为空,则最大距离要么是左子树最大深度,要么是右子树 785 *    最大深度,要么是左右子树最大深度之和,同时记录左右 786 *    子树的最大深度 787 * 剑指offer;编程之美3.8 788 **********************************************************/ 789 int GetLargestDestInNode(BinaryTree Tree, int& nMaxLeft, int& nMaxRight) 790 { 791     if (Tree == NULL) 792     { 793         nMaxLeft = 0; 794         nMaxRight = 0; 795         return 0; 796     } 797     int maxLL = 0, maxLR = 0; 798     int maxRL = 0, maxRR = 0; 799     int maxDistLeft = 0; 800     int maxDistRight = 0; 801     if (Tree->pLeft == NULL) 802     { 803         maxDistLeft = 0; 804         nMaxLeft = 0; 805     } 806     if (Tree->pRight == NULL) 807     { 808         maxDistRight = 0; 809         nMaxRight = 0; 810     } 811  812     if(Tree->pLeft != NULL) 813     { 814         maxDistLeft = GetLargestDestInNode(Tree->pLeft, maxLL, maxLR); 815         nMaxLeft = maxLL>maxLR?maxLL+1:maxLR+1; 816     } 817     if(Tree->pRight != NULL) 818     { 819         maxDistRight = GetLargestDestInNode(Tree->pRight, maxRL, maxRR); 820         nMaxRight = maxRL>maxRR?maxRL+1:maxRR+1; 821     } 822  823     int maxDist = maxDistLeft>maxDistRight?maxDistLeft:maxDistRight; 824     int nMax = nMaxLeft + nMaxRight; 825     return maxDist>nMax?maxDist:nMax; 826 } 827  828 /********************************************************* 829 * 求二叉树中和为某一值得路径 830 * 路径:从根节点到叶子节点的路径 831 * 1.如果树为空,则路径为空 832 * 2.如果树不为空,则从根节点开始遍历(即前序遍历),遍历的过程中记录路径 833 *    并记录遍历过的路径的和,如果遍历到叶子节点,判断和是否为所给值, 834 *    如果是,则输出此路径,然后再回到上一个节点。 835 *    记录节点的路径就是一个栈结构, 836 * 注意:在回到上一个几点时,要将叶子节点出栈 837 * 另:本题用vector实现,是因为需要打印路径时,stack无法遍历打印 838 * 剑指offer25题 839 **********************************************************/ 840 void GetRoad(BinaryTree Tree, vector<int>& path, const int& expectedSum, int& currentSum); 841 void GetRoad(BinaryTree Tree, int expectedSum) 842 { 843     if (Tree == NULL) 844     { 845         return; 846     } 847     vector<int> path; 848     int currentSum = 0; 849     GetRoad(Tree, path, expectedSum, currentSum); 850     return ; 851 } 852 void GetRoad(BinaryTree Tree, vector<int>& path, const int& expectedSum, int& currentSum) 853 { 854     if (Tree == NULL) 855     { 856         return ; 857     } 858  859     path.push_back(Tree->data); 860     currentSum += Tree->data; 861     bool isLeaf = Tree->pLeft == NULL && Tree->pRight == NULL; 862     if (isLeaf && expectedSum == currentSum) 863     { 864         cout << "和为" << expectedSum << "的路径为: "; 865         vector<int>::iterator iter = path.begin(); 866         for (; iter != path.end(); ++iter) 867         { 868             cout << *iter << " "; 869         } 870         cout << endl; 871     } 872  873     GetRoad(Tree->pLeft, path, expectedSum, currentSum); 874     GetRoad(Tree->pRight, path, expectedSum, currentSum); 875  876     if (!path.empty()) 877     { 878         //在返回父节点之前,应该从currentSum中减去当前节点的值,因为函数传递的参数currentSum是以引用传递的 879         //若currentSum是非引用传递而是一般传值(即int currentSum),则不用这步操作 880         currentSum -= path.back();  881     } 882     path.pop_back(); //在返回到父节点之前,删除路径上当前的节点 883 } 884  885  886 /********************************************************* 887 * 判断二叉树是否是完全二叉树 888 * 1.如果树为空,则返回true 889 * 2.如果树不为空,则从根据层序遍历,遍历到第一个左子树为空的节点 890 *    第一个左子树为空的节点的右子树也为空,并且其以后的所有节点 891 *    的左右字数均为空的话,则为完全二叉树,返回true 892 *    否则,不是完全二叉树,返回false 893 **********************************************************/ 894 bool IsCompleteBinaryTree(BinaryTree Tree) 895 { 896     if (Tree == NULL) 897     { 898         return true; 899     } 900  901     queue<PtrNode> q; 902     PtrNode ptrNode = Tree; 903     q.push(ptrNode); 904      905     PtrNode ptrFirNode = NULL; 906     while (!q.empty()) 907     { 908         ptrNode = q.front(); 909         if (ptrFirNode != NULL && (ptrNode->pLeft != NULL || ptrNode->pRight != NULL)) 910         { 911             return false; 912         } 913         if (ptrFirNode == NULL && (ptrNode->pLeft == NULL || ptrNode->pRight == NULL)) 914         { 915             ptrFirNode = ptrNode; 916         } 917         q.pop(); 918  919         if (ptrNode->pLeft != NULL) 920         { 921             q.push(ptrNode->pLeft); 922         } 923         if (ptrNode->pRight != NULL) 924         { 925             q.push(ptrNode->pRight); 926         } 927     } 928  929     return true; 930 } 931  932  933  934  935 int main() 936 { 937     cout << "建立二叉树..." << endl; 938     BinaryTree Tree = CreateBinaryTree(); 939     BinaryTree Tree2 = CreateBinaryTree2(); 940     BinaryTree Tree4 = CreateBinaryTree4(); 941  942  943     int treeDepth = GetTreeDepth(Tree); 944     cout << "二叉树深度: " << treeDepth << endl; 945  946     int nodeNum = GetNodeNumber(Tree); 947     cout << "二叉树结点个数: " << nodeNum << endl; 948  949     cout << "先序遍历..." << endl; 950     PerOrderPrint(Tree); 951     cout << endl; 952  953     cout << "非递归先序遍历..." << endl; 954     PerOrderPrintNoRecursive(Tree); 955     cout << endl; 956  957     cout << "中序遍历..." << endl; 958     InOrderPrint(Tree); 959     cout << endl; 960  961     cout << "非递归中序遍历..." << endl; 962     InOrderPrintNoRecursive(Tree); 963     cout << endl; 964  965     cout << "非递归后序遍历..." << endl; 966     //PostOrderNoRecursive(Tree); 967     cout << endl; 968  969     cout << "层序遍历..." << endl; 970     LayerOrderPrint(Tree); 971     cout << endl; 972  973     //int nodeNum = GetNodeNumber(Tree); 974     //cout << "二叉树结点个数: " << nodeNum << endl; 975  976  977     int leavesNum = GetLeavesNumber(Tree); 978     cout << "叶节点的个数: " << leavesNum << endl; 979  980 //    //转换成双向链表 981 //    PtrNode treeToList = ConvertToList(Tree); 982 //    cout << "双向链表由左至右打印:" <<endl; 983 //    PrintList(treeToList); 984  985     //第K层的节点数 986     int k = 3; 987     //int nodeNumInK = GetNodeNumInLayerK(Tree, k) - GetNodeNumInLayerK(Tree, k - 1); 988     int nodeNumInK = GetNodeNumInLayerK(Tree, k); 989     cout << "" << k << "层节点数: " << nodeNumInK<< endl;  990     int nodeNumInK2 = GetNodeNumInLayerKByLayerPrint(Tree, k); 991     cout << "根据层序遍历,求得第" << k << "层节点数: " << nodeNumInK2<< endl;  992  993  994     //判断两个树结构是否相同: 995     cout << "判断两个树结构是否形同: " << StructureCmp(Tree, Tree2) << endl; 996  997     //判断B是否是A的子结构: 998     bool hasSubtree = HasSubtree(Tree, Tree4); 999     cout << "是否是子结构"  << hasSubtree << endl;1000 1001     //判断树是否是AVL树:1002     int height = 0;1003     bool isAvl = IsAVL(Tree, height);1004     cout << "是否是AVL树: " << isAvl << endl;1005 1006     //二叉树的镜像:1007     TreeMirror(Tree);1008     cout << "镜像层序输出:";1009     LayerOrderPrint(Tree);1010     //恢复原状:1011     TreeMirror(Tree);1012     cout << endl;1013 1014     //由先序及中序遍历重建二叉树1015     int length = nodeNum;1016     int perOrder[] = {1,2,4,8,10,11,9,5,3,6,7};1017     int inOrder[] = {10,8,11,4,9,2,5,1,6,3,7};1018     BinaryTree rebuildTree = RebuildTree(perOrder, inOrder, length);1019     cout << "重建后层序输出: ";1020     LayerOrderPrint(rebuildTree);1021     cout << endl;1022 1023     //寻找最低公共祖先节点1024     PtrNode commonParentNode = GetLastCommonParent(Tree, Tree->pLeft->pLeft->pLeft, Tree->pRight->pRight);1025     cout << commonParentNode->data << endl;1026     commonParentNode = GetLastCommonParent(Tree, Tree->pLeft->pLeft->pLeft, Tree->pLeft->pRight);1027     cout << "LCA: " << commonParentNode->data << endl;1028     //非递归方法求公共祖先节点:1029     commonParentNode = GetLastCommonParentNoRecur(Tree, Tree->pLeft->pLeft->pLeft, Tree->pLeft->pRight);1030     cout << "LCA: " << commonParentNode->data << endl;1031     //非递归方法求公共祖先节点:1032     //递归方法二:1033     commonParentNode = GetLCA(Tree, Tree->pLeft->pLeft->pLeft, Tree->pLeft->pRight);1034     cout << "LCA: " << commonParentNode->data << endl;1035     1036 1037     //二叉树节点之间的最大距离1038     int nMaxLeft = 0;1039     int nMaxRight = 0;1040     int nMaxLen = GetLargestDestInNode(Tree, nMaxLeft, nMaxRight);1041     cout << nMaxLen << endl;1042 1043 1044     //和为某一个值得路径1045     int expectedSum = 22;1046     BinaryTree Tree3 = CreateBinaryTree3();1047     GetRoad(Tree3, expectedSum);1048 1049     //判断二叉树是否是完全二叉树1050     bool isCompleteTree = IsCompleteBinaryTree(Tree);1051     cout << "是否是完全二叉树: " << isCompleteTree << endl;1052 1053 1054     return 0;1055 }

 

[原创]二叉树相关笔试题代码