数据结构-树相关算法
来源:互联网 发布:淘宝卖家能给差评吗 编辑:程序博客网 时间:2024/05/01 01:10
二叉树前序遍历非递归算法:
void preOrder(TreeNode* root) { if(root == NULL) { return; } stack<TreeNode*> st; st.push(root); while(!st.empty()) { TreeNode* p = st.top(); st.pop(); cout<<p->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<TreeNode*> st; TreeNode* p = root; do { //左节点一直进栈 while(p != NULL) { st.push(p); p = p->left; } //栈顶元素如果存在就是下一个访问节点 if(!st.empty()) { p = st.top(); st.pop(); cout<<p->val<<" "; p = p->right; } } while(p != NULL || !st.empty());}
二叉树后序遍历非递归算法:
void postOrder(TreeNode* root) { if(root == NULL) { return; } stack<TreeNode*> st; TreeNode* p = NULL; TreeNode* pre = NULL;//保存上一次访问的节点 st.push(root); while(!st.empty()) { p = st.top(); //访问某一节点有两种情况:1.该节点是叶子节点 2.该节点的左右子树都已经访问过了 if((p->left == NULL && p->right == NULL) || (pre != NULL && (pre == p->left || pre == p->right))) { st.pop(); cout<<p->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; //转化为删除p节点 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<const TreeNode*> q; q.push(root); while(!q.empty()) { const TreeNode* p = q.front(); q.pop(); cout<<p->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<int> &v) { if(root == NULL) { return; } if(root->val == x) { int size = v.size(); for(int i = 0; i < size; i++) { cout<<v[i]<<" "; } cout<<root->val<<endl; } else if(root->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<int> pre, int preStart, int preEnd, vector<int> 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,直接返回NULL2.给定节点有右子树,则返回右子树中序遍历的第一个节点,也就是左下角那个节点3.给定节点没有右子树,如果是根节点则说明没有下一个节点了返回NULL4.不是根节点,如果该节点是其父节点的左孩子,则下一个节点就是其父节点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<vector<int> > Print(TreeNode* pRoot) {vector<vector<int> > v;if(pRoot == NULL) { return v;}stack<TreeNode*> st1, st2;st2.push(pRoot);while(!st1.empty() || !st2.empty()) { vector<int> 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<int> 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<TreeNode*> 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;}
0 0
- 数据结构-树相关算法
- 十四、数据结构相关算法
- 数据结构算法相关
- 涂鸦数据结构3 算法相关
- 初学数据结构---二叉树,线索二叉树相关算法
- 数据结构与算法简记:二叉查找树相关操作
- 数据结构-树相关
- 数据结构与算法 相关经典书籍推荐
- 数据结构-单向链表相关操作算法
- 稀疏矩阵的数据结构及相关算法
- 数据结构:图相关概念及遍历算法
- 数据结构之链表及相关算法
- 数据结构复习:几种排序算法的C++实现和二叉树的相关算法实现
- 算法基础----关于数据结构中树的相关算法总结探究
- 浅谈算法和数据结构----无向图相关算法基础
- 数据结构与算法学习之二叉树及二叉树的相关操作
- 数据结构与算法====》二叉树相关操作
- 数据结构树的相关概念
- [Leetcode] Intersection of Two Arrays II
- android 走马灯效果
- nowcoder--取近似值
- POJ 1149 PIGS 最大流
- Java内存管理原理及内存区域详解
- 数据结构-树相关算法
- 第2周项目3-(2)体验复杂度
- [Leetcode] Power of Three
- Linux字符界面下ls分屏显示
- 忘记Win10电脑密码,修改密码的方法
- C语言取得int的位数
- 博客足迹
- [Leetcode] Power of Two
- 【light-oj】-1109 - False Ordering(数学)