关闭

C语言基本数据结构之二(二叉树的三种遍历,节点数以及深度算法)

标签: c语言数据结构算法二叉树
2569人阅读 评论(0) 收藏 举报
分类:

关于二叉树的定义,网上有比较好的介绍,在这里就简单介绍二叉树的一些性质

二叉树的基本性质

1)二叉树的第i层上至多有 2^(i-1)(i ≥1)个结点;
2)深度为 h 的二叉树中至多含有 2^h – 1 个结点;
3)若在任意一棵二叉树中,有 n0 个叶子结点,有 n2 个度为 2 的结点,则:n0 = n2 + 1。

特殊形式的二叉树

1)满二叉树
特点:深度为h且含有2h-1个结点的二叉树,为满二叉树。图示满二叉树,结点编号为自上而下,自左而右。
2)完全二叉树(左图)
特点:指深度为k的,有n个结点的,且每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应,完全一致,则为完全二叉树。(右图)


3)平衡二叉树
特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为0,-1,1。

关于二叉树的存储方式(顺序和链式存储)

(1) 顺序存储结构

用一组连续的存储单元存放二叉树的数据元素。结点在数组中的相对位置蕴含着结点之间的关系。
其所需的存储单元数为:2^h-1= 24-1 = 15,若父结点在数组中i下标处,其左孩子在2*i处,右孩子在2*i+1处。


(2)链式存储结构
链式存储结构的每个结点由数据域、左指针域和右指针域组成。左指针和右指针分别指向下一层的二叉树
             

放二叉树的数据元素。结点在数组中的相对位置蕴含着结点之间的关系

关于二叉树的三种遍历方式

(1)先序遍历(D L R): 访问根结点,按先序遍历左子树,按先序遍历右子树。
(2)中序遍历(L D R): 按中序遍历左子树,访问根结点,按中序遍历右子树。
(3)后序遍历(L R D): 按后序遍历左子树,按后序遍历右子树,访问根结点。

还是直接上代码吧~~这里用的是链式存储结构,相对顺序存储结构,前者所需存储容量更小,更易于理解~~

二叉树的结构体
struct Tree{
	int data;//这里可以改成你想要的数据类型
	tree *left;
	tree *right;
};

初始化二叉树,添加数据
tree *initTree(tree* H){
	H = NULL;
	int data = 0;
	printf(" 输入data \n ");
	scanf("%d",&data);
	if(data!=0){
		H = (tree *)malloc(sizeof(tree));
		H->data = data;
		printf(" t data is %d \n",H->data);
		printf(" 请输入左字树data \n");
		H->left = initTree(H->left);
		printf(" 请输入右字树data \n");
		H->right = initTree(H->right);
	}
	return H;
}

先序,中序,后序遍历的递归算法(ps:递归真是个好东西~~,写出来的代码就是简洁~~)
/*
先序遍历
*/
void DLR(tree* T){
	if(NULL!=T){
		printf(" data is %5d \n ",T->data);
		DLR(T->left);
		DLR(T->right);
	}
}
/*
中序遍历
*/
void LDR(tree* T){
	if(NULL!=T){
		LDR(T->left);
		printf(" data is %5d \n",T->data);
		LDR(T->right);
	}
}
/*
后序遍历
*/
void LRD(tree* T){
	if(NULL!=T){
		LRD(T->left);
		LRD(T->right);
		printf(" data is %5d \n",T->data);
	}
}

二叉树的层次遍历
void LOrder(tree* T) /* 层次遍历二叉树T */
{ treeQ[MAXNODE];     /* 辅助队列,MAXNODE为最大的队列容量 */ 
  int f,r;               /* 队列的首、尾指针 */
  if (T == NULL) return; /* 空树,直接返回 */
  f = -1;                /* 队首,队尾指针初始化 */ 
  r = 0;
  Q[r] = T;              /* 树根进队 */
  while( f != r )
   { f++;
     printf(“%d”,Q[f]->data);   /* 访问队首结点的数据域 */
     if (Q[f]->left!= NULL)  /* 将队首结点的左孩子入队列 */
      { r++;
        Q[r] = Q[f]->left;  }
     if (Q[f]->right!= NULL)  /* 将队首结点的右孩子入队列 */
      { r++;
        Q[r] = Q[f]->right;  }
   } 
}


计算二叉树的深度;
/*计算树的深度*/
int deep(tree* H){
	int d1 = 0;
	int d2 = 0;
	if(NULL!=H){
		d1 = deep(H->left) +1;
		d2 = deep(H->right) +1;
	}
	return d1>=d2? d1:d2;
}

计算总的节点数和叶子数
//计算总的节点数
int node(tree* H){
	int n = 0;
	if(NULL!=H){
		n = node(H->left)+node(H->right) +1;
	}
	return n;
}
//计算叶子节点
int CountLeaf(tree* H){
	if(NULL==H) return 0;
	if((NULL==H->left)&&(NULL==H->right)){
		return 1;
	}
	return CountLeaf(H->left) + CountLeaf(H->right);
}

全部代码如下
#include <stdio.h>
#include <malloc.h>
typedef  struct Tree tree ;
/*
定义二叉树的结构体
*/
struct Tree{
	int data;
	tree *left;
	tree *right;
};
tree *p[100];
/*
初始化二叉树
*/
tree *initTree(tree* H){
	H = NULL;
	int data = 0;
	printf(" 输入data \n ");
	scanf("%d",&data);
	if(data!=0){
		H = (tree *)malloc(sizeof(tree));
		H->data = data;
		printf(" t data is %d \n",H->data);
		printf(" 请输入左字树data \n");
		H->left = initTree(H->left);
		printf(" 请输入右字树data \n");
		H->right = initTree(H->right);
	}
	return H;
}
/*
先序遍历
*/
void DLR(tree* H){
	if(NULL!=H){
		printf(" data is %5d \n ",H->data);
		DLR(H->left);
		DLR(H->right);
	}
}

/*
中序遍历
*/
void LDR(tree* H){
	if(NULL!=H){
		LDR(H->left);
		printf(" data is %5d \n",H->data);
		LDR(H->right);
	}
}

/*
后序遍历
*/
void LRD(tree* H){
	if(NULL!=H){
		LRD(H->left);
		LRD(H->right);
		printf(" data is %5d \n",H->data);
	}
}

/*
计算树的深度
*/
int deep(tree* H){
	int d1 = 0;
	int d2 = 0;
	if(NULL!=H){
		d1 = deep(H->left) +1;
		d2 = deep(H->right) +1;
	}
	return d1>=d2? d1:d2;
}
//计算总的节点数
int node(tree* H){
	int n = 0;
	if(NULL!=H){
		n = node(H->left)+node(H->right) +1;
	}
	return n;
}
//计算叶子节点
int CountLeaf(tree* H){
	if(NULL==H) return 0;
	if((NULL==H->left)&&(NULL==H->right)){
		return 1;
	}
	return CountLeaf(H->left) + CountLeaf(H->right);
}
void main(){
	tree *H = (tree*)malloc(sizeof(tree)) ;
	 H = initTree(H);
	 printf("DLR : \n");
	 DLR(H);
	 printf("LDR : \n");
	 LDR(H);
	 printf("LRD : \n");
	 LRD(H);
	 printf("\n deep is %5d \n ",deep(H));
	 printf(" CountLeaf is %5d \n",CountLeaf(H));
	 printf(" node number is %5d  \n",node(H));
}


大概就这么多了。想起了在补充吧~~




3)平衡二叉树

特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为3)平衡二叉树
特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为0,-1,1。

3
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

C语言基本数据结构之二(二叉树的三种遍历,节点数以及深度算法)

关于二叉树的定义,网上有比较好的介绍,在这里就简单介绍二叉树的一些性质 二叉树的基本性质 1)二叉树的第i层上至多有 2^(i-1)(i ≥1)个结点; 2)深度为 h 的二叉树中至多含有 2^h –...
  • to_perfect
  • to_perfect
  • 2016-12-05 19:29
  • 2569

数据结构 二叉树的递归算法、前序、中序、后序遍历(c语言实现)

实验目的 1、掌握二叉树的表示与实现。 2、掌握二叉树的定义、创建、遍历等基本操作的实现。 3、熟悉求二叉树深度等递归算法的设计与实现。 实验内容 问题描述:已知二叉树t,分别采用顺序存储结...
  • catkint
  • catkint
  • 2015-12-18 23:08
  • 5517

C++算法之 求二叉树的节点个数、深度、四种遍历方法

//节点的数据结构 class BTree { public: int m_nValue; BTree* m_nLeft; BTree* m_nRight; ...
  • djb100316878
  • djb100316878
  • 2015-01-04 11:42
  • 16126

基本数据结构——二叉树的建立,遍历,求叶子节点,深度计算

/* 新建立一棵二叉树,遍历,查找树的高度,查找树的叶子节点,和总结点数计算距离最远的两个节点。 SQ 2014-04-20 */ #include struct Node{     ...
  • u012606764
  • u012606764
  • 2014-04-20 21:55
  • 1594

【数据结构】二叉树的实现(如:默认成员函数、(叶子)节点数、深度、四种遍历)

二叉树:树的每个节点最多有两个子节点。我们看下它的结构,有二叉链表结构与三叉链表结构,具体结果如我摘自《C++Primer》中的图。650) this.width=650;" src="http://...
  • hanjing_1995
  • hanjing_1995
  • 2016-05-30 17:18
  • 292

数据结构 二叉树三种遍历的非递归算法(背诵版).doc

  • 2008-12-22 15:07
  • 3KB
  • 下载

<数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现

二叉树是数据结构中一种非常重要的结构,熟练的掌握二叉树的创建,遍历是打好编程基础的关键。对于遍历,不能仅仅只掌握递归遍历,还应掌握效率更高地非递归遍历。对于非递归的先序、中序、后序遍历要用到栈(在之前...
  • fzh1900
  • fzh1900
  • 2013-11-02 17:12
  • 3578

数据结构之二叉树 (构造 拷贝构造 以及前序中序后续三种遍历方法)

首先二叉树的节点定义如下: struct BinaryNode {                  BinaryNo...
  • qq_33452263
  • qq_33452263
  • 2016-06-03 10:18
  • 176

数据结构之二叉树(遍历、建立、深度)

转自:http://blog.chinaunix.net/uid-26548237-id-3476141.html 1、二叉树的深度遍历         二叉树的遍历是指从根结点出发,...
  • malizhchxiaozi
  • malizhchxiaozi
  • 2015-03-07 17:49
  • 243

数据结构之二叉树(遍历、建立、深度)

数据结构之二叉树(遍历、建立、深度) 1、二叉树的深度遍历         二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树的所有结点,使得每个结点被访问一次且仅被访问一次。 ...
  • jingjingxujiayou
  • jingjingxujiayou
  • 2014-05-10 21:01
  • 1331
    个人资料
    • 访问:30086次
    • 积分:466
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    最新评论