二叉树算法小结
1.广度优先遍历
也是层序遍历
void bfs(node *root) { queue<node*> q; q.push(root); while(!q.empty()) { node *n = q.front(); q.pop(); cout<<n->data; if(n->left!=NULL) q.push(n->left); if(n->right!=NULL) q.push(n->right); } }
2.深度优先遍历
非递归
void dfs(node *root) { stack<node*> s; s.push(root); while(s.empty()!=1) { node *n=s.top(); s.pop(); if(n!=NULL) { cout<<n->data; if(root->right!=NULL) { s.push(n->right); } if(n->left!=NULL) { s.push(n->left); } } } }
前序、中序、后序遍历
递归写法:
void dlr(node *root) { if(root!=NULL) { cout<<root->data; dlr(root->left); dlr(root->right); } } void ldr(node *root) { if(root!=NULL) { ldr(root->left); cout<<root->data; ldr(root->right); } } void lrd(node *root) { if(root!=NULL) { lrd(root->left); lrd(root->right); cout<<root->data; } }
前中后序遍历的非递归写法
前序遍历的非递归和深度优先遍历一样
void ldr_n(node* root) { node *p=root; stack<node*> s; while(s.empty()!=1 || p!=NULL) { if(p!=NULL) { s.push(p); p=p->left; } else { p=s.top(); s.pop(); cout<<p->data; p=p->right; } } } void lrd_n(node *root) { stack<node*> s; node *p=root; node *pre=NULL; while(!s.empty() || p) { if(p)//若节点非空则压栈,向左儿子移动 { s.push(p); p=p->left; } else { if(pre==s.top()->right)//若最近访问节点是栈顶结点的右儿子,则弹出节点并访问(此时栈顶元素的左儿子和右儿子都已经访问结束 { pre=s.top(); s.pop(); cout<<pre->data; } else if(pre==s.top()->left)//若最近访问节点是栈顶结点的左儿子,则节点指向栈顶元素右儿子(即将压栈的节点) { p=s.top()->right; pre=NULL; } } } }
求树的高度
int height(node *root) { if(root==NULL) return 0; return max(height(root->left), height(root->right))+1; }
判断是否是平衡二叉树
int isBalance(node *root) { if(root==NULL) return 1; int hleft=height(root->left); int hright=height(root->right); if(abs(hleft-hright)>1) return 0; return isBalance(root->left) && isBalance(root->right); }
查找最近公共父节点
node* com_father(node *root, node *a, node *b) { if(root==a) return a; if(root==b) return b; if(root==NULL) return NULL; if((com_father(root->left, a, b)==a&&com_father(root->right, a, b)==b) ||(com_father(root->left, a, b)==b&&com_father(root->right, a, b)==a) ||(com_father(root->left, a, b)==a&&root==b) ||(com_father(root->right, a, b)==b&&root==a)) { return root; } }
把查找二叉树变成双向链表
在中序遍历的基础上操作
node* make_list(node *root) { stack<node*> s; node *pre=NULL; node *head=NULL; node *p=root; while(s.empty()!=1 || p!=NULL) { if(p!=NULL) { s.push(p); p=p->left; } else { p=s.top(); s.pop(); if(pre!=NULL) { pre->right=p; } p->left=pre; if(head==NULL) { head=p; } pre=p; p=p->right; } } return head; }
已知前序和中序遍历
求树
node *beTree(int preorder[], int ps, int pe, int after[], int as, int ae) { int i; node *root=new node(preorder[ps], NULL, NULL); for(i=as;i<=ae;i++) { if(after[i]==preorder[ps]) { break; } } if(i>as) root->left=beTree(preorder, ps+1, ps+i-as, after, as, i-1); if(i<ae) root->right=beTree(preorder, ps+i-as+1,pe, after, i+1,ae); return root; }
浙公网安备 33010602011771号