数据结构-二叉树

二叉树

  • 1.基本概念
    可以定义为结点的有限集合,这个集合可以为空集,或者由一个称为根的节点,
  • 2.基本形态
    1、空树
    2、只有一个根结点
    3、有根结点和非空左子树
    4、有根结点和非空右子树
    5、有根结点且左右子树非空
  • 3.相关概念
    父结点:若x是y的前驱,y是x的后继,则称x为y的父结点
    叶子结点:左右子树均为空二叉树的结点称为叶子结点
    层次:规定根的层数为0,其他结点的层数等于父结点的层数加1
    深度:二叉树结点的最大层数称为二叉树的高度
  • 4.特殊的二叉树
    1、满二叉树:若一个二叉树的任何结点都是树叶或者都有两个非空子树,则称这种二叉树为满二叉树
    2、完全二叉树:若一个二叉树中,只有最下面两层的结点的子树个数小于2,其余各层结点都等于2,并且最下面一层的结点都是集中在该层的最左边。若设二叉树的深度为h,除第h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
  • 5.二叉树的周游
    1、先根次序周游:若二叉树非空,则先访问根,然后按先根次序访问左子树,最后再右子树
//递归算法:
void pre_order(pNode root, void(*func)(pNode node))
{
    if (root == NULL)
    {
        return ;
    }
    func(root);
    pre_order(root->left,func);
    pre_order(root->right,func);
}
//非递归算法:先将根结点压入栈中,然后取栈头元素进行访问,先压入栈头元素的右子树,再压入栈头元素的左子树
void npre_order(pNode root)
{
	STACK *s = create_stack();
	if(root == NULL) return ;
	pNode c = root;
	push(s,c);
	while( isEmptyStack(s) != 0)
	{
		c = top(s);
		pop(s);
		if(c != NULL)
		{
			printf("%d-",c->data);
			push(s,c->right);
			push(s,c->left);
		}
	}
	destroy_stack(&s);
	printf("\n");
}
2、中根次序周游:若二叉树非空,则周游左子树,再访问根,最后再访问右子树
//递归算法:
void mid_order(pNode root, void(*func)(pNode node))
{
    if (root == NULL)
    {
        return ;
    }
    mid_order(root->left, func);
    func(root);
    mid_order(root->right,func);
}
//非递归算法
void nmid_order(pNode root)
{
	STACK *s = create_stack();
	pNode c = root;
	if(c == NULL) return;
	do
	{
		while(c != NULL)
		{
			push(s,c);
			c = c->left;
		}
		c = top(s);
		pop(s);
		printf("%d-",c->data);
		c = c->right;
	}while(c != NULL || isEmptyStack(s) != 0);
	destroy_stack(&s);
	printf("\n");
}
3、后根次序周游:若二叉树非空,则先周游左子树,再周游右子树,最后访问根
//递归算法:
void back_order(pNode root, void(*func)(pNode node))
{
    if (root == NULL)
    {
        return ;
    }
    back_order(root->left,func);
    back_order(root->right,func);
    func(root);
}
//非递归算法:
void nback_order(pNode root)
{
	STACK *s = create_stack();
	pNode c = root;
	pNode cc;
	while(c != NULL || isEmptyStack(s) != 0)
	{
		while(c != NULL)
		{
			push(s,c);
			cc = c->right;
			c = c->left;
			if(c == NULL) c = cc;
		}
		c = top(s);
		pop(s);
		printf("%d-",c->data);
		if(isEmptyStack(s) != 0 && top(s)->left == c)
		{
			c = top(s)->right;
		}
		else c = NULL;
	}
	destroy_stack(&s);
	printf("\n");
}

4、层次周游(广度周游):逐层从左到右周游
通过队列,先加入根结点;然后访问队头元素;若队头有子树,则先加入左子树至队尾,再加入右子树;队头元素出队,循环至队列为空;

void level_order(pNode root)
{
	QUEUE *q = create_queue();
	if(root == NULL) return;
	pNode c = root;
	pNode cc;
	add_queue(q,c);
	while( isEmptyQueue(q) != 0 )
	{
		c = frontQueue(q);
		printf("%d-",c->data);
		del_queue(q);
		cc = c->left;
		if(cc != NULL) add_queue(q,cc);
		cc = c->right;
		if(cc != NULL) add_queue(q,cc);
	}
	destroy_queue(&q);
	printf("\n");
}
  • 6.二叉树的打印
void print_tree(pNode root,int ident,int depth[])
{
	if(ident > 0)
	{
		for(int i = 0; i < ident - 1; ++i)
        {
            printf(depth[i] ? "│   " : "    ");
        }
        printf(depth[ident-1] ? "├── " : "└── ");
	}
	if(! root)
    {
        printf("(null)\n");
        return;
    }

    printf("%d\n", root->data);
    if(!root->left && !root->right)
    {
        return;
    }

    depth[ident] = 1;
    print_tree(root->left, ident + 1,depth);
    depth[ident] = 0;
    print_tree(root->right, ident + 1,depth);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值