二叉树算法小结

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;
}

 

posted @ 2012-06-13 13:49  w0w0  阅读(244)  评论(0)    收藏  举报