1、前序遍历(递归与非递归)
//前序遍历:先访问根节点,再左子树,再右子树
void PrevOrder(Node* root)
{
if (root == NULL)
return ;
cout << root->value << " ";
PrevOrder(root->Lchild);
PrevOrder(root->Rchild);
}
//前序非递归,利用栈,先访问根节点并依次把左路节点依次压入栈,拿出来在子问题解决
void PrevOrder_No(Node* root)
{
if(root == NULL)
return;
stack<Node*> s;
Node* cur = root;
while (cur || !s.empty())
{
while (cur)
{
cout << cur->value << " ";
s.push(cur);
cur = cur->Lchild;
}
cur = s.top()->Rchild;
s.pop();
}
cout << endl;
}
2、中序遍历(递归与非递归)
//中序遍历 递归,左根右
void MidTreeOrder(Node* root)
{
if (root == NULL)
return;
MidTreeOrder(root->Lchild);
cout << root->value << " ";
MidTreeOrder(root->Rchild);
}
//中序,非递归(同前序一样思想,不过是从栈中拿出来再访问节点)
void MidTreeOrder_No(Node* root)
{
if (root == NULL)
return;
Node* cur = root;
stack<Node*> s1;
while (cur || !s1.empty())
{
while (cur)
{
s1.push(cur);
cur = cur->Lchild;
}
cur = s1.top();
cout << cur->value << " ";
s1.pop();
cur = cur->Rchild;
}
cout << endl;
}
3、后序遍历
//后续遍历:先访问左节点,再访问右节点,再访问根节点
void PostTreeOrder(Node* root)
{
if (root == NULL)
return;
PostTreeOrder(root->Lchild);
PostTreeOrder(root->Rchild);
cout << root->value << " ";
}
//后续,非递归
void PostTreeOrder_No(Node* root)
{
if (root == NULL)
return;
Node* cur = root;
int flag = 0;
Node* ptag = NULL;
stack<Node*> s2;
s2.push(cur);
cur = cur->Lchild;
while ( !s2.empty())
{
while (cur)
{
s2.push(cur);
cur = cur->Lchild;
}
ptag = NULL;//ptag指向已访问过的cur(null)
flag = 1;//设置当前cur已访问
//现在一种右路没有节点(需要循环输出),一种右路有节点(子问题 ——需要循环压入)
while (!s2.empty() && flag ==1 )
{
cur = s2.top();
if (cur->Rchild == ptag)//右孩子不存在,或者右孩子已经访问过
{
cout << cur->value << " ";
s2.pop();
ptag = cur; //重置
}
else
{ //访问右孩子,重置flag
cur = cur->Rchild;
flag = 0;
}
}
}
}
4、求树的深度
int BinaryTreeDepth(Node* root)
{
if (root == NULL)
return 0;
int lenleft = BinaryTreeDepth(root->Lchild);
int lenright = BinaryTreeDepth(root->Rchild);
return lenleft > lenright ? lenleft + 1 : lenright + 1;
}
5、判断一颗树是不是平衡二叉树
//判断一棵树是不是平衡二叉树
bool IsBalancedTree_old(Node* root)
{
if (root == NULL)
return true;
int lenleft = BinaryTreeDepth(root->Lchild);//每往下一层,计算一次深度,时间复杂度N^2
int lenright = BinaryTreeDepth(root->Rchild);
int temp = lenleft - lenright;
if (temp >1 || temp < -1)
return false;
return IsBalancedTree_old(root->Lchild) && IsBalancedTree_old(root->Rchild);//满足条件,计算它的下一层的左右子树
}
//判断是否为平衡二叉树(优化)
bool _IsBlancedtree_new(Node* root,int* pDepth)
{
if (root == NULL)
{
*pDepth = 0;
return true;
}
int left, right;
if (_IsBlancedtree_new(root->Lchild, &left) && _IsBlancedtree_new(root->Rchild, &right))//后序遍历思想
{
int temp = left - right;
if (temp <= 1 && temp >= -1)//拿到深度值
{
*pDepth = left > right ? left + 1 : right + 1;
return true;
}
}
return false;
}
bool IsBlancedTree_new(Node* root)
{
int pDepth;
bool tag = _IsBlancedtree_new(root, &pDepth);
return tag;
}
6、得到树的节点的个数
//得到树的节点个数
void _GetTreeSize(Node* root, size_t& size)
{
if (root == NULL)
return;
++size;
_GetTreeSize(root->Lchild,size);
_GetTreeSize(root->Rchild,size);
}
size_t GetTreeSize(Node* root)
{
size_t size;
_GetTreeSize(root, size);
return size;
}
7、得到树的叶子节点的个数
//叶子节点的个数:利用前序遍历思想
int MunLeavesNodeOfTree(Node* root)
{
if (root == NULL)
return 0;
Node* cur = root;
stack<Node*> s4;
int count = 0;
while (cur || !s4.empty())
{
while (cur)
{
s4.push(cur);
cur = cur->Lchild;
}
cur = s4.top();
s4.pop();
if (cur->Rchild == NULL && cur->Lchild == NULL)
count++;
cur = cur->Rchild;
}
return count;
}
8、计算二叉树第K层节点个数
//第K层节点个数:
int GetNumKOfTree(Node* root, int k)
{
if (root == NULL || k <1)
return 0;
if (k == 1)
return 1;
//求第k层节点个数,返回左子树k-1层节点个数与右子树k-1层节点个数之和
int numLeft = GetNumKOfTree(root->Lchild, k - 1); // 左子树中k-1层的节点个数
int numRight = GetNumKOfTree(root->Rchild, k - 1); // 右子树中k-1层的节点个数
return (numLeft + numRight);
}
9、判断一个值是否在二叉树当中
//判断一个值是否存在二叉树中
bool JudgeKOfTree(Node* root, size_t K)
{
if (root == NULL)
return false;
if (root->value == K)
return true;
return JudgeKOfTree(root->Lchild,K)||JudgeKOfTree(root->Rchild,K);
//左右子树只要有一颗存在就返回ture
}
10、求一颗二叉树镜像
//求一颗二叉树的镜像 :两棵树左右对称
void MirrorRecursively(Node* root)
{
if (root == NULL)
return ;
if (root->Lchild == NULL && root->Rchild == NULL)
return ;
Node* temp = root->Lchild;//交换左右子树
root->Lchild = root->Rchild;
root->Rchild = temp;
if (root->Lchild)//递归下去
MirrorRecursively(root->Lchild);
if (root->Rchild)
MirrorRecursively(root->Rchild);
}
11、二叉树的销毁
void DestoryTree(Node*& root)//防止野指针
{
if (root == NULL)
return;
DestoryTree(root->Lchild);
DestoryTree(root->Rchild);
delete root;
root = NULL;
}
12、判断一棵树是否是完全二叉树,一个子树没有孩子,后面的子树都不能有孩子,利用队列;
bool IsCompleteTree(Node* root)
{
if (root == NULL)
return true;
queue<Node*> s;
bool mustnochild = false;
s.push(root);
while (!s.empty())
{
Node* cur = s.front();
s.pop();
if (mustnochild == true)//左右子树都没有孩子了
{
if (cur->Lchild != NULL || cur->Rchild != NULL)
return false;
}
if (cur->Lchild == NULL && cur->Rchild == NULL)
mustnochild = true;
if (cur->Lchild != NULL && cur->Rchild == NULL)//有左孩子,没有右孩子
{
s.push(cur->Lchild);
mustnochild = true;
}
if (cur->Lchild == NULL && cur->Rchild != NULL)//没左孩子,有右孩子
return false;
if (cur->Lchild != NULL && cur->Rchild != NULL)//左右都有孩子,则插入
{
s.push(cur->Lchild);
s.push(cur->Rchild);
}
}
return true;
}
13、给定一颗二叉树,和其中的一个节点,怎么找到中序遍历的下一个节点
//左,根,右,
Node* GetNextNode(Node* pnode)//假设一定在,
{
if (pnode == NULL)
return NULL;
Node* cur = pnode;
if (cur->Rchild != NULL)//cur作为根
{
cur = cur->Rchild;
while (cur->Lchild)
cur = cur->Lchild;
return cur;
}
if (cur->Parent != NULL && cur->Parent->Lchild == cur)//cur作为左子树
return cur->Parent;
if (cur->Parent != NULL && cur->Parent->Rchild == cur)//cur作为右子树某一点
{
while (cur->Parent && cur->Parent->Rchild == cur)
{
cur = cur->Parent;
}
cur = cur->Parent;
return cur;
}
return NULL;
}
14、判断一颗二叉树是不是对称的
bool IsSymmet(Node* root1, Node* root2)
{
if (root1 == NULL && root2 == NULL)
return true;
if (root1 == NULL || root2 == NULL)
return false;
if (root1->value != root2->value)
return false;
return IsSymmet(root1->Lchild, root2->Rchild) && IsSymmet(root1->Rchild, root2->Lchild);
}
bool IsSymmet(Node* root)
{
return IsSymmet(root, root);
}
15、将二叉搜索树转换成一个排序的双向链表。提示:要求不能创建任何新的结点,只能调整树中结点指针的指向
void _ToList(Node* cur, Node*& prev)
{
if (cur == NULL)
return;
_ToList(cur->Lchild, prev);
//
cur->Lchild = prev;
if (prev)
prev->Rchild = cur;
prev = cur;
_ToList(cur->Rchild, prev);
}
Node* ToList(Node* root)
{
Node* prev = NULL;
_ToList(root, prev);
Node* head = root;
while (head && head->Lchild)
{
head = head->Lchild;
}
return head;
}