今天学习了完全二叉树,是二叉树的一种,有以下特点:
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;
}