关于树的面试题

1:二叉搜索树转换为双向链表

递归思想:分为三部分,以4为根的书,以2为根的左子树,和以6为根的又子树。根据排序链表的定义,4的前驱为左子树上最大的值,后序为右子树上值最小的值。按照中序遍历的顺序,遍历到根结点4的时候,左子树已经转换为一个有序的链表了,并且处在链表最后一个位置的节点为左子树的最大节点。把4与3连接起来,4成为当前链表的最大值,然后再去转换右子树。由此可以联想到用递归。

非递归思想:二叉树的非递归中序遍历,用栈的方法,记录前一个出栈的节点即可。

   1: #include<iostream>
   2: #include <queue>
   3: #include <stack>
   4: using namespace std;
   5: struct BSTreeNode
   6: {
   7:     int m_nValue;
   8:     BSTreeNode *m_pLeft;
   9:     BSTreeNode *m_pRight;
  10: };
  11: typedef BSTreeNode * BSTree;
  12:  
  13: BSTreeNode * CreateBSTree(BSTreeNode *t,int value)
  14: {
  15:     if(t== NULL)
  16:     {
  17:         t = new BSTreeNode;
  18:         t->m_nValue = value;
  19:         t->m_pLeft = NULL;
  20:         t->m_pRight = NULL;
  21:     }
  22:     return t;
  23: }
  24:  
  25: void InsertBSTreeNode(BSTreeNode **t,int value)
  26: {
  27:     if(*t==NULL)
  28:     {
  29:             //(*t) = (BSTreeNode *)malloc(sizeof(BSTreeNode));
  30:             (*t) = new BSTreeNode;
  31:             (*t)->m_nValue = value;
  32:             (*t)->m_pLeft = NULL;
  33:             (*t)->m_pRight = NULL;
  34:             return;
  35:     }
  36:     if(value > (*t)->m_nValue)InsertBSTreeNode(&((*t)->m_pRight),value);
  37:     if(value < (*t)->m_nValue)InsertBSTreeNode(&((*t)->m_pLeft),value);
  38: }
  39: void PrintBSTreeBylevel(BSTreeNode *root)
  40: {
  41:     queue<BSTreeNode *> q;
  42:     if(root != NULL)
  43:     {
  44:             cout<<root->m_nValue<<"**";
  45:             if(root->m_pLeft != NULL)q.push(root->m_pLeft);
  46:             if(root->m_pRight != NULL)q.push(root->m_pRight);
  47:     }
  48:     while (!q.empty())
  49:     {
  50:         BSTreeNode *p = q.front();
  51:         cout<<p->m_nValue<<"**";
  52:         if (p->m_pLeft != NULL)q.push(p->m_pLeft);
  53:         if(p->m_pRight!= NULL)q.push(p->m_pRight);
  54:         q.pop();
  55:     }
  56: }
  57: BSTreeNode * BSTreeToDoubleLinkedList1(BSTree tree,BSTreeNode* &lastNode)
  58: {
  59:     BSTreeNode *head = NULL;
  60:     if (tree == NULL)
  61:     {
  62:         lastNode = NULL;
  63:         return NULL;
  64:     }
  65:     if (tree->m_pLeft == NULL)//左子树为空,则该节点为链表的头节点
  66:     {
  67:         head = tree;
  68:     }
  69:     else
  70:     {
  71:         head = BSTreeToDoubleLinkedList1(tree->m_pLeft,lastNode);//返回左子树,链表的头结点。
  72:         lastNode->m_pRight = tree;//左子树转换链表的最后一个节点连接根节点
  73:         tree->m_pLeft = lastNode;//根节点的前驱为左子树转换后链表的最后一个节点。
  74:     }
  75:  
  76:     if (tree->m_pRight == NULL)//若无右子树,该节点为链表的最后节点
  77:     {
  78:         lastNode = tree;
  79:     }
  80:     else
  81:     {
  82:         tree->m_pRight = BSTreeToDoubleLinkedList1(tree->m_pRight,lastNode);
  83:         tree->m_pRight->m_pLeft = tree;
  84:     }
  85:     return head;
  86: }
  87: //非递归解法,采用栈存储,非递归中序遍历
  88: BSTreeNode * BSTreeToDoubleLinkedList2(BSTreeNode *node)
  89: {
  90:     stack<BSTreeNode *> s;
  91:     BSTreeNode *pHead = NULL;
  92:     BSTreeNode *preNode = NULL;//前驱
  93:     while(node!=NULL || !s.empty())
  94:     {
  95:         while(node)
  96:         {
  97:             s.push(node);
  98:             node = node->m_pLeft;
  99:         }
 100:         if (!s.empty())//
 101:         {
 102:             node = s.top();
 103:             if(pHead == NULL)
 104:             {
 105:                 pHead = node;//头结点
 106:                 pHead->m_pLeft =NULL;
 107:                 preNode = pHead;
 108:             }
 109:             else
 110:             {
 111:                 preNode->m_pRight = node;//前驱指向后继
 112:                 node->m_pLeft = preNode;//当前指向前驱
 113:                 preNode = node;
 114:             }
 115:             cout<<node->m_nValue<<"**";
 116:             s.pop();
 117:             node = node->m_pRight;
 118:         }
 119: }
 120:     return pHead;
 121: }
 122: void PrintList(BSTreeNode *p)
 123: {
 124:     while(p)
 125:     {
 126:         if(p->m_pLeft!=NULL)cout<<"\tpre:\t"<<p->m_pLeft->m_nValue;
 127:         else cout<<"\tpre\t:NULL";//前驱
 128:         cout<< "\tcur:\t"<<p->m_nValue;//当前
 129:         if(p->m_pRight!= NULL)cout<<"\tpost\t"<<p->m_pRight->m_nValue;//后继
 130:         else cout<<"\tpost:\tNULL";
 131:         cout<<endl;
 132:         p = p->m_pRight;
 133:     }
 134: }
 135: void main()
 136: {
 137:     BSTreeNode *ptree1 = NULL,*ptree2 = NULL;
 138:     BSTreeNode *plastNode;
 139:     BSTreeNode *p1,*p2;
 140:     //p = CreateBSTree(p,7);
 141:     int a[15] = {7,3,11,1,5,9,13,0,2,4,6,8,10,12,14};
 142:     for (int i = 0; i < 15; i++)//创建二叉排序树
 143:     {
 144:         InsertBSTreeNode(&ptree1,a[i]);
 145:         InsertBSTreeNode(&ptree2,a[i]);
 146:     }
 147:     PrintBSTreeBylevel(ptree1);//按层打印树
 148:     p1 = BSTreeToDoubleLinkedList1(ptree1,plastNode);
 149:     cout<<endl;
 150:     p2 = BSTreeToDoubleLinkedList2(ptree2);
 151:     cout<<endl;
 152:     cout<<endl<<"-------------递归方法---------------"<<endl;
 153:     PrintList(p1);
 154:     cout<<endl<<"-------------非递归方法---------------"<<endl;
 155:     PrintList(p2);
 156:     system("pause");
 157: }

输出结果:

image

参考资料:

[1]http://zephiruswt.blog.51cto.com/5193151/886171

[2]剑指offer

 


2:二叉树中和为某一值的路径

输入一棵二叉树和一个整,打印出二叉树中结点值的和为输入整数的所有路径,从树的根节点开始一直到页结点所经过的路径称为一条路径

   1: #include<iostream>
   2: #include <vector>
   3: using namespace std;
   4: #define NIL (2^32 - 1)
   5: struct node{
   6:     int value;
   7:     node *pleft;
   8:     node *pright;
   9: };
  10:  
  11: typedef node * BiTree;
  12: void CreateBiTreeByArray(BiTree &t,int array[],int i,int len)
  13: {
  14:     if(i > len||array[i] == NIL)return;
  15:     t = new node;
  16:     t->value = array[i];
  17:     t->pleft = NULL;
  18:     t->pright = NULL;
  19:     CreateBiTreeByArray(t->pleft,array,2*i,len);
  20:     CreateBiTreeByArray(t->pright,array,2*i+1,len);
  21: }
  22: void display(BiTree *t)        //显示树形结构   
  23: {  
  24:     if(*t!=NULL)  
  25:     {  
  26:         cout<<(*t)->value;  
  27:         if((*t)->pleft!=NULL)  
  28:         {  
  29:             cout<<'(';  
  30:             display(&(*t)->pleft);  
  31:         }  
  32:         if((*t)->pright!=NULL)  
  33:         {  
  34:             cout<<',';  
  35:             display(&(*t)->pright);  
  36:             cout<<')';  
  37:         }  
  38:     }  
  39: }
  40: void FindTreePathEqualK(BiTree &t,vector<int> &path,int cursum,int k)//利用vector存储路径
  41: {
  42:     cursum += t->value;
  43:     path.push_back(t->value);
  44:     bool isLeaf = (t->pleft == NULL && t->pright==NULL);
  45:     if (isLeaf && cursum == k)
  46:     {
  47:         cout<<"\n---------\n";
  48:         vector<int>::iterator itor;
  49:         for (itor = path.begin(); itor != path.end();itor++)
  50:         {
  51:             cout <<*itor<<" ";
  52:         }
  53:     }
  54:     //不是叶结点,则遍历它的子节点。
  55:     if(t->pleft!=NULL)FindTreePathEqualK(t->pleft,path,cursum,k);
  56:     if (t->pright!=NULL)FindTreePathEqualK(t->pright,path,cursum,k);
  57:     cursum -= t->value;//返回父结点之前删除结点。并减去当前结点的值
  58:     path.pop_back();
  59: }
  60: void EqualK(BiTree t,int k)
  61: {
  62:     if(t==NULL)return;
  63:     vector<int> path;
  64:     int cursum = 0;
  65:     FindTreePathEqualK(t,path,cursum,k);
  66: }
  67: void main()
  68: {
  69:     /*
  70:             3
  71:          /     \
  72:          4      7
  73:         /  \    / \
  74:        2    0   3  2
  75:       / \  /
  76:      3     7 5
  77:      */
  78:     int array[11] = {NIL,3,4,7,2,0,3,2,3,7,5};
  79:     BiTree t;
  80:     CreateBiTreeByArray(t,array,1,10);
  81:     display(&t);
  82:     EqualK(t,12);
  83:     system("pause");
  84: }

posted @ 2012-10-22 21:52  foreverlearn  阅读(1306)  评论(0编辑  收藏  举报