c语言实现二叉树的创建及遍历

二叉树:一种常见的树形结构,每个节点中包含数据域和两个指针域,分别指向左右子树。
特点:

  1. 每个节点最多有两颗子树,且有左右之分。即其中不存在度大于2的节点
  2. 第i层至多有2^i-1个节点
  3. n个节点的树一共有2n个指针域,其中有2n+1个空指针域,因为有2n-1个指向(2n-1个节点有父节点)
    除此之外还有一些特殊结构的二叉树:
    满二叉树(树中不存在只有一个孩子的父节点,每一层的节点数都为2^i-1)、
    完全二叉树(叶子结点只出现在底下两层,且不存在只有右孩子而无左孩子)
    代码实现:
/*
tree.h文件,包含了二叉树节点的声明及方法的声明

*/
#ifndef _TREE_H    
#define _TREE_H    
                                                        
 typedef int BTDataType;     
 typedef struct BinaryTreeNode    
{                                                         
  BTDataType _data;                       
  struct BinaryTreeNode* _left;    
  struct BinaryTreeNode* _right;                           
}BTNode;                
//遍历                     
 void BinaryTreePrevOrder(BTNode* root);    
 void BinaryTreeInOrder(BTNode* root);                            
 void BinaryTreePostOrder(BTNode* root);                                                 

BTNode* BinaryTreeCreate(BTDataType* a, int* pi); //初始化二叉树   
void BinaryTreeDestory(BTNode* root); //销毁二叉树
int BinaryTreeSize(BTNode* root);    //统计二叉树节点数
int BinaryTreeLeafSize(BTNode* root);    //统计二叉树叶子结点数
int BinaryTreeLevelKSize(BTNode* root, int k);   //统计二叉树第k层节点数
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);//查找某一数据的所在节点
#endif
/*
文件包含了tree.h文件中声明的方法实现及测试

tree.cpp文件,由于在操作中是用了c++中STL库,
所以是.cpp文件,但在实现中除STL库之外均是用c语言实现

*/
#include<iostream>
#include<cstdio>
#include<cassert>
#include<cstdlib>
#include<queue>
#include"tree.h"
using namespace std;

BTNode* BinaryTreeCreate(BTDataType* a,int* pi)
{
  static int s_n=0;
  if(a[s_n]==*pi)
  {
    s_n++;
    return NULL;
  }
  BTNode* New=(BTNode*)malloc(sizeof(BTNode));
  New->_data=a[s_n];
  s_n++;
  New->_left=BinaryTreeCreate(a,pi);
  New->_right=BinaryTreeCreate(a,pi);
  return New;
}
void BinaryTreeDestory(BTNode* root)
{
  if(root==NULL)
  {
    return ;
  }
  BinaryTreeDestory(root->_left);
  BinaryTreeDestory(root->_right);
  free(root);
}
int BinaryTreeSize(BTNode* root)
{
  if(root==NULL)
  {
    return 0;
  }
  int lNum=BinaryTreeSize(root->_left);
  int rNum=BinaryTreeSize(root->_right);
  return lNum+rNum+1;
}
int BinaryTreeLeafSize(BTNode* root)
{
  if(root==NULL)
  {
    return 0;
  }
  if(root->_left || root->_right)
  {
    return BinaryTreeLeafSize(root->_left)+BinaryTreeLeafSize(root->_right);
  }
  return 1;
}
int BinaryTreeLevelKSize(BTNode* root, int k)
{
  assert(root!=NULL);
  queue<BTNode*> qu;
  qu.push(root);
  int level=1;
  int levNum=1;
  while(!qu.empty())
  {
    if(k==level)
    {
      return levNum;
    }
    BTNode*tmp=qu.front();
    qu.pop();
    levNum--;
    if(tmp->_left)
    {
      qu.push(tmp->_left);
    }
    if(tmp->_right)
    {
      qu.push(tmp->_right);
    }
    if(levNum==0)
    {
      level++;
      levNum=qu.size();
    }
  }
  return -1;
}
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
  if(root==NULL)
  {
    return NULL;
  }
  if(root->_data==x)
  {
    return root;
  }
  BTNode*lTree=BinaryTreeFind(root->_left,x);
  if(lTree)
  {
    return lTree;
  }
  BTNode*rTree=BinaryTreeFind(root->_right,x);
  if(rTree)
  {
    return rTree;
  }
  else{
    return NULL;
  }
}
void BinaryTreePrevOrder(BTNode* root)
{
  if(root==NULL)
  {
    return;
  }
  printf("%d",root->_data);
  BinaryTreePrevOrder(root->_left);
  BinaryTreePrevOrder(root->_right);
}
 void BinaryTreeInOrder(BTNode* root)
{
  if(root==NULL)
  {
    return;
  }
  BinaryTreePrevOrder(root->_left);
  printf("%d",root->_data);
  BinaryTreePrevOrder(root->_right);
}
 void BinaryTreePostOrder(BTNode* root)
{
  
  if(root==NULL)
  {
    return;
  }
  BinaryTreePrevOrder(root->_left);
  BinaryTreePrevOrder(root->_right);
  printf("%d",root->_data);
}
void BinaryTreePrint(BTNode*root)
{
 assert(root);
 queue<BTNode*> qu;
 qu.push(root);
 int level=1;
 while(!qu.empty())
 {
   BTNode*tmp=qu.front();
  printf("%d ",tmp->_data);
  qu.pop();
  level--;
  if(tmp->_left)
  {
    qu.push(tmp->_left);
  }
  if(tmp->_right)
  {
    qu.push(tmp->_right);
  }
  if(level==0)
  {
    putchar('\n');
    level=qu.size();
  }
 }
}
int main()
{

  BTNode* root;
  int arr[]={0,4,10,23,-1,-1,24,-1,-1,12,25,-1,-1,26,-1,-1,8,13,21,-1,-1,-1,-1};
  int flag=-1;
  root=BinaryTreeCreate(arr,&flag);
  BinaryTreePrint(root);
  BTNode* pTree= BinaryTreeFind(root,10);
  printf("查找10的节点为:%p,数据为:%d\n",pTree,pTree->_data);
  printf("root树的叶子节点个数为:%d\n",BinaryTreeLeafSize(root));
  int n;
  printf("输入你要查看的哪一层数的节点数");
  scanf("%d",&n);
  printf("%d层的节点个数为:%d\n",n,BinaryTreeLevelKSize(root,n));

  BinaryTreeDestory(root);
  return 0;
}

运行结果:

[test@bogon Tree]$ ./tree.out 
0 
4 8 
10 12 13 
23 24 25 26 21 
查找10的节点为:0x1ea9c60,数据为:10
root树的叶子节点个数为:5
输入你要查看的哪一层数的节点数4
4层的节点个数为:5

其中大多数使用了递归方法,其中稍微不同的是统计第k层节点个数和打印的时候使用queue数据结构来辅助,这其实和实现二叉树的层序遍历相同。主要是借助了队列的先入先出的特点,每次将上层节点入队,每个节点出队时都将其左右孩子入队,统计记录每一层的节点数,当节点数为0时,说明该层节点已经全部出队,此时队列中保存的节点为下层的所有节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值