目录
前序打印图解:
一个节点是根的同时又是子树
链式二叉树:
首先创建节点
typedef char DataType;
typedef struct Node
{
DataType data;
struct Node* left;
struct Node* right;
}BTNode;
BTNode* Buynode(DataType x)
{
BTNode* node=(BTNode*)malloc(sizeof(BTNode));
if(node==NULL)
{
perror("malloc fail");
return NULL;
}
node->data=x;
node->left=NULL;
node->right=NULL;
return node;
}
把节点互连
BTNode* CreatBinaryTree()
{
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
node1->left = node2;
node1->right = node4;
node2->left = node3;
node4->left = node5;
node4->right = node6;
return node1;
}
这样我们就实现了如图一个二叉树
接着我们实现
前序:
void prevOrder(BTNode* root)
{
root=(BTNode*)malloc(sizeof(BTNode));
if (root == NULL)
{
printf("N");
return;
}
printf("%d ", root->data);
prevOrder(root->left);
prevOrder(root->right);
}
main函数:
int main()
{
BTNode* root = CreatBinaryTree();
prevOrder(root);
printf("\n");
中序:
//中序
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("N ");
return;
}
InOrder(root->left);
printf("%d ", root->data);
InOrder(root->right);
}
后序:
//中序
void BackOrder(BTNode* root)
{
if (root == NULL)
{
printf("N ");
return;
}
BakcOrder(root->left);
BackOrder(root->right);
printf("%d ", root->data);
}
求节点个数
第一种方法:计数法
定义一个size变量,每当有一个节点不为空就size++
countTree(BTNode* root)
{
int size = 0;
if (root == NULL)
{
return;
}
++size;
printf("size个数为:%p %d\n", &size,size);
countTree(root->left);
countTree(root->right);
}
这是因为size是一个局部变量,出了作用域就销毁了,每次都会从0开始
把size定义为静态局部变量:
countTree(BTNode* root)
{
static int size = 0;
if (root == NULL)
{
return;
}
++size;
printf("size个数为:%p %d\n", &size,size);
countTree(root->left);
countTree(root->right);
}
虽然可以得到正确节点个数,但是·有缺点,就是在main函数里不能打印size,因为static是静态的局部变量
把size作为返回值返给main函数打印size:
int countTree(BTNode* root)
{
static int size = 0;
if (root == NULL)
{
return size;
}
++size;
//printf("size个数为:%p %d\n", &size,size);
countTree(root->left);
countTree(root->right);
return size;
}
打印两次size:
printf("size个数为:%d\n", countTree(root));
printf("szie个数为:%d\n", countTree(root));
size第一次为6,第二次为12.这是因为size是static size,但是第二次却没有被置0.怎么在第二次打印的时候把size置0呢?难道要这样吗:
printf("size个数为:%d\n", countTree(root));
int size = 0;
printf("szie个数为:%d\n", countTree(root));
没有用,结果还是一样
这是因为你这里置0的这个int size和上面的static size是两个变量了。
要想置0,我们只能把size用做全局变量:
static int size = 0;
int countTree(BTNode* root)
{
if (root == NULL)
{
return size;
}
++size;
//printf("size个数为:%p %d\n", &size,size);
countTree(root->left);
countTree(root->right);
return size;
}
printf("size个数为:%d\n", countTree(root));
size = 0;
printf("szie个数为:%d\n", countTree(root));
第二种方法:分治法
思路:如果孩子都为空就返回0,如果有一个节点就返回1,然后用递归全部累加起来。
int countTree(BTNode* root)
{
if (root == NULL)
{
return 0;
}
//printf("size个数为:%p %d\n", &size,size);
return countTree(root->left)
+countTree(root->right)
+ 1;
}
int size = countTree(root);
printf("size个数为:%d", size);
也可以简写为:
int countTree(BTNode* root)
{
//
//if (root == NULL)
//{
// return 0;
//}
//printf("size个数为:%p %d\n", &size,size);
return root==NULL ? 0 : countTree(root->left)
+countTree(root->right)+1;
}
画图解析:
向下创建栈的时候并没有连接
然后开始递归,递归就开始返回值,进行连接了
求叶子节点的个数:
思路:因为叶子节点在最下面,所以没有分支,左孩子右孩子都为空
if (root->left == NULL&& root->right==NULL)
{
return 1;
}
然后再用递归累加起来:
int countTree(BTNode* root)
{
if (root == NULL)
{
return 0;
}
if (root->left == NULL&& root->right==NULL)
{
return 1;
}
return countTree(root->left)
+countTree(root->right);
}
求二叉树的高度
假设我们构建一个二叉树
求这个二叉树的高度无非就是求节点个数最多的那个分支的节点个数不同与之前的求节点个数是把所以节点个数累加起来,求高度是把左孩子和右孩子进行比较,谁大谁加1.
左分支:
右分支;
最后谁大把谁+1返回去:
左右都一样,返回哪边都一样:
代码:
int HeighjtTree(BTNode* root)
{
if (root == NULL)
{
return 0;
}
return HeighjtTree(root->left) > HeighjtTree(root->right) ? HeighjtTree(root->left) + 1 : HeighjtTree(root->right) + 1;
}
但是这个代码时间复杂度过高
这是因为没有返回值去接收,每次都要从叶子那里层层往回返。
用返回值接收一下:
int HeighjtTree(BTNode* root)
{
if (root == NULL)
{
return 0;
}
int Hle = HeighjtTree(root->left);
int Hri = HeighjtTree(root->right);
return Hle > Hri ? Hle + 1 : Hri + 1;
}
求第k层节点个数
同样还是用递归遍历的方式来求
用递归就要考虑两点:子问题和节数条件
子问题:
假设k=3,那我们就让k从0开始,往下走依次增加,当k=3时就return 1,第三层有几个节点就return几个1
但是这样实际上不行,因为k肯定是要我们传值传过去的,假设我们的k为3,那怎么让它从0开始走呢。
所以我们可以换一种思路,第一层为k=3,往下依次--,当k=1时,那一层的节点个数就是我们要求的
k=3时
k=4时:
结束条件:
第一个就是上面说的k==1,还有一个,就是当root=0时也要有一个返回值。
递归图:
代码:
Kcount(BTNode* root,int k)
{
assert(k>0 );
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return Kcount(root->left, k-1)
+Kcount(root->right, k-1);
}
printf("第k层节点个数为:%d\n", kcount(root,3));//当k为3时