二叉树前序遍历非递归算法:
void preOrder(TreeNode* root) {
if(root == NULL) {
return;
}
stack
st;
st.push(root);
while(!st.empty()) {
TreeNode* p = st.top();
st.pop();
cout<
val<<" ";="" if(p-="">right != NULL) { st.push(p->right); } if(p->left != NULL) { st.push(p->left); } } }
二叉树中序遍历非递归算法:
void inOrder(TreeNode* root) {
if(root == NULL) {
return;
}
stack
st;
TreeNode* p = root;
do {
while(p != NULL) {
st.push(p);
p = p->left;
}
if(!st.empty()) {
p = st.top();
st.pop();
cout<
val<<" ";="" p="p-">right; } } while(p != NULL || !st.empty()); }
二叉树后序遍历非递归算法:
void postOrder(TreeNode* root) {
if(root == NULL) {
return;
}
stack
st; TreeNode* p = NULL; TreeNode* pre = NULL; st.push(root); while(!st.empty()) { p = st.top(); if((p->left == NULL && p->right == NULL) || (pre != NULL && (pre == p->left || pre == p->right))) { st.pop(); cout<
val<<" ";="" pre="p;" }="" else="" {="" if(p-="">right != NULL) { st.push(p->right); } if(p->left != NULL) { st.push(p->left); } } } }
二叉搜索树删除节点算法:
void remove(TreeNode * & root, int x) {
if(root == NULL) {
return;
}
if(x < root->val) {
remove(root->left, x);
} else if(x > root->val) {
remove(root->right, x);
} else {
if(root->left != NULL && root->right != NULL) {
TreeNode* p = root->right;
while(p->left != NULL) {
p = p->left;
}
root->val = p->val;
remove(p, x);
} else {
TreeNode* temp = root;
if(root->left != NULL) {
root = root->left;
} else {
root = root->right;
}
delete temp;
}
}
}
说明:二叉搜索树删除一个节点,如果该节点存在,删除该节点后需要进行相应的调整保证删除后该树还是二叉搜索树,分为四种情况:
1.被删除有左子树也有右子树
2.被删除节点只有左子树
3.被删除节点只有右子树
4.被删除节点既没有左子树也没有右子树。
情况1的调整方法就是寻找右子树中序遍历序列的第一个节点A,用该节点代替被删除节点,然后现在问题就转化为删除这个节点A,递归
处理即可;情况2,3,4可以代码中统一处理,就是把左子树(或者右子树)代替被删除节点。
二叉树层次遍历算法:
void levelOrder(const TreeNode* root) {
if(root == NULL) {
return;
}
queue
q;
q.push(root);
while(!q.empty()) {
const TreeNode* p = q.front();
q.pop();
cout<
val<<" ";="" if(p-="">left != NULL) { q.push(p->left); } if(p->right != NULL) { q.push(p->right); } } }
求二叉树叶子节点数算法:
int getLeafNum(const TreeNode* root) {
if(root == NULL) {
return 0;
}
if(root->left == NULL && root->right == NULL) {
return 1;
}
return getLeafNum(root->left) + getLeafNum(root->right);
}
求二叉树深度算法:
int depth(const TreeNode* root) {
if(root == NULL) {
return 0;
}
if(root->left == NULL && root->right == NULL) {
return 1;
}
int leftDepth = depth(root->left);
int rightDepth = depth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
生成二叉树镜像算法:
void mirror(TreeNode* root) {
if(root == NULL) {
return;
}
TreeNode* p = root->right;
root->right = root->left;
root->left = p;
mirror(root->left);
mirror(root->right);
}
打印二叉树中从根节点出发且和为某一定值的所有路径算法:
void printPaths(const TreeNode* root, int x, vector
&v) {
if(root == NULL) {
return;
}
if(root->val == x) {
int size = v.size();
for(int i = 0; i < size; i++) {
cout<
val<
val < x) { v.push_back(root->val); printPaths(root->left, x - root->val, v); printPaths(root->right, x - root->val, v); v.pop(); } }
由前序遍历序列和中序遍历序列重建二叉树算法:
TreeNode* build(vector
pre, int preStart, int preEnd,
vector
in, int inStart, int inEnd) {
if(preStart > preEnd || inStart > inEnd) {
return NULL;
}
TreeNode* p = new TreeNode(pre[preStart]);
int i = inStart;
for(; i <= inend;="" i++)="" {="" if(in[i]="=" pre[prestart])="" break;="" }="" p-="">left = build(pre, preStart + 1, preStart + i - inStart, in, inStart, i - 1);
p->right = build(pre, preStart + i - inStart + 1, preEnd, in, i + 1, inEnd);
return p;
}
二叉搜索树转有序双向链表算法:
TreeNode* Convert(TreeNode* pRootOfTree){
if(pRootOfTree == NULL) {
return NULL;
}
TreeNode* p = Convert(pRootOfTree->left);
TreeNode* q = Convert(pRootOfTree->right);
TreeNode* temp = p;
if(p != NULL) {
while(p->right != NULL) {
p = p->right;
}
p->right = pRootOfTree;
} else {
temp = pRootOfTree;
}
if(q != NULL) {
q->left = pRootOfTree;
}
pRootOfTree->left = p;
pRootOfTree->right = q;
return temp;
}
判断一颗树是否为平衡二叉树算法:
bool isAVL(TreeNode* pRoot, int &depth) {
if(pRoot == NULL) {
depth = 0;
return true;
}
int leftDepth = 0;
int rightDepth = 0;
if(isAVL(pRoot->left, leftDepth) && isAVL(pRoot->right, rightDepth)) {
int temp = leftDepth - rightDepth;
if(temp >= -1 && temp <= 1)="" {="" depth="leftDepth"> rightDepth ? leftDepth + 1 : rightDepth + 1;
return true;
}
}
return false;
}
说明:使用depth保存左右子树的深度,避免重复计算。
寻找二叉树中序遍历的下一个节点算法:
TreeLinkNode* GetNext(TreeLinkNode* pNode){
if(pNode == NULL) {
return NULL;
}
if(pNode->right != NULL) {
pNode = pNode->right;
while(pNode->left != NULL) {
pNode = pNode->left;
}
return pNode;
}
if(pNode->next == NULL) {
return NULL;
}
if(pNode == pNode->next->left) {
return pNode->next;
}
while(pNode->next != NULL && pNode != pNode->next->left) {
pNode = pNode->next;
}
return pNode->next;
}
分步判断:
1.给定节点为NULL,直接返回NULL
2.给定节点有右子树,则返回右子树中序遍历的第一个节点,也就是左下角那个节点
3.给定节点没有右子树,如果是根节点则说明没有下一个节点了返回NULL
4.不是根节点,如果该节点是其父节点的左孩子,则下一个节点就是其父节点
5.不是根节点,如果该节点是其父节点的右孩子,则向上寻找直到找到一个节点是其父节点的左孩子,返回其父节点。
判断一棵二叉树是否是对称算法:
bool isSymmetrical(TreeNode* pRoot)
{
if(pRoot == NULL) {
return true;
}
return isSymmetrical0(pRoot->left, pRoot->right);
}
bool isSymmetrical0(TreeNode* left, TreeNode* right) {
if(left == NULL && right == NULL) {
return true;
} else if(left != NULL && right != NULL) {
return left->val == right->val
&& isSymmetrical0(left->left, right->right)
&& isSymmetrical0(left->right, right->left);
} else {
return false;
}
}
之字形层次打印二叉树算法:
vector
>
Print(TreeNode* pRoot) {
vector
>
v;
if(pRoot == NULL) {
return v;
}
stack
st1, st2;
st2.push(pRoot);
while(!st1.empty() || !st2.empty()) {
vector
vec1;
while(!st2.empty()) {
TreeNode* temp = st2.top();
st2.pop();
vec1.push_back(temp->val);
if(temp->left != NULL) {
st1.push(temp->left);
}
if(temp->right != NULL) {
st1.push(temp->right);
}
}
if(vec1.size() > 0) {
v.push_back(vec1);
}
vector
vec2;
while(!st1.empty()) {
TreeNode* temp = st1.top();
st1.pop();
vec2.push_back(temp->val);
if(temp->right != NULL) {
st2.push(temp->right);
}
if(temp->left != NULL) {
st2.push(temp->left);
}
}
if(vec2.size() > 0) {
v.push_back(vec2);
}
}
return v;
}
寻找二叉搜索树第k个节点算法:
TreeNode* KthNode(TreeNode* pRoot, unsigned int k){
if(pRoot == NULL || k <= 0)="" {="" return="" null;="" }="" unsigned="" int="" count="0;" stack
st; TreeNode* p = pRoot; while(p != NULL || !st.empty()) { while(p != NULL) { st.push(p); p = p->left; } if(!st.empty()) { p = st.top(); count++; if(count == k) { return p; } st.pop(); p = p->right; } } return NULL; }