二叉树相关笔试题代码

   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 = 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 == 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 = 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 }

 

你可能感兴趣的:(二叉树)