二叉树

序:二叉树作为树的一种,是一种重要的数据结构,常见的二叉树有:
满二叉树:除叶子结点外,所有结点都有两个结点,叶子结点的left,right为NULL.
哈夫曼树:又称为最优二叉数,是一种带权路径最短的树。哈夫曼编码就是哈夫曼树的应用,可以用来进行编码压缩.哈夫曼树的构造见哈夫曼树的构造
完全二叉树:除了最底层的叶子结点之外,其余层全满,而且叶子层集中在左端.堆是一种特殊的完全二叉树(全满或者差一个结点就全满)
平衡二叉树:所谓平衡二叉树指的是,左右两个子树的高度差的绝对值不超过 1。包括AVL树,红黑树.
红黑树:具体见红黑树问题
下面是我总结的这几天看过的一些常见二叉树问题.

1.二叉搜索树的迭代构造

二叉搜索树是一棵排好序的树,当新插入一个节点的时候,小于当前根结点左走,大于当前根结点右走,直至走到NULL点,就是该结点的位置.

 

void IterativeInsert(Tree* T,node* z)//插入节点  
{  
    node* y=NULL;  
    node* x=T->root;//管理两个指针,父指针y,y的子树指针x  
    while(x!=NULL)//一直向下遍历到z应该插入的位置  
    {  
        y=x;  
        if(x->value < z->value)  
            x=x->right;  
        else x=x->left;  
    }  
    z->p=y;//先将z的父指针p指向y  
    if(y==NULL)//若树为空,树根即为z  
        T->root=z;  
    else if(z->value < y->value)//否则分插入左边还是右边  
        y->left=z;  
    else y->right=z;  
}

 

2.二叉搜索树的递归构造

1.若是空树,则插入至根结点位置

2.若比当前根点,插入左边.

3.否则插入右边

 

node* TreeInsert(node* root,node* z)
{
	if(!root)
		root=z;
	else if(root->value < z->value)
		root->right=TreeInsert(root->right,z);
	else root->left=TreeInsert(root->left,z);
	return root;
}

 

3.二叉树三种递归遍历方式.

 

void InorderTreeWalk(node* root)
{
	if(!root ) return ;
	InorderTreeWalk(root->left);
	cout<<root->value<<' ';
	InorderTreeWalk(root->right);
}
void PriorTreeWalk(node* root)
{
	if(!root ) return ;
	cout<<root->value<<' ';
	PriorTreeWalk(root->left);
	PriorTreeWalk(root->right);
}
void PostTreeWalk(node* root)
{
	if(!root ) return ;
	PostTreeWalk(root->left);
	PostTreeWalk(root->right);
	cout<<root->value<<' ';
}

 

4.二叉树三种迭代遍历方式.

深度优先原则,输出顺序是'左子树优先'

 

void IterativeInorderWalk(node *root)//迭代中序遍历  
{  
    node* p=root;  
    stack<node*> st;//利用栈  
    if(!p)  //if(!p)=if(p==null)
        return ;  
    while(p || !st.empty())//当p不为空 或者st不为空  
    {  
        while(p)//沿着左孩子方向走到最左下。同时压栈  
        {  
            st.push(p);  
            p=p->left;  
        }  
        p=st.top();//获取栈顶元素  
        cout<<p->value<<" ";  
        st.pop();  
        p=p->right;  
    }  
}  

void IterativePriorTreeWalk(node* root)//迭代先序遍历  
{  
    node* p=root;  
    stack<node* > st;  
    if(!p)   
        return ;  
    while(p || !st.empty())  
    {  
        while(p)  
        {  
            cout<<p->value<<" ";  
            st.push(p);  
            p=p->left;  
        }  
        p=st.top();  
        st.pop();  
        p=p->right;  
    }  
}  

void IterativePostWalk(node* root)  
{  
    node* p=root;  
    stack<node* > st;  
    node* pre=NULL;//pre表示最近一次访问的结点  
    if(!p) return ;  
    while(p || !st.empty())  
    {  
        while(p)    //沿着左孩子方向走到最左下  
        {  
            st.push(p);  
            p=p->left;  
        }  
        p=st.top(); //获取栈顶元素  
        if( !p->right || p->right ==pre)//如果p没有右孩子或者其右孩子刚刚被访问过.小窍门if (!p)表示如果p为空  
        {  
            st.pop();  
            cout<<p->value<<' ';  
            pre=p;      //最近一次访问的节点是p  
            p=NULL;     //使下一次循环不再执行p节点以下的压栈操作  
        }  
        else  
            p=p->right;  
    }  
}  

 

5.怎样从根结点开始逐层打印二叉树结点数据.

广度优先原则,需要用到队列,当访问一个当前节点CurrentNode的时候,将该结点出队,同时将该CurrentNode的左右子结点入队,重复这个操作,直至队列为空.步骤:1初始化队列.2重复出队入队操作直至队列为空.

 

//从顶部开始逐层打印二叉树结点数据,即广度遍历二叉树,需要用到队列
void printHori(node* root)
{
	if(!root) return ;
	queue<node*> Q;
	Q.push(root);
	while(!Q.empty())
	{
		nod
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raise

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值