【C/C++】【数据结构】二叉树的基本操作

二叉树的基本操作

 按前辈们的说法,在嵌入式的开发中并不用得到二叉树。在次就仅仅对二叉树的基本操作作简单介绍。

二叉树性质 

(1)第 i 层最多有 2^(i-1) 个节点。

(2)深度为 k 的二叉树至多有 2^k - 1 个节点。

(3)若一个二叉树终端节点个数为 n,度为 2 的节点个数为 m,则有 n = m+1。

(4)有 n 个节点的完全二叉树深度为 log2(n) + 1。

(5)如果对一颗有 n 个节点的二叉树的节点按层序编号,对任一节点:

         * 如果 i = 1, 则节点 i 是二叉树的根,无双亲。

           如果 i > 1, 则某节点的双亲是 i / 2

         * 如果 2i > n,则节点 i 无左子树,否则左子树是 2i 。

         * 如果 2i+1 > n,则节点 i 无右子树,否则右子树是 2i 。

二叉树遍历

二叉树有三种遍历方式,分别为先序遍历、中序遍历、后序遍历

先序遍历:

        (1)先访问根节点。

        (2)再访问左子树。

        (3)最后访问右子树。

中序遍历:

        (1)先访问左子树。

        (2)再访问根节点。

        (3)最后访问右子树。

后序遍历:

        (1)先访问左子树。

        (2)再访问右子树。

        (3)最后访问根节点。

比如如下的二叉树

先序遍历结果为    ABCDEFG

中序遍历结果为    CBEDAFG

后序遍历结果为    CEDBGFA

代码展示

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//二叉树节点信息
struct binarytreenode
{
	int  data;
	struct binarytreenode *lchild;//左子树
	struct binarytreenode *rchild;//右子树
};
typedef struct binarytreenode BiTNode;

void print( int e)
{
	printf(" %2d", e);
}


//二叉树创建
BiTNode *CreatTree( int *a)
{
	int i;
	BiTNode *pNode[11] = {0};

	for ( i = 0; i < 10; i++)
	{
		pNode[i] = (BiTNode *) malloc(sizeof(BiTNode));

		if ( NULL == pNode[i])
		{
			printf("malloc error!\n");
			exit(1);
		}

		pNode[i]->lchild = NULL;

		pNode[i]->rchild = NULL;

		pNode[i]->data = a[i];
	}

	for ( i = 0; i < 10/2; i++)
	{
		pNode[i]->lchild = pNode[ 2 * (i + 1) - 1];

		pNode[i]->rchild = pNode[ 2 * (i + 1) + 1 - 1];
	}

	return pNode[0];
}

//先序遍历
int  PreOrderTraverse( BiTNode *root, void (*visit)(int) )
{
	if ( NULL == root)
	{
		return 1;
	}

	(*visit)(root->data);

	if ( PreOrderTraverse(root->lchild, visit) )
	{
		if ( PreOrderTraverse(root->rchild, visit) )
		{
			return 1;
		}
	}

	return 0;

}

//中序遍历
int MidOrderTraverse( BiTNode *root, void (*visit)(int) )
{
	if ( NULL == root)
	{
		return 1;
	}

	if ( MidOrderTraverse( root->lchild, visit) )
	{
		(*visit)(root->data);

		if ( MidOrderTraverse( root->rchild, visit) )
		{
			return 1;
		}
	}

	return 0;
}


//后序遍历
int PostOrderTraverse( BiTNode *root, void (*visit)(int) )
{
	if ( NULL == root)
	{
		return 1;
	}

	if ( PostOrderTraverse( root->lchild, visit) )
	{
		if ( PostOrderTraverse( root->rchild, visit) )
		{
			(*visit)(root->data);

			return 1;
		}
	}

	return 0;
}

//先序非递归遍历
int PreOrderNonRecursive( BiTNode *root, void (*visit)(int))
{
	if ( NULL == root)
	{
		return 1;
	}

	LinkStack *Stack = NULL;
	int ret = 0;

	ret = StackInit(Stack);
	if( FAILURE == ret)
	{
		printf("StackInit error;\n");
	}

}


int main()
{
	int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	BiTNode *root = NULL;

	root = CreatTree(a);

	PreOrderTraverse( root, print);

	printf("\n");

	MidOrderTraverse( root, print);

	printf("\n");

	PostOrderTraverse( root, print);

	printf("\n");
	return 0;
}

/***运行结果***/ 

  1  2  4  8  9  5 10  3  6  7
  8  4  9  2 10  5  1  6  3  7
  8  9  4 10  5  2  6  7  3  1

 

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: C/C++ 是应用广泛的编程语言,其在数据结构应用方面也十分重要。面试中相关的 C/C++ 数据结构问题主要围绕数组、链表、二叉树和图等方面。以下是一些常见问题及其解答: 1. 如何反转一个单向链表? 答:可以使用三个指针来实现:cur 代表当前节点,pre 代表上一个节点,next 代表下一个节点。每次遍历时,将 cur 的 next 指向 pre,然后将三个指针分别向后移动即可。 2. 如何判断两个链表是否相交,并找出相交的点? 答:可以分别遍历两个链表,得到各自的长度。然后让长的链表先走 n 步,使得两个链表剩余的长度相等。接下来同时遍历两个链表,比较节点是否相同即可找出相交的点。 3. 如何判断一个二叉树是否为平衡二叉树? 答:可以计算每个节点的左右子树深度差,如果任何一个节点的深度差大于1,则此树不是平衡二叉树。可以使用递归实现,每次计算当前节点的深度,然后递归判断其左右子树是否平衡。 4. 如何实现图的深度优先搜索(DFS)和广度优先搜索(BFS)算法? 答:DFS 可以使用递归实现。从某个节点开始,逐个访问其未被访问的邻接节点,并将其标记为已访问。然后对每个未被访问的邻接节点递归调用 DFS 函数。BFS 可以使用队列实现。从某个节点开始,将其加入队列,并标记为已访问。然后从队列中弹出节点,并访问其所有未被访问的邻接节点,并将其加入队列中。重复此过程直到队列为空。 以上是一些常见的 C/C++ 数据结构面试问题及其解答。在面试中,除了掌握相关算法和数据结构知识外,还需多做练习和积累经验,才能更好地应对各种面试问题。 ### 回答2: C语言是一种用于编写系统级程序的高级编程语言,具有简单、高效、灵活等特点,是许多操作系统、编译器等软件的首选语言,也是许多企业在进行面试时重点考察的技能。在C/C++数据结构面试题中,经常会涉及到各种数据结构相关的算法和应用,测试面试者的算法思维能力和实现能力。 其中,常见的数据结构包括链表、栈和队列、二叉树、搜索树、哈希表等。在面试时,会常常涉及代码设计和实现,比如实现链表的插入、删除、查找操作,实现二叉树的遍历、查找操作等。 此外,在数据结构面试中,还经常涉及排序和查找算法,如冒泡排序、快速排序、归并排序、二分查找、哈希查找等。同时,面试者还需要解决一些较为复杂的算法问题,如图的最短路径问题,最小生成树问题等。 总之,C/C++数据结构面试题涵盖了运用数据结构的各种算法和实现方法,需要面试者具备扎实的编程基础和算法思维能力。在备战面试时,可以多做练习,熟悉常用的数据结构和算法,提高理解和实现能力,从而更好地应对面试挑战。 ### 回答3: 面试过程中常见的C/C++数据结构面试题有很多。以下就介绍几个常见的题目并给出解答。 1. 求两个有序数组的中位数 题目描述:给定两个升序排列的整形数组,长度分别为m和n。实现一个函数,找出它们合并后的中位数。时间复杂度为log(m+n)。 解答:这个问题可以使用二分法求解。首先,我们可以在两个数组中分别选出所谓的中间位置,即(i+j)/2和(k+l+1)/2,其中i和j分别是数组A的起始和结束位置,k和l分别是数组B的起始和结束位置。判断A[i+(j-i)/2]和B[k+(l-k)/2]的大小,如果A的中间元素小于B的中间元素,则中位数必定出现在A的右半部分以及B的左半部分;反之,则必定出现在A的左半部分以及B的右半部分。以此类推,每一次都可以删去A或B的一半,从而达到对数级别的时间复杂度。 2. 堆排序 题目描述:对一个长度为n的数组进行排序,时间复杂度为O(nlogn)。 解答:堆排序是一种常用的排序算法,在面试中也经常被考察。堆排序的具体过程是首先将数组构建成一个最大堆或最小堆,然后不断将堆顶元素与最后一个元素交换,并将最后一个元素从堆中剔除。这样,每次剔除后,堆都会重新调整,使得剩下的元素仍然保持堆的性质,直到堆中只剩下一个元素为止。 3. 链表反转 题目描述:反转一个单向链表,例如给定一个链表: 1->2->3->4->5, 反转后的链表为: 5->4->3->2->1。 解答:链表反转题目也是非常常见,其思路也比较简单。遍历链表,将当前节点的next指针指向前一个节点,同时记录当前节点和前一个节点,直至遍历到链表末尾。 以上这三个问题分别从二分法、堆排序和链表三个方面介绍了常见的C/C++数据结构面试题,希望能帮助面试者更好地准备面试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值