树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树的原因是它看起来像一棵倒挂着的树,也就是说它是根朝上,而叶朝下的。
一棵二叉树是结点的一个有限集合,该集合为空或者由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
二叉树的顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实使用中只有堆才会使用数组来存储,二叉树顺序存储在物理存储上是一个数组,在逻辑上则是一颗二叉树。
二叉树的链式存储结构是指用链表来表示一棵二叉树,即用链来表示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点的左孩子和右孩子所在的链结点的存储地址。
void BinaryTreePrevOrder(BTNode* root)
{
//可以不加下面的if语句及其内容,只是节点为空时不打印东西而已
if (root == NULL)
{
printf("# ");
return;
}
printf("%c ", root->data);
//可以用下面的式子替代上面的式子
//putchar(root->_data);
BinaryTreePrevOrder(root->left);
BinaryTreePrevOrder(root->right);
}
中序与后续的遍历与前序遍历的代码差不多,只需要修改一下最后面的三个式子而已。
函数的参数参见下方二叉树创建函数中的root,将 BTNode* 类型的root作为实参传递即可。
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
int main()
{
char str[] = "ABD##E#H##CF##G##";
int i = 0;
int size = sizeof(str) / sizeof(str[0]);
BTNode* root = BinaryTreeCreate(str, size, &i);
}
BTNode *BinaryTreeCreate(BTDataType * src, int n, int* pi)
{
if (*pi >= n || src[*pi] == '#')
{
(*pi)++;
return NULL;
}
BTNode * cur = (BTNode *)malloc(sizeof(BTNode));
cur->data = src[*pi];
(*pi)++;
cur->left = BinaryTreeCreate(src, n, pi);
cur->right = BinaryTreeCreate(src, n, pi);
return cur;
}
void BinaryTreeDestory(BTNode** root)
{
if (*root)
{
BinaryTreeDestory(&(*root)->left);
BinaryTreeDestory(&(*root)->right);
free(*root);
*root = NULL;
}
}
进行函数调用的参数需为 &(*root)->_left ,不能去掉’&',否则,即传的实参是 (*root)->left 时,传的只是一级指针,而下一个递归函数的形参只是这个一级指针的临时拷贝,编译器会在内存中另外开辟一块空间进行存储,而对这个形参进行修改,不会影响到实参,即节点本身。
设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
void BinaryTreeLevelOrder(BTNode* root)
{
Queue qu;
BTNode* cur;
QueueInit(&qu);
QueuePush(&qu, root);
while (!QueueEmpty(&qu))
{
cur = QueueFront(&qu);
putchar(cur->data);
if (cur->left)
{
QueuePush(&qu, cur->left);
}
if (cur->right)
{
QueuePush(&qu, cur->right);
}
QueuePop(&qu);
}
QueueDestroy(&qu);
}
本文到这里就结束了,如有错误或者不清楚的地方欢迎评论或者私信
如果觉得写得不错,请务必一键三连