1.二叉树的前序,中序,后序遍历
//前序遍历非递归
void PrevOrder(BinaryTreeNode* root)
{
stack<BinaryTreeNode*> s;
BinaryTreeNode* cur=root;
while(cur||!s.empty())
{
while(cur)
{
cout<<cur->_data<<" ";
s.push(cur);
cur=cur->_left;
}
BinaryTreeNode* top=s.top();
s.pop();
cur=top->_right;
}
cout<<endl;
}
//中序遍历非递归
void InOrder(BinaryTreeNode* root)
{
stack<BinaryTreeNode*> s;
BinaryTreeNode* cur=root;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left;
}
BinaryTreeNode* top=s.top();
s.pop();
cout<<top->_data<<" ";
cur=top->_right;
}
cout<<endl;
}
//后序遍历非递归
void PostOrder(BinaryTreeNode* root)
{
stack<BinaryTreeNode*> s;
BinaryTreeNode* cur=root;
BinaryTreeNode* prev=NULL;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left;
}
BinaryTreeNode* top=s.top();
if(top->_right==NULL||top->_right==prev)
{
cout<<top->_data<<" ";
prev=top;
s.pop();
}
else
{
cur=top->_right;
}
}
cout<<endl;
}
2.实现一颗二叉树的层序遍历
void LevelOrder(BinaryTreeNode* root)
{
queue<BinaryTreeNode*> q;
q.push(root);
while(!q.empty())
{
BinaryTreeNode* front=q.front();
q.pop();
cout<<front->_data<<" ";
if(front->_left)
q.push(front->_left);
if(front->_right)
q.push(front->_right);
}
cout<<endl;
}
3.求二叉树的高度
int Depth(BinaryTreeNode* root)
{
if(root==NULL)
return 0;
return Depth(root->_left)>Depth(root->_right)?Depth(root->_left)+1:Depth(root->_right)+1;
}
4.求二叉树叶子节点的个数int LeafSize(BinaryTreeNode* root)
{
if(root==NULL)
return 0;
if(root->_left==NULL&&root->_right==NULL)
return 1;
return LeafSize(root->_left)+LeafSize(root->_right);
}
5.求二叉树第k层结点的个数
int KLevel(BinaryTreeNode* root,size_t k)
{
if(root==NULL||k<0)
return 0;
if(k==1)
return 1;
return KLevel(root->_left,k-1)+KLevel(root->_right,k-1);//左子树中k-1层的结点个数与右子树中k-1层的节点个数之和
}
6.判断一个结点是否在一颗二叉树中
bool IsBinaryTree(BinaryTreeNode* root,int x)
{
if(root==NULL)
return false;
if(root->_data==x)
return true;
return IsBinaryTree(root->_left,x)||IsBinaryTree(root->_right,x);
}
7.判断一颗二叉树是否是平衡二叉树
int Depth(BinaryTreeNode* root)
{
if(root==NULL)
return 0;
return Depth(root->_left)>Depth(root->_right)?Depth(root->_left)+1:Depth(root->_right)+1;
}
//重复遍历
bool IsBalance(BinaryTreeNode* root)
{
if(root==NULL)
return true;
int left=Depth(root->_left);
int right=Depth(root->_right);
int dif=left-right;
if(dif>1||dif<-1)
return false;
return IsBalance(root->_left)&&IsBalance(root->_right);
}
8.子树
bool SubTree(BinaryTreeNode* root1,BinaryTreeNode* root2)
{
if(root2==NULL)
return true;
if(root1==NULL)
return false;
if(root1->_data!=root2->_data)
return false;
return SubTree(root1->_left,root2->_left)&&SubTree(root1->_right,root2->_right);
}
bool NodeSubTree(BinaryTreeNode* root1,BinaryTreeNode* root2)
{
bool ret=false;
if(root1!=NULL&&root2!=NULL)
{
if(root1->_data==root2->_data)
ret=SubTree(root1,root2);
if(!ret)
ret=NodeSubTree(root1->_left,root2);
if(!ret)
ret=NodeSubTree(root1->_right,root2);
}
return ret;
}
9.求二叉树的镜像
void Mirror(BinaryTreeNode* root)
{
if(root==NULL)
return;
if(root->_left==NULL&&root->_right==NULL)
return;
BinaryTreeNode* temp=root->_left;
root->_left=root->_right;
root->_right=temp;
if(root->_left)
Mirror(root->_left);
if(root->_right)
Mirror(root->_right);
}
10.判断一棵树是不是完全二叉树 树的深度为h,除h层外,其余层节点个数达到最多,第h层所有结点个数都连续集中在最左边
完全二叉树的空洞在层序遍历是在末尾,如果不是完全二叉树遍历到空洞时后边还会有值。所以只有看空后面还有没有值来判断是否是完全二叉树。
bool Iscomplete(BinaryTreeNode* root)
{
queue<BinaryTreeNode*> q;
q.push(root);
while(q.front()!=NULL)
{
BinaryTreeNode* temp=q.front();
q.pop();
q.push(temp->_left);
q.push(temp->_right);
}
while(!q.empty())
{
BinaryTreeNode* ptr=q.front();
q.pop();
if(ptr!=NULL)
{
return false;
}
}
return true;
}
11.求二叉树两个结点的最近公共祖先
1.二叉树中每个节点都有parent(三叉链)
从给出的结点根据父亲指针向上走,每个路径的结尾都是根节点,可以转换成两个链表求第一个公共节点,则第一个公共结点就是最近祖先。
2.二叉树是搜索二叉树
二叉搜索数是排序的,从根节点开始和输入的两个数进行比较,如果当前结点大于输入的两个数,在当前节点的左子树中找,如果比两个值都小,在右子树中找,第一个在这两个数中间的数就是最近公共祖先。
3.就是一颗普通的树
《1》遍历这棵树,每次遍历到一个结点,判断输入的两个数字是否在他的子树中,如果在,分别遍历他的子节点,看看在不在他们的子树中,一直向下找,如果一个子树中有两个结点,则其子树中没有,则有的就是他的最近公共祖先。(重复遍历)、
《2》用两个链表分别存入到两个结点的路径,把问题转化成求两个链表的最后公共结点。
.
12.二叉搜索树的后序遍历 判断该数组是不是二叉搜索数的后序遍历 数组的最后一个数是根节点
bool IsPost(int *a,int length)
{
if(a==NULL||length<=0)
return false;
int root=a[length-1];//根节点
int i=0;
for(i=0;i<length-1;i++)
{
if(root<a[i])
{
break;
}
} //左子树
int j=i;
for(j=i;j<length-1;j++)
{
if(root>a[j])
{
return false;
}
} //右子树
//判断左右子树是不是二叉搜索数
bool left=true;
if(i>0)
left=IsPost(a,i);
bool right=true;
if(i<length-1)
right=IsPost(a+i,length-i-1);
return (left&&right);
}
14.重建二叉树
BinaryTreeNode* Construct1(int *startpre,int *endpre,int *startin,int *endin)
{
//前序遍历的第一个结点是根节点
int rootvalue=startpre[0];
BinaryTreeNode* root=new BinaryTreeNode(rootvalue);
root->_left=root->_right=NULL;
//在中序遍历中找到根节点
int *rootIn=startin;
while(rootIn<=endin&&*rootIn!=rootvalue)
rootIn++;
if(rootIn==endin&&*rootIn!=rootvalue)
return NULL;
//构建左子树
int leftlength=rootIn-startin;
int* leftpreend=startpre+leftlength;
if(leftlength>0)
{
root->_left=Construct1(startpre+1,leftpreend,startin,rootIn-1);
}
//构建右子树
if(leftlength<endpre-startpre)
{
root->_right=Construct1(leftpreend+1,endpre,rootIn+1,endin);
}
return root;
}
BinaryTreeNode* Construct(int* preorder,int* inorder,int length)
{
if(preorder==NULL||inorder==NULL||length<=0)
return NULL;
return Construct1(preorder,preorder+length-1,inorder,inorder+length-1);
}
15.二叉搜索树转换成双向链表 中序遍历二叉搜索树,是排序的。指向左子树的结点的指针调整为链表中指向前一个节点的指针,指向右子树的结点的指针调整为链表中指向后一个结点的指针,遍历到根节点,将二叉树分为三部分,根节点连接到左子树最大的值,连接到右子树最小的值。 把左右子树转换成双向链表在和根节点连接起来。
中序遍历这棵树,放入队列中,然后将队列中的数字连接起来
void Inorder(BinaryTreeNode* root,queue<BinaryTreeNode*>& q)
{
if(root==NULL)
return;
Inorder(root->_left,q);
q.push(root);
Inorder(root->_right,q);
}
BinaryTreeNode* ConvertNode(BinaryTreeNode* root)
{
if(root==NULL)
return NULL;
queue<BinaryTreeNode*> q;
Inorder(root,q);
BinaryTreeNode* ListHead=q.front();
q.pop();
ListHead->_left=NULL;
BinaryTreeNode* prev=ListHead;
while(!q.empty())
{
BinaryTreeNode* cur=q.front();
q.pop();
prev->_right=cur;
cur->_left=prev;
cur->_right=NULL;
prev=cur;
}
return ListHead;
}