您的位置:首页 > 其它

二叉树学习总结-建立、广度优先算法,前序中序后序非递归算法

2015-08-25 14:55 381 查看
二叉树的知识前后学习过几遍,学习过后过段时间总是会遗忘,记录下这次的学习内容,权当做笔记了。也欢迎大家批评指正,共同进步。

树节点定义:

struct treenode
{
int data;
treenode *lchild;
treenode *rchild;
};
指向树的结构:
struct tree

{
treenode *root;

};

一、树的建立

树的建立用的是插入结点的算法:将待插入的结点表示为tempptr,将这个结点值从树根开始向下进行比较:若大于一个比较结点tempptr1则转向比较的右子女,否则转向左子女,直到比较的结点tempptr1为空。在比较的过程中需要一个辅助指针pretempptr1,作为比较结点tempptr1的父结点。最后将tempptr作为pretempptr1的子女,当然还要判断是做左子女还是做右子女。

void maketree(treenode *&root)
{
int temp;
treenode *pretempptr1,*tempptr1;
cout<<"please input a number:\n";
cin>>temp;
if(temp==-1)   //若输入-1表示结束树的输入
{
root=NULL;
return;
}
treenode *tempptr=new treenode;
tempptr->data=temp;
tempptr->lchild=NULL;
tempptr->rchild=NULL;

root=tempptr;

cout<<"please input a number:\n";
cin>>temp;
while(temp!=-1)
{
pretempptr1=root;
tempptr1=root;

tempptr=new treenode;
tempptr->data=temp;
tempptr->lchild=NULL;
tempptr->rchild=NULL;

while(tempptr1!=NULL)
{
pretempptr1=tempptr1;
if(tempptr1->data>tempptr->data)
tempptr1=tempptr1->lchild;
else
tempptr1=tempptr1->rchild;
}
if(pretempptr1->data>tempptr->data)
{
pretempptr1->lchild=tempptr;
}
else
pretempptr1->rchild=tempptr;
cout<<"please input a number:\n";
cin>>temp;
}
}

二、广度优先算法
广度优先算法,采用自上而下,从左到右的顺序来遍历。遍历借助队列来实现,实现的要点为:每访问一个结点,若此结点的左子女非空,则将此左子女加入队列;若右子女非空,则将此右子女加入队列。通过这种方式即可保证每一层的结点自左到右依次加入队列。

void breadfirst(treenode *&root)
{
queue<treenode *> queue_tree;
treenode *temp=root;
if(root==NULL)
{
cout<<"the tree is empty!"<<endl;
return;
}
queue_tree.push(temp);
while(!queue_tree.empty())
{
temp=queue_tree.front();
queue_tree.pop();
cout<<temp->data<<" ";
if(temp->lchild!=NULL)
queue_tree.push(temp->lchild);
if(temp->rchild!=NULL)
queue_tree.push(temp->rchild);
}
}

三、树的非递归遍历

前序:

void iterativeNLR(treenode *&root)
{
stack<treenode *> stack_tree;
treenode *temp;
if(root==NULL)
{
cout<<"the tree is empty!"<<endl;
return;
}
temp=root;
//stack_tree.push(root);
while(temp!=NULL||!stack_tree.empty())
{
while(temp!=NULL)
{
cout<<temp->data<<" ";
stack_tree.push(temp);
temp=temp->lchild;
}
if(!stack_tree.empty())
{
temp=stack_tree.top();
stack_tree.pop();
temp=temp->rchild;
}
}
}
中序:
void iterativeLNR( treenode *&root)
{
stack<treenode *> stack_tree;
treenode *temp;
if(root==NULL)
{
cout<<"the tree is empty!"<<endl;
return;
}
temp=root;
//stack_tree.push(temp);

while(!stack_tree.empty()||temp!=NULL)
{
while(temp!=NULL)
{
stack_tree.push(temp);
temp=temp->lchild;
}

if(!stack_tree.empty())
{
temp=stack_tree.top();
cout<<temp->data<<" ";
stack_tree.pop();
//  if(temp->rchild!=NULL)
temp=temp->rchild;
}
}
}

后序:

后序稍微复杂一些,因为在访问完一个左子女后待访问该结点的父结点时,需要判断该父结点的右子女是否已经访问:可以借助于一个bool型变量来实现。当bool=true时表示右子女已经访问。

void iterativeLRN(treenode *&root)
{
stack<pair<treenode *,bool>> stack_tree;
treenode *temp=root;
if(root==NULL)
{
cout<<"the tree is empty!"<<endl;
return;
}
while(temp!=NULL||!stack_tree.empty())
{
while(temp!=NULL)
{
stack_tree.push(make_pair(temp,false));
temp=temp->lchild;
}

if(!stack_tree.empty()&&stack_tree.top().second==true)
{
cout<<stack_tree.top().first->data<<" ";
stack_tree.pop();
}
if(!stack_tree.empty())
{
stack_tree.top().second=true;
temp=stack_tree.top().first->rchild;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息