1. 前序/中序/后序遍历(非递归)
前序
void PrevOrderNonR()
{
stack<Node*> s;
Node* cur = _root;
while (cur || !s.empty())
{
while (cur)
{
cout<<cur->_data<<" ";
s.push(cur);
cur = cur->_left;
}
// top从栈取出来表示这个节点的左子树访问过了
// 剩余右子树还没访问,循环子问题访问右树
Node* top = s.top();
s.pop();
// 子问题的方式访问右树
cur = top->_right;
}
cout<<endl;
}
中序
void InOrder()
{
_InOrder(_root);
cout<<endl;
}
void InOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cout<<top->_data<<" ";
// 子问题
cur = top->_right;
}
}
后序
void PostOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
Node* prev = NULL;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* front = s.top();
if (front->_right == NULL || front->_right == prev)
{
cout<<front->_data<<" ";
prev = front;
s.pop();
}
else
{
// 子问题
cur = front->_right;
}
}
cout<<endl;
}
判断一棵二叉树是否是平衡二叉树
//判断一棵树是不是平衡二叉树
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;
}
求二叉树的镜像
//求一颗二叉树的镜像 :两棵树左右对称
void Mirror(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);
}
求两个节点的最近公共祖先
bool GetNodePath(Node* root, Node* x, stack<Node*>& paths)
{
if (root == NULL)
return false;
paths.push(root);
if (root == x)
return true;
if(GetNodePath(root->_left, x, paths))
return true;
if (GetNodePath(root->_right, x, paths))
return true;
paths.pop();
return false;
}
Node* GetCommonAncestor(Node* root, Node* x1, Node* x2)
{
assert(x1 && x2);
stack<Node*> paths1;
stack<Node*> paths2;
if (GetNodePath(root, x1, paths1) == false)
return NULL;
if (GetNodePath(root, x2, paths2) == false)
return NULL;
while(paths1.size() != paths2.size())
{
if (paths1.size() > paths2.size())
paths1.pop();
else
paths2.pop();
}
while (1)
{
if (paths1.top() == paths2.top())
{
return paths1.top();
}
paths1.pop();
paths2.pop();
}
}
Node * FindLCA(Node * node, Node * target1, Node * target2)
{
if (node == nullptr)
return nullptr;
if (node == target1 || node == target2)
return node;
Node * left = FindLCA(node->left, target1, target2);
Node * right = FindLCA(node->right, target1, target2);
if (left && right) // 分别在左右子树
return node;
return left ? left : right; // 都在左子树或右子树
}
求二叉树中最远的两个节点的距离
int _FindMaxLen(Node* root, int& maxLen)
{
if (root == NULL)
return 0;
int l = _FindMaxLen(root->_left, maxLen);
int r = _FindMaxLen(root->_right, maxLen);
if (l+r > maxLen)
{
maxLen = l+r;
}
return l > r ? l+1 : r+1;
}
int FindMaxLen(Node* root)
{
int max = 0;
_FindMaxLen(root, max);
return max;
}
//void _FindMaxLen(Node* root, int& maxLen)
//{
// if (root == NULL)
// return;
//
// int l = Height(root->_left);
// int r = Height(root->_right);
// if (l + r > manLen)
// manLen = l + r;
// FindMaxLen(root->_left);
// FindMaxLen(root->_right);
//}
由前序遍历和中序遍历重建二叉树(如:前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)
Node* ReBulidTree(char*& prev, char* inStart, char* inEnd)
{
if (*prev=='\0')
return NULL;
Node* root = new Node(*prev);
if (inStart == inEnd)
return root;
char* pos = inStart;
while (pos <= inEnd)
{
if (*pos == *prev)
break;
++pos;
}
assert(pos <= inEnd);
// [inStart,pos-1]
// [pos+1,inEnd]
root->_left = ReBulidTree(++prev, inStart, pos-1);
root->_right = ReBulidTree(++prev, pos+1, inEnd);
return root;
}
判断一棵树是否是完全二叉树
bool IsCompleteTree(Node* root)
{
if (root == NULL)
return true;
bool tag = true;
queue<Node*> q;
q.push(root);
while (!q.empty())
{
Node* front = q.front();
q.pop();
if (front->_left)
{
if (tag == false)
return false;
q.push(front->_left);
}
else
{
tag = false;
}
if (front->_right)
{
if (tag == false)
return false;
q.push(front->_right);
}
else
{
tag = false;
}
}
return true;
}
将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
Node* ToSortList(Node* root)
{
Node* prev = NULL;
ToSortList(root, prev);
while (root && root->_left)
{
root = root->_left;
}
return root;
}
Node* _ToSortList(Node* cur, Node*& prev)
{
if (cur == NULL)
return;
_ToSortList(cur->_left, prev);
cur->_left = prev;
if (prev)
prev->_right = cur;
prev = cur;
_ToSortList(cur->_right, prev);
}
}