树相关题目

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:二叉树的镜像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值