C++ 完全二叉树的建立、先序递归非递归遍历、层序遍历

今天学习了完全二叉树,是二叉树的一种,有以下特点:

1.所有叶子节点都在最后一层或者倒数第二层;

2.倒数第二层的所有叶子节点都在非终结节点的右边。

3.倒数第二层除了最右边的非终结节点可能有一个或两个儿子(有一个儿子,必然是左儿子),剩下的非终结节点都有两个分支。

完全二叉树的建立,借助于队列实现。基本思想是:

1.如果树是一个空树,就插入根节点,并把根节点入队。

2.如果树非空:

(1)如果队首节点的左儿子为空,将插入的新节点作为队首节点左儿子,然后把该节点入队;

(2)如果队首节点的左儿子非空,但右儿子为空,就将新加入的节点作为队首节点的右儿子,然后把该节点入队,队首节点出队;

由此观之,完全二叉树的建立是按照层序的顺序,层序遍历的结果和插入顺序一样。

对于先序遍历,递归的实现很简单,非递归借助于一个栈实现,思想如下:

1.记root节点为根节点。

2.循环直到root为空且栈为空:

1.循环直到root为空:

输出root的data;

root压栈;

root = root的左儿子;

2.若栈非空:

栈顶元素弹出至root;

root = root的右儿子

这个看上去不太好理解,但是先序遍历的顺序是“根、左、右”,仔细看看就会记住了。

层序遍历的思想与建立的思想完全一样,也是借助于队列,这里就不说了。

#include <iostream>
#include <queue>
#include <stack>
//完全二叉树的操作:建立、递归和非递归遍历(先序)、层序遍历、
using namespace std;

struct node{
    struct node *lchild;
    struct node *rchild;
    char data;
};
typedef struct node *BTREE;//定义指向节点的指针类型.名字叫BTREE

struct tree{
     BTREE root;
     queue <BTREE> insert_queue;
     stack <BTREE> search_stack;
     queue <BTREE> search_queue;
};
typedef struct tree *TREE;

TREE CreateTree(char data);//可以利用队列建立完全二叉树,实际上是按照层序插入
void InsertNode(TREE tree,char data);//插入
void ProOrder_Re(BTREE n);//先序遍历(递归)
void ProOrder(TREE n);//先序遍历(非递归)
void LevelOrder(TREE n);//层序遍历

int main()
{
    TREE tree_sample = CreateTree('a');
    while(1)
    {

        char x;
        cin>>x;
        if(x=='1')//先序遍历(递归)
        {
            ProOrder_Re(tree_sample->root);
            cout<<endl;
        }
        else if(x=='2')//先序遍历(非递归)
        {
            ProOrder(tree_sample);
        }
        else if(x=='3')//层序遍历
        {
            LevelOrder(tree_sample);
        }
        else
        {
            InsertNode(tree_sample,x);
        }
    }

    return 0;
}

TREE CreateTree(char data)
{
    TREE tree_sample = new tree();
    tree_sample->root= new node();
    tree_sample->root->data = data;
    tree_sample->root->lchild = NULL;
    tree_sample->root->rchild = NULL;
    tree_sample->insert_queue.push(tree_sample->root);
    return tree_sample;
}

void InsertNode(TREE tree,char data)
{
    BTREE parent = tree->insert_queue.front();

    if(parent->lchild==NULL)
    {

        parent->lchild = new node();
        parent->lchild->data = data;
        parent->lchild->lchild = NULL;
        parent->lchild->rchild = NULL;
        tree->insert_queue.push(parent->lchild);
    }
    else if(parent->rchild==NULL)
    {

        parent->rchild = new node();
        parent->rchild->data = data;
        parent->rchild->lchild = NULL;
        parent->rchild->rchild = NULL;
        tree->insert_queue.push(parent->rchild);
        tree->insert_queue.pop();
    }

}
void ProOrder_Re(BTREE n)//先序遍历递归算法
{
    if(n!=NULL)
    {
        cout<<n->data;
        ProOrder_Re(n->lchild);
        ProOrder_Re(n->rchild);
    }
}
void ProOrder(TREE n)//这个是重点,也不好理解
{
    BTREE a = n->root;
    while(a!=NULL || n->search_stack.size()!=0)
    {
        while(a!=NULL)
        {
            cout<<a->data;
            n->search_stack.push(a);
            a = a->lchild;
        }
        if(n->search_stack.size()!=0)
        {
            a = n->search_stack.top();
            n->search_stack.pop();
            a = a->rchild;
        }
    }
    cout<<endl;
}
void LevelOrder(TREE n)
{
    BTREE a = n->root;
    if(a!=NULL)
    {
        cout<<a->data;
        n->search_queue.push(a);
    }
    else
    {
        return;
    }
    while(n->search_queue.size()!=0)
    {
        a = n->search_queue.front();
        if(a->lchild!=NULL)
        {
            cout<<a->lchild->data;
            n->search_queue.push(a->lchild);
        }
        if(a->rchild!=NULL)
        {
            cout<<a->rchild->data;
            n->search_queue.push(a->rchild);
        }
        n->search_queue.pop();
    }
    cout<<endl;
}




  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值