关于二叉树的插入和遍历

    在数据结构中,要我选择的话,优先选择C++的容器,出错率小,其次就是二叉树了。至于哈希表这种需要思考一个好的键值的反而最不擅长,本文就讲下二叉树的存储和遍历,直接上代码(话说这个博客的代码编译器真不好用!)。

 
#include <stdio.h>
#include <stdlib.h>
struct TNode
{
        char data;//这里可以写成struct xxx data,测试就用char类型了
        struct TNode *lchild;
        struct TNode *rchild;//定义节点
};
typedef struct TNode Node;//定义别名
int init(Node **node)// 申请新的节点空间,左右孩子置为NULL,成功为0,失败-1
{
        *node = (Node *)malloc(sizeof(Node));
        if(*node!=0)
        {
                return -1;
        }
        (*node)->lchild = (*node)->rchild = NULL;(*node)->data = 0;
        reuturn 0;
}
int construct(char data, Node **node)//本次的重点,就时把大的数据放在右边,小的放左边,若插入成功返回0,失败-1,这样查找数据时时间复杂度为log2 n次
{int i;
Node *temp_node = *node;
while(temp_node)//判断头节点是否为空,若为空,不进行任何操作
{
                if(!temp_node->data)
                {
                        temp_node->data=data; 
                        return 0;
                }
                else if(data<=temp_node->data)
                {
                        if(!temp_node->lchild)
                        {    
                                if(!init(&temp_node->lchild))
                                {  
                                        temp_node->lchild->data=data;//生成节点插入数据。    
                                        return 0;
                                }
                                else
                                    return -1;
                        }
                        else
                        {
                                temp_node = temp_node->lchild;
                                continue;
                        }
            }    

            else if(data > temp_node->data)
            {
                     if(!temp_node->rchild)
                     {
                              if(!init(&temp_node->rchild))
                              { 
                                      temp_node->rchild->data=data; 
                                       return 0;
                               }
                              else
                                       return -1;
                   }
                   else
                    {     
                           temp_node = temp_node->rchild;    
                           continue;
                     }
                }
       }      
return -1;
}
int preordertraverse(Node *tree_node)//先序遍历
{
        if(tree_node)
       {
            printf("%c ",tree_node->data);
            if(preordertraverse(tree_node->lchild))
                    if(preordertraverse(tree_node->rchild))
                            return 1;
            return 0;
        }
        else
                return 1;
}
int inordertraverse(Node *tree_node)//中序遍历
{
        if(tree_node)
        {
                if(inordertraverse(tree_node->lchild))
                        printf("%c ",tree_node->data);
                                if(inordertraverse(tree_node->rchild))
                                         return 1;
              return 0;
        }
        else
                return 1;
}
int postordertraverse(Node *tree_node)//后序遍历
{
         if(tree_node)
        {
                if(postordertraverse(tree_node->lchild))
                        if(postordertraverse(tree_node->rchild))
                        {    
                                printf("%c ",tree_node->data);
                                return 1;
                        }
                return 0;
        }
        else
                return 1;
}//这三个遍历就是简单的递归调用,区别就是printf在那个位置
int main()
{
        int i;
        Node *root;    
        char data[8] = {'e','f','h','g','a','c','b','d'};
        init(        &root);    
        for(i=0;i<8;i++)
                    construct(data[i],&root);
         pirntf("\npreorder .............\n");
         preordertraverse(root);
         printf("\npostorder ..............\n");
         postordertraverse(root);
         printf("\ninordertraverse ..........\n");
         inordertraverse(root); printf("\n");
        return 0;
}
    这就是笔者二叉树的习惯用法,查找效率比较高,时间复杂度为log2  n次,还是比较好用的,可以当个模板。
二叉树 遍历 插入 二叉树的三种遍历,先,中,后遍历 二叉树遍历分为以下三种: 先序遍历遍历顺序规则为【根左右】 中序遍历遍历顺序规则为【左根右】 后序遍历遍历顺序规则为【左右根】 什么是【根左右】?就是先遍历根,再遍历左孩子,最后遍历右孩子; 举个例子,看下图(图从网上找的): 先序遍历:ABCDEFGHK 中序遍历:BDCAEHGKF 后序遍历:DCBHKGFEA 以中序遍历为例: 中序遍历的规则是【左根右】,我们从root节点A看起; 此时 是根节点,遍历A的左子树; A的左子树存在,找到B,此时B看做根节点,遍历B的左子树; B的左子树不存在,返回B,根据【左根右】的遍历规则,记录B,遍历B的右子树; B的右子树存在,找到C,此时C看做根节点,遍历C的左子树; C的左子树存在,找到D,由于D是叶子节点,无左子树,记录D,无右子树,返回C,根据【左根右】的遍历规则,记录C,遍历C的右子树; C的右子树不存在,返回B,B的右子树遍历完,返回A; 至此,A的左子树遍历完毕,根据【左根右】的遍历规则,记录A,遍历A的右子树; A的右子树存在,找到E,此时E看做根节点,遍历E的左子树; E的左子树不存在,返回E,根据【左根右】的遍历规则,记录E,遍历E的右子树; E的右子树存在,找到F,此时F看做根节点,遍历F的左子树; F的左子树存在,找到G,此时G看做根节点,遍历G的左子树; G的左子树存在,找到H,由于H是叶子节点,无左子树,记录H,无右子树,返回G,根据【左根右】的遍历规则,记录G,遍历G的右子树; G的右子树存在,找到K,由于K是叶子节点,无左子树,记录K,无右子树,返回G,根据【左根右】的遍历规则,记录F,遍历F的右子树; F的右子树不存在,返回F,E的右子树遍历完毕,返回A; 至此,A的右子树也遍历完毕; 最终我们得到上图的中序遍历为BDCAEHGKF,无非是按照遍历规则来的; 根据“中序遍历”的分析,相信先序遍历和后序遍历也可以轻松写出~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值