二叉查找树的插入与遍历

 

二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;

 

插入操作:

首先执行查找算法,找出被插结点的父亲结点。

判断被插结点是其父亲结点的左、右儿子。将被插结点作为 叶子结点插入。
二叉树为空。则首先单独生成根结点。
注意:新插入的结点总是 叶子结点
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode *Tree;
struct TreeNode 
{
	int num;
	Tree left;
	Tree right;
}TreeNode;

//二叉搜索树 的递归插入
Tree insert(Tree root,int element)  
{
	if(root==NULL)
	{
		root = (Tree)malloc(sizeof(TreeNode));
		root->num = element;
		root->left = NULL;
		root->right = NULL;
	}
	else if(root->num >= element)
	{
		root->left = insert(root->left,element);
	}
	else
	{
		root->right = insert(root->right,element);
	}
	return root;
}

//二叉搜索树 的迭代插入
Tree insert2(Tree root,int element)  
{
	Tree node = (Tree)malloc(sizeof(TreeNode));
	Tree before = NULL,tmp = root;
	int flag = 0;
	node->num = element;
	node->left = NULL;
	node->right = NULL;
	if(root==NULL)
	{
		printf("ddddd\n");
		return node;
	}
	while(tmp)
	{
		before = tmp;
		if(tmp->num >=element)
		{
			flag = 0;    //left
			tmp = tmp->left;
		}
		else
		{
			flag = 1;
			tmp = tmp->right;
		}
	}
	if(flag)
		before->right = node;
	else
		before->left = node;
	return root;
}


//递归前序遍历
void preOrder(Tree root)
{
	if(root)
	{
		printf("%d  ",root->num);
		preOrder(root->left);
		preOrder(root->right);
	}
}

//迭代前序遍历      下面是C++代码

/* 
思想:从根节点开始,先打印节点信息(获取数据),如果节点有右孩子,则有孩子入栈;
如果有左孩子,当前指针指向左孩子,没有左孩子的话,出栈。继续这个过程,直到获取栈元素的时候栈为空。

void PreOrder(BinaryTreeNode* pRoot)  
{  
    if (pRoot==NULL)  
        return;  
    std::stack<BinaryTreeNode*> S;  
    BinaryTreeNode *p=pRoot;   //二叉树分左右,所以光有栈不行,合理的运用遍历指针是关键之一   
    while(p!=NULL)  
    {  
        visit(p);   //打印数据
        if (p->m_pRight!=NULL)   //右孩子进栈
            S.push(p->m_pRight);  
        if (p->m_pLeft!=NULL)    //
            p=p->m_pLeft;  
        else  
        {  
            if (S.empty())  
                break;  
            p=S.top();  
            S.pop();  
        }  
    }  
}  */


//递归中序遍历
void inOrder(Tree root)
{
	if(root)
	{
		inOrder(root->left);
		printf("%d  ",root->num);
		inOrder(root->right);
	}
}

/*
void InOrder(BinaryTreeNode* pRoot)  
{  
    if (pRoot==NULL)  
        return;  
    std::stack<BinaryTreeNode*> S;  
    BinaryTreeNode *p=pRoot;  
    do   
    {  
        while(p!=NULL)  
        {  
            S.push(p);  
            p->m_pLeft;  
        }  
        //若进行到这里左子树为空   
        if (!S.empty())   //Stack不空时退栈,然后访问该元素   
        {  
            p=S.top();  
            S.pop();  
            visit(p);  
            p=p->m_pRight;  
        }  
    } while (p!=NULL||!S.empty());  
    //这里的p==NULL表示右子树为空,然后堆栈如果也空的话,才是处理完毕   
}  

*/

//递归后序遍历
void postOrder(Tree root)
{
	if(root)
	{
		postOrder(root->left);
		postOrder(root->right);
		printf("%d  ",root->num);
	}
}

/*迭代后序遍历

 void PostOrder(BinaryTreeNode* pRoot)  
{  
    if (pRoot==NULL)  
        return;  
    std::pair<BinaryTreeNode*,char> w;  
    std::stack<std::pair<BinaryTreeNode*,char> > S;  
    BinaryTreeNode *p=pRoot;        
    do   
    {  
        while(p!=NULL)           //左子树经过节点加L进栈   
        {  
            w.first=p;  
            w.second='L';  
            S.push(w);  
            p=p->m_pLeft;  
        }  
        bool continuel=true;     //继续循环标志,用于L改为R的时候就开始向右遍历   
        while (continuel && !S.empty()) //用一个break语句也能实现循环标志continuel的功能   
        {  
            w=S.top();  
            S.pop();  
            p=w.first;  
            if (w.second=='L')  //标记为L表示左子树遍历完   
            {  
                w.second=='R';  
                S.push(w);  
                continuel=false;  
                p=p->m_pRight;  
            }  
            else  
                visit(p);      //如果标记为R,表示右子树遍历完   
        }  
    }while (!S.empty());  
}  
*/


int main(int argc,char **argv)
{
	int array[] = {5,6,8,9,1,3,4,2,7,0};
	int i;
	Tree tree=NULL;
	for(i=0; i<10; i++)
	{
		tree = insert2(tree,array[i]);
	}
	printf("preOrder:\n");
	preOrder(tree);
	printf("\ninOrder\n");
	inOrder(tree);
	printf("\npostOrder\n");
	postOrder(tree);
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值