8月27日笔记数据结构树

1.树的概念
    树是一种非线性结构(一对多的关系),一组数据除了一个节点(根节点,没有前驱节点)外,
    其余的任意节点有且仅有零节点或多个节点,我们把这种特殊的关系,称为树状关系,俗称一对多的关系
    
2.生活中如何描述树状关系
    公司的人员架构 家族的族谱 学校的组织
    
3.树的逻辑关系:
    树是由若干个节点组成的分支,每个节点都有可能组成一颗树
    1.节点的: 节点拥有的子树的数量,称之为该节点的度,度为0的节点称为叶子节点或者终端节点
                  度不为0的节点称为分支节点或者是非终端节点

        n1,n1,n2
    2.节点的层次
        从树根开始,根为第一层,根的孩子(子节点)为第二层,树中的节点最大的层次为树的深度或者高度
        
4.二叉树
    二叉树它的特性是:每个节点最多只能挂两个节点,即二叉树中不存在度大于2的节点
        并且二叉树有左右之分,分为左子树和右子树,切记,逻辑顺序不能颠倒
        
    二叉树的特性
        1.空二叉树
        2.只有一个根节点的二叉树
        3只有左子树
        4.只有右子树
        5.完全二叉树
        
5.二叉树的性质
    1.在二叉树的第i层,最多有2^(i-1)个节点
    

    2.深度为k的二叉树最多有2^k - 1个节点
    
    3.对于任意一棵二叉树,如果其终端节点数为n0,度为2的节点为n2,则有 n2 = n0-1
        
    4.满二叉树 :一棵树深度为k,且具有满足2^k - 1,我们把它称为满二叉树,就是不能再插入任何节点
    
    5.完全二叉树,要满足以下两个条件:
        1.除去最后一层,则此树必定是满二叉树
        2.最后一层的节点必须是依次从左往右编排,如果左边不排满,右边不能排
        3.完全二叉树总结  : 完全二叉树是从内存的角度考量的,主要是为了节约空间 
            满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树
    
    练习 : 节点数为699的完全二叉树的叶子节点的数量是多少?
            提示 (1) 套用 n2 = n0 - 1的公式
                (2) 节点数为奇数的完全二叉树不存在度为1(n1)的节点 即n1 = 0
                
            1.699 = n0+n1+n2  // 699 = 度为0的节点+度为1的节点+度为2的节点
            2.n2 = n0-1 ==》 n0 = n2 + 1
            3.699 = 2n2+1+n1 又因为 n1为0 ==》 699 = 2n2+1
            4.n2 = 349
            5.因为 n2 = n0-1 所以  n0 = n2+1 = 349+1 = 350
            
6.二叉树的存储
    存储结构: 既可以保存元素有保存的元素与元素之间的关系
        1.顺序存储(一块连续的空间),需要将此树抽象成完全二叉树才能存放,否则无法描述他们之间的逻辑关系,弊端是浪费空间
            #define MAX_LEN 1024 
            dataTpye BinTree[MAX_LEN];
            
        2.链式存储
            struct BiTNode
            {
                dataTpye data; // 数据域
                struct BiTNode *lchild,*rchild;// 指针域,指向下一个节点
            };            
            
7.二叉树的遍历        
    如何按某条搜索路径进行查找对应的节点
        1.先序遍历 : 根  左  右
        2.中序遍历 :  左  根  右
        3.后序遍历 :  左  右   根
    1.先序  中序  后序遍历是以根节点为参考点
    2.若"左"和"右"不是终端节点,则会进入递归遍历,每次都是访问"根",遇到节点为空的时候则进行回退(回溯)
        
    
8.二叉排序树又名二叉查找树
    二叉排序树要么是空树,要么需要满足以下条件:
    1.如果它们的左子树不为空,则左子树的数值一定比根节点的数值小
    2.如果它们的右子树不为空,则右子树的数值一定比根节点的数值大
    3.左子树或右子树的数值一定不能和根节点相等
    
9.二叉查找树程序实现:

    typedef  char dataTpye;
    struct struct BiTNode
    {
        dataTpye data; // 数据域
        struct BiTNode *lchild,*rchild;// 指针域,指向下一个节点
    };
    
    // 将节点插入到二叉树中
    struct BiTNode *Insert_Node(struct BiTNode *root,dataTpye data);
    
    //遍历节点
    // 先序遍历,中序遍历,后序遍历


具体代码BinarySortTree.c

#include <stdio.h>
#include <stdlib.h>
//-----------------------------
typedef  char dataTpye;
//-----------------------------
struct BiTNode
{
	dataTpye data; // 数据域
	struct BiTNode *lchild,*rchild;// 指针域,指向下一个节点
};
//-----------------------------
// 实现二叉排序树的数据插入
struct BiTNode *Insert_Node(struct BiTNode *root,dataTpye data)
{
	// 定义遍历指针查找需要插入的位置
	struct BiTNode *p = root;
	
	// 创建新节点
	struct BiTNode *pnew = malloc(sizeof(struct BiTNode));
	if(pnew == NULL)
	{
		return NULL;
	}
	pnew->data = data;
	pnew->lchild = NULL;
	pnew->rchild = NULL;
	
	// 如果二叉树没有节点
	if(root == NULL) // 从无到有
	{
		root = pnew;
	}
	else // 二叉树有节点
	{
		// 遍历查找位置
		while(p)
		{
			// 如果data的值大于根节点则,则右插
			if(data > p->data)
			{
				if(p->rchild == NULL)
				{
					p->rchild = pnew;
					break; // 插完就跑
				}
				else // 继续往右找
				{
					p = p->rchild;
				}
			}
			else if(data < p->data) // 左插
			{
				if(p->lchild == NULL)
				{
					p->lchild = pnew;
					break; // 插完就跑
				}
				else // 继续往左找
				{
					p = p->lchild;
				}
			}
			else // data与根节点相等表示异常
			{
				printf("insert value error!\n");
				break;
			}
		}
	}
	
	return root;
}
//-----------------------------
/* 先序实现遍历二叉排序树 */
void pre_order(struct BiTNode *root)
{
	// 递归实现
	// 退出条件
	if(root == NULL)
	{
		return ;
	}
	
	// 根 左 右 
	// 根
	printf("%c ",root->data);
	// 左
	pre_order(root->lchild);
	// 右
	pre_order(root->rchild);
}

/* 中序实现遍历二叉排序树 */
void mid_order(struct BiTNode *root)
{
	// 递归实现
	// 退出条件
	if(root == NULL)
	{
		return ;
	}
	
	// 左 根 右 
	// 左
	mid_order(root->lchild);
	// 根
	printf("%c ",root->data);
	// 右
	mid_order(root->rchild);
}
//-----------------------------
/* 后序实现遍历二叉排序树 */
void last_order(struct BiTNode *root)
{
	// 递归实现
	// 退出条件
	if(root == NULL)
	{
		return ;
	}
	
	// 左 右 根

	// 左
	last_order(root->lchild);
	// 右
	last_order(root->rchild);
	//根
	printf("%c ",root->data);
}
//-----------------------------
/* 创建二叉排序树 按回车结束 */
struct BiTNode *create_sort_tree()
{
	struct BiTNode *root = NULL;
	// 不断的创建节点并插入到树中,按回车键结束
	while(1)
	{
		dataTpye data = getchar();
		if(data == '\n')
			break; // 输入回车键跑路
		
		// 将数据插入到树中,root因为是局部变量所以每次都得要跟一下树的状态
		root = Insert_Node(root,data);
	}
	
	return root;
}
//-----------------------------
int main()
{
	// 创建二叉排序树
	struct BiTNode *root = create_sort_tree();
	
	// 通过先序遍历打印结果
	//pre_order(root);
	
	// 中序遍历
	//mid_order(root);
	
	// 后序遍历
	last_order(root);
	
	printf("\n");
	
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值