二叉树算法习题:
1.二叉树自下而上,自左到右的层次遍历算法
void ReverseVisitTreeLevel(BiTree tr)
2.非递归算法求解二叉树的高度
int GetHeight(BiTree tr)
3.递归算法求解二叉树的高度
int GetHeightCircle(BiTree tr)
4.二叉树各个值不同,先序和中序遍历序列分别存于数组A[1…n],B[1…n]中, 算法建立该二叉树链表
BiTree BuildTreeBeforeAndIn(int A[], int B[], int h1, int t1, int h2, int t2)
5.二叉树用二叉链表形式存储,写一个判定二叉树是否是完全二叉树的算法, 思路:层次遍历,遇到空节点,检查队列是否有节点
bool isCompleteTree(BiTree tr)
6.二叉树采用二叉链表存储,尝试设计一个算法, 计算一颗给定二叉树的所有双分支节点数
int DoubleNodeNumber(BiTree tr)
7.把二叉树中,所有节点的左右子树交换
void ExchangeLeftAndRight(BiTree tr)
函数定义:
BiTree.h
#include <stack>
#include <iostream>
#include <malloc.h>
#include <queue>
typedef struct BiNode
{
int data;
struct BiNode *lchild, *rchild;
} BiNode, *BiTree;
/**
* 前序遍历,递归
*/
void VisitTreeHead(BiTree tr)
{
if (tr)
{
std::cout << char(tr->data) << " ";
VisitTreeHead(tr->lchild);
VisitTreeHead(tr->rchild);
}
}
/**
* 前序遍历,非递归
*/
void TreeNodeHead(BiTree tr)
{
std::stack<BiNode *> s;
BiNode *p = tr;
while (!s.empty() || p)
{
if (p)
{
std::cout << char(p->data) << " ";
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}
/**
* 后序递归遍历二叉树
*/
void VisitTreeAfter(BiTree tr)
{
if (tr)
{
VisitTreeAfter(tr->lchild);
VisitTreeAfter(tr->rchild);
std::cout << tr->data << " ";
}
}
/**
* 后序非递归遍历二叉树
*/
void TreeNodeAfter(BiTree tr)
{
std::stack<BiNode *> s;
BiNode *p = tr, *r = NULL;
while (!s.empty() || p)
{
if (p)
{
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
if (p->rchild && p->rchild != r)
{ //p有右孩子,且没有被访问过
p = p->rchild;
s.push(p);
p = p->lchild;
}
else
{
s.pop();
std::cout << char(p->data) << " ";
r = p;
p = NULL;
}
}
}
}
/**
* 创建一颗树
*/
BiTree CreateBTree(BiTree bt, bool isRoot)
{
char ch;
if (isRoot)
std::cout << "Root:";
std::cin >> ch;
if (ch != '#')
{
isRoot = false;
bt = (BiNode *)malloc(sizeof(BiNode));
bt->data = ch;
bt->lchild = NULL;
bt->rchild = NULL;
std::cout << "请输入" << ch << "的左孩子" << std::endl;
bt->lchild = CreateBTree(bt->lchild, isRoot);
std::cout << "请输入" << ch << "的右孩子" << std::endl;
bt->rchild = CreateBTree(bt->rchild, isRoot);
}
return bt;
}
/**
* 中序遍历二叉树:非递归
*/
void TreeNodeIn(BiTree tr)
{
std::stack<BiNode *> s;
BiNode *p = tr;
while (!s.empty() || p)
{
if (p)
{
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
s.pop();
std::cout << char(p->data) << " ";
p = p->rchild;
}
}
}
/**
* 中序遍历二叉树:递归
*/
void VisitTreeIn(BiTree tr)
{
if (tr != NULL)
{
VisitTreeIn(tr->lchild);
std::cout << char(tr->data) << " ";
VisitTreeIn(tr->rchild);
}
}
/**
* 层次遍历二叉树,
*/
void VisitTreeLevel(BiTree tr)
{
std::queue<BiNode *> q;
BiNode *p = tr;
q.push(p);
while (!q.empty())
{
p = q.front();
q.pop();
if (p)
{
std::cout << char(p->data) << " ";
q.push(p->lchild);
q.push(p->rchild);
}
}
}
/***
* 二叉树自下而上,自左到右的层次遍历算法
*/
void ReverseVisitTreeLevel(BiTree tr)
{
std::stack<BiNode *> s;
std::queue<BiNode *> q;
BiNode *p = tr;
q.push(p);
while (!q.empty())
{
p = q.front();
q.pop();
if (p)
{
s.push(p);
q.push(p->lchild);
q.push(p->rchild);
}
}
while (!s.empty())
{
p = s.top();
s.pop();
std::cout << char(p->data) << " ";
}
}
/**
* 非递归算法求解二叉树的高度
*/
int GetHeight(BiTree tr)
{
if (!tr)
return 0;
std::queue<BiNode *> q;
BiNode *p = tr, *r = tr;
int height = 0;
q.push(p);
while (!q.empty())
{
p = q.front();
q.pop();
if (p->lchild)
q.push(p->lchild);
if (p->rchild)
q.push(p->rchild);
if (p == r)
{
height += 1;
r = q.back();
}
}
return height;
}
/**
* 递归算法求解二叉树的高度
*/
int GetHeightCircle(BiTree tr)
{
if (tr)
{
int hleft = GetHeight(tr->lchild) + 1;
int hright = GetHeight(tr->rchild) + 1;
return hleft > hright ? hleft : hright;
}
else
{
return 0;
}
}
/***
* 二叉树各个值不同,先序和中序遍历序列分别存于数组A[1..n],B[1....n]中,
* 算法建立该二叉树链表
*/
BiTree BuildTreeBeforeAndIn(int A[], int B[], int h1, int t1, int h2, int t2)
{
BiNode *root = (BiNode *)malloc(sizeof(BiNode));
root->data = A[h1]; //找到根节点
//std::cout << root->data << " ";
int i;
for (i = h2; B[i] != A[h1]; i++)
;
int llen = i - h2; //以根为中间节点,划分左右
int rlen = t2 - i;
//std::cout << llen << " " << rlen << " " << std::endl;
if (llen != 0)
root->lchild = BuildTreeBeforeAndIn(A, B, h1 + 1, h1 + llen, h2, h2 + llen - 1);
else
root->lchild = NULL;
if (rlen != 0)
root->rchild = BuildTreeBeforeAndIn(A, B, h1 + llen + 1, t1, h2 + llen + 1, t2);
else
root->rchild = NULL;
return root;
}
/***
* 二叉树用二叉链表形式存储,
* 写一个判定二叉树是否是完全二叉树的算法
*
* 思路:层次遍历,遇到空节点,检查队列是否有节点
*/
bool isCompleteTree(BiTree tr)
{
std::queue<BiNode *> q;
BiNode *p = tr;
q.push(p);
int id = tr->data;
while (!q.empty())
{
p = q.front();
q.pop();
if (p)
{
q.push(p->lchild);
q.push(p->rchild);
}
else
{
while (!q.empty())
{
p = q.front();
q.pop();
if (p)
return false;
}
}
}
return true;
}
/**
* 二叉树采用二叉链表存储,尝试设计一个算法,
* 计算一颗给定二叉树的所有双分支节点数
*/
int DoubleNodeNumber(BiTree tr)
{
int num = 0;
std::queue<BiNode *> q;
BiNode *p = tr;
q.push(p);
while (!q.empty())
{
p = q.front();
q.pop();
if (p)
{
q.push(p->rchild);
q.push(p->lchild);
}
if (p && p->lchild && p->rchild)
{
num += 1;
}
}
return num;
}
/***
* 把二叉树中,所有节点的左右子树交换
*/
void ExchangeLeftAndRight(BiTree tr)
{
if (tr)
{
ExchangeLeftAndRight(tr->lchild);
ExchangeLeftAndRight(tr->rchild);
BiNode *tmp = tr->lchild;
tr->lchild = tr->rchild;
tr->rchild = tmp;
}
}
调用:
BiTree_use.cpp
#include "BiTree.h"
int main()
{
int A[9] = {'1', '2', '3', '4', '5', '6', '7', '8'};
int B[9] = {
'4',
'3',
'2',
'5',
'1',
'7',
'6',
'8',
};
BiTree tr2 = BuildTreeBeforeAndIn(A, B, 0, 7, 0, 7);
VisitTreeLevel(tr2);
std::cout << std::endl;
if (isCompleteTree(tr2))
std::cout << "二叉树是完全二叉树" << std::endl;
else
std::cout << "二叉树不是完全二叉树" << std::endl;
std::cout << "二叉树双分支节点个数:" << DoubleNodeNumber(tr2) << std::endl;
ExchangeLeftAndRight(tr2);
VisitTreeLevel(tr2);
}