关于树的面试题
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: }
输出结果:
参考资料:
[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: 371: / \72: 4 773: / \ / \74: 2 0 3 275: / \ /76: 3 7 577: */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: }