二叉树的遍历

简单生成一个二叉树,可测前序,中序,后序遍历。

// testbina.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<stdlib.h>
#include <time.h>
struct tree                //声明树的结构
{
    int data;
    struct tree *left;
    struct tree *right;
};

typedef struct tree treenode;
typedef treenode *b_tree;             //声明二叉树链表

//遍历求树高

int hight_tree(b_tree t){
    int h,left,right;
    if(!t){
        return 0;
    }
    left = hight_tree(t->left);
    right = hight_tree(t->right);
    h = (left>right?left:right)+1;
    return h;
}

//首先应该明白isB函数的功能,它对于空树返回0,对于平衡树返回树的深度,对于不平衡树返回-1。明白了函数的功能再看代码就明白多了,只要有一个函数返回了-1,则整个函数就会返回-1。

int isB(Tree t){
      if(!t) return 0;
    int left=isB(t.left);
    int right=isB(t.right);
    if( left >=0 && right >=0 && left - right <= 1 || left -right >=-1)
        return (left < right)? (right +1) : (left + 1);
    else return -1;
}

//两个树是否一样

int is_equal(bintree t1,bintree t2){
    if(!t1 && !t2){      //都为空就相等
        return 1;
    }
    if(t1 && t2 && t1->data == t2->data){      //有一个为空或数据不同就不判断了
        if(is_equal(t1->lchild,t2->lchild))
            if(is_equal(t1->rchild,t2->rchild)){
                return 1;
            }
    }
    return 0;
}

//二叉树的查找

bintree search_tree(bintree t,datatype x){
    if(!t){
        return NULL;
    }
    if(t->data == x){
        return t;
    }else{
        if(!search_tree(t->lchild,x)){
            return search_tree(t->rchild,x);
        }
        return t;
    }
}

//创建二叉树--先序输入--递归
b_tree createBiTreePreOrder()
{
    b_tree ptree = NULL;
    int data;  
    scanf("%d",&data);  
    if(data == 0 ) {
      return NULL;
    }else{
        ptree=(b_tree)malloc(sizeof(treenode));
        ptree->data = data;
        ptree->left=createBiTreePreOrder();
        ptree->right=createBiTreePreOrder();
    }
    return ptree;
}


b_tree insert_node(b_tree root,int data)
{
    b_tree newnode;
    b_tree temp;
    newnode=(b_tree)malloc(sizeof(treenode));     //建立新节点的内存空间
    newnode->data=data;
    newnode->right=NULL;
    newnode->left=NULL;

    if(root == NULL)// = -> ==
    {
        return newnode;
    }
    else
    {
        temp = root;
        while(temp != 0)
        {
            if(newnode->data > temp->data)
            {
                if(temp->right == 0)
                {
                    temp->right = newnode;
                    break;
                }
                else
                {
                    temp = temp->right;
                }
            }
            else
            {
                if(temp->left == 0)
                {
                    temp->left = newnode;
                    break;
                }
                else
                {
                    temp = temp->left;
                }
            }            
        }
    }
    return root;
}

// 建立二叉树
b_tree create_btree(int *data,int len)
{
    b_tree root=NULL;
    int i;

    for(i=0;i<len;i++)
    {
        root=insert_node(root,data[i]);

    }
    return root;
}

//二叉树前序遍历
void preorder(b_tree point)
{
    if(point!=NULL)
    {
         printf("%d--",point->data);
        preorder(point->left);
        preorder(point->right);
    }
}

//二叉树中序遍历
void midorder(b_tree point)
{
    if(point!=NULL)
    {
        midorder(point->left);
        printf("%d--",point->data);
        midorder(point->right);
    }
}

//二叉树后序遍历
void postorder(b_tree point)
{
    if(point!=NULL)
    {
        postorder(point->left);
        postorder(point->right);
        printf("%d--",point->data);
    }
}

//二叉树前序遍历 非递归

void PreOrderWithoutRecursion1(b_tree root)
{
    if (root == NULL){
        return;
    }

    b_tree p = root;
    stack<b_tree> s;
    while (!s.empty() || p)
    {
        //边遍历边打印,并存入栈中,以后需要借助这些根节点(不要怀疑这种说法哦)进入右子树
        while (p)
        {
            printf("%d--", p->data);
            s.push(p);
            p = p->left;
        }
        //当p为空时,说明根和左子树都遍历完了,该进入右子树了
        if (!s.empty())
        {
            p = s.top();
            s.pop();
            p = p->right;
        }
    }
    cout << endl;
}

//中序非递归遍历
//中序遍历
void InOrderWithoutRecursion1(b_tree root)
{
    //空树
    if (root == NULL)
        return;
    //树非空
    b_tree p = root;
    stack<b_tree> s;
    while (!s.empty() || p)
    {
        //一直遍历到左子树最下边,边遍历边保存根节点到栈中
        while (p)
        {
            s.push(p);
            p = p->left;
        }
        //当p为空时,说明已经到达左子树最下边,这时需要出栈了
        if (!s.empty())
        {
            p = s.top();
            s.pop();
            printf("%d--", p->data);
            //进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)
            p = p->right;
        }
    }
}

//后序非递归遍历  
Status PostOrderTraverseExt(const BiTree &T, Status(*Visit)(TElemType e))  
{  
    //后序非递归遍历  
    SqStack S;  
    SElemType e;  
    InitStack(S);  
    SElemType lastVist = NULL;  
    e = T;   
    while(!StackEmpty(S) || e)  
    {  
        while(e)  
        {  
            Push(S,e);  
            e = e->lchild;//左孩子进栈  
        }  
        GetTop(S,e);  
        if(!e->rchild)  
        {    
            //如果结点没有右孩子  
            //则说明该访问该结点了      
            if(!Visit(e->data))  
                return ERROR;  
            Pop(S,lastVist);  
            e = e->rchild;  
        }  
        else if(lastVist == e->rchild)  
        {  
            //上次访问了它的右孩子  
            //则说明该访问该结点了  
            if(!Visit(e->data))  
                return ERROR;  
            Pop(S,lastVist);  
            e = NULL;  
        }  
        else  
        {  
            e = e->rchild;  
        }  
    }  
    return OK;  


//主程序
void main()
{
    b_tree root=NULL;
    int nodelist[20];
     int num = 10;

    if(1){
        int index = 0;

        printf("\n pleaase input the elements of binary tree(exit for 0 ):\n");
        //读取数值存到数组中
        scanf("%d",&num);
        while(num != 0)
        {
            nodelist[index]=num;
            index=index+1;
            scanf("%d",&num);
        }
        num = index;
    }else{
        srand((unsigned)time(0));      

        for(int i=0;i<num;i++){
            int  ran_num = rand() % 100;
            nodelist[i] = ran_num;
            printf("random num:%d\n", ran_num);
        }  
    }
 
    //建立二叉树
    root=create_btree(nodelist,num);

    //中序遍历二叉树
    printf("\nThe inorder traversal result is :");
    midorder(root);
    printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

山西茄子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值