1:二叉搜索树转换为双向链表
递归思想:分为三部分,以4为根的书,以2为根的左子树,和以6为根的又子树。根据排序链表的定义,4的前驱为左子树上最大的值,后序为右子树上值最小的值。按照中序遍历的顺序,遍历到根结点4的时候,左子树已经转换为一个有序的链表了,并且处在链表最后一个位置的节点为左子树的最大节点。把4与3连接起来,4成为当前链表的最大值,然后再去转换右子树。由此可以联想到用递归。
非递归思想:二叉树的非递归中序遍历,用栈的方法,记录前一个出栈的节点即可。
#include<iostream>
#include <queue>
#include <stack>
using namespace std;
struct BSTreeNode
{
int m_nValue;
BSTreeNode *m_pLeft;
BSTreeNode *m_pRight;
};
typedef BSTreeNode * BSTree;
BSTreeNode * CreateBSTree(BSTreeNode *t,int value)
{
if(t== NULL)
{
t = new BSTreeNode;
t->m_nValue = value;
t->m_pLeft = NULL;
t->m_pRight = NULL;
}
return t;
}
void InsertBSTreeNode(BSTreeNode **t,int value)
{
if(*t==NULL)
{
//(*t) = (BSTreeNode *)malloc(sizeof(BSTreeNode));
(*t) = new BSTreeNode;
(*t)->m_nValue = value;
(*t)->m_pLeft = NULL;
(*t)->m_pRight = NULL;
return;
}
if(value > (*t)->m_nValue)InsertBSTreeNode(&((*t)->m_pRight),value);
if(value < (*t)->m_nValue)InsertBSTreeNode(&((*t)->m_pLeft),value);
}
void PrintBSTreeBylevel(BSTreeNode *root)
{
queue<BSTreeNode *> q;
if(root != NULL)
{
cout<<root->m_nValue<<"**";
if(root->m_pLeft != NULL)q.push(root->m_pLeft);
if(root->m_pRight != NULL)q.push(root->m_pRight);
}
while (!q.empty())
{
BSTreeNode *p = q.front();
cout<<p->m_nValue<<"**";
if (p->m_pLeft != NULL)q.push(p->m_pLeft);
if(p->m_pRight!= NULL)q.push(p->m_pRight);
q.pop();
}
}
BSTreeNode * BSTreeToDoubleLinkedList1(BSTree tree,BSTreeNode* &lastNode)
{
BSTreeNode *head = NULL;
if (tree == NULL)
{
lastNode = NULL;
return NULL;
}
if (tree->m_pLeft == NULL)//左子树为空,则该节点为链表的头节点
{
head = tree;
}
else
{
head = BSTreeToDoubleLinkedList1(tree->m_pLeft,lastNode);//返回左子树,链表的头结点。
lastNode->m_pRight = tree;//左子树转换链表的最后一个节点连接根节点
tree->m_pLeft = lastNode;//根节点的前驱为左子树转换后链表的最后一个节点。
}
if (tree->m_pRight == NULL)//若无右子树,该节点为链表的最后节点
{
lastNode = tree;
}
else
{
tree->m_pRight = BSTreeToDoubleLinkedList1(tree->m_pRight,lastNode);
tree->m_pRight->m_pLeft = tree;
}
return head;
}
//非递归解法,采用栈存储,非递归中序遍历
BSTreeNode * BSTreeToDoubleLinkedList2(BSTreeNode *node)
{
stack<BSTreeNode *> s;
BSTreeNode *pHead = NULL;
BSTreeNode *preNode = NULL;//前驱
while(node!=NULL || !s.empty())
{
while(node)
{
s.push(node);
node = node->m_pLeft;
}
if (!s.empty())//
{
node = s.top();
if(pHead == NULL)
{
pHead = node;//头结点
pHead->m_pLeft =NULL;
preNode = pHead;
}
else
{
preNode->m_pRight = node;//前驱指向后继
node->m_pLeft = preNode;//当前指向前驱
preNode = node;
}
cout<<node->m_nValue<<"**";
s.pop();
node = node->m_pRight;
}
}
return pHead;
}
void PrintList(BSTreeNode *p)
{
while(p)
{
if(p->m_pLeft!=NULL)cout<<"\tpre:\t"<<p->m_pLeft->m_nValue;
else cout<<"\tpre\t:NULL";//前驱
cout<< "\tcur:\t"<<p->m_nValue;//当前
if(p->m_pRight!= NULL)cout<<"\tpost\t"<<p->m_pRight->m_nValue;//后继
else cout<<"\tpost:\tNULL";
cout<<endl;
p = p->m_pRight;
}
}
void main()
{
BSTreeNode *ptree1 = NULL,*ptree2 = NULL;
BSTreeNode *plastNode;
BSTreeNode *p1,*p2;
//p = CreateBSTree(p,7);
int a[15] = {7,3,11,1,5,9,13,0,2,4,6,8,10,12,14};
for (int i = 0; i < 15; i++)//创建二叉排序树
{
InsertBSTreeNode(&ptree1,a[i]);
InsertBSTreeNode(&ptree2,a[i]);
}
PrintBSTreeBylevel(ptree1);//按层打印树
p1 = BSTreeToDoubleLinkedList1(ptree1,plastNode);
cout<<endl;
p2 = BSTreeToDoubleLinkedList2(ptree2);
cout<<endl;
cout<<endl<<"-------------递归方法---------------"<<endl;
PrintList(p1);
cout<<endl<<"-------------非递归方法---------------"<<endl;
PrintList(p2);
system("pause");
}
输出结果:
参考资料:
[1]http://zephiruswt.blog.51cto.com/5193151/886171
[2]剑指offer
2:二叉树中和为某一值的路径
输入一棵二叉树和一个整,打印出二叉树中结点值的和为输入整数的所有路径,从树的根节点开始一直到页结点所经过的路径称为一条路径
#include<iostream> #include <vector> using namespace std; #define NIL (2^32 - 1) struct node{ int value; node *pleft; node *pright; }; typedef node * BiTree; void CreateBiTreeByArray(BiTree &t,int array[],int i,int len) { if(i > len||array[i] == NIL)return; t = new node; t->value = array[i]; t->pleft = NULL; t->pright = NULL; CreateBiTreeByArray(t->pleft,array,2*i,len); CreateBiTreeByArray(t->pright,array,2*i+1,len); } void display(BiTree *t) //显示树形结构 { if(*t!=NULL) { cout<<(*t)->value; if((*t)->pleft!=NULL) { cout<<'('; display(&(*t)->pleft); } if((*t)->pright!=NULL) { cout<<','; display(&(*t)->pright); cout<<')'; } } } void FindTreePathEqualK(BiTree &t,vector<int> &path,int cursum,int k)//利用vector存储路径 { cursum += t->value; path.push_back(t->value); bool isLeaf = (t->pleft == NULL && t->pright==NULL); if (isLeaf && cursum == k) { cout<<"\n---------\n"; vector<int>::iterator itor; for (itor = path.begin(); itor != path.end();itor++) { cout <<*itor<<" "; } } //不是叶结点,则遍历它的子节点。 if(t->pleft!=NULL)FindTreePathEqualK(t->pleft,path,cursum,k); if (t->pright!=NULL)FindTreePathEqualK(t->pright,path,cursum,k); cursum -= t->value;//返回父结点之前删除结点。并减去当前结点的值 path.pop_back(); } void EqualK(BiTree t,int k) { if(t==NULL)return; vector<int> path; int cursum = 0; FindTreePathEqualK(t,path,cursum,k); } void main() { /* 3 / \ 4 7 / \ / \ 2 0 3 2 / \ / 3 7 5 */ int array[11] = {NIL,3,4,7,2,0,3,2,3,7,5}; BiTree t; CreateBiTreeByArray(t,array,1,10); display(&t); EqualK(t,12); system("pause"); }
——————————————————————————————————————————————————————————————————————
3:二叉树中节点的最大距离
4:二叉树的镜像