前文讲了二叉树的创建,递归遍历和完全基于栈的非递归遍历,叶子节点、树高等计算方法。以下主要分析二叉树的复制、销毁、以及但含有递归思想的非递归遍历方法。
1 二叉树节点构建,与前文一致,不再分析
typedef struct Tree //二叉树
{
void *data; //数据域,void* 可保存任意数据类型的地址
struct Tree *left; //左子节点指针
struct Tree *right; //右子节点指针
} Tree;
Tree *createTreeNode(void *data) //根据数据域data创建节点
{
Tree *node = (Tree *)malloc(sizeof(Tree)); //在堆区申请内存
node->data = data;
node->left = NULL;
node->right = NULL;
}
2 二叉树的复制
Tree *copyTree(Tree *root) //二叉树copy
{
if (root == NULL)
return NULL;
Tree *copyRoot = root;//本质为前序遍历的递归方法
copyRoot->left = copyTree(root->left);
copyRoot->right = copyTree(root->right);
return copyRoot;
}
3 二叉树的中序遍历(非递归版本)
void inOrderList(Tree *root)//二叉树的非递归遍历
{
if (root == NULL)
return;
Tree **treeStack = (Tree **)malloc(sizeof(Tree *)); //向堆区申请内存
int top = 0;
/*** //上面两行代码,其实就是栈的构建,及初始化过程
* typedef struct Stack//与这样构建的栈是一样的
* {
* void *data[MAX];
* int top;
* }*/
while (root != NULL || top > 0)
{
while (root != NULL) //向栈中压入root及所有的左子结点
{
treeStack[top++] = root; //栈的大小top实时更新
root = root->left;
}//这段while结束,栈顶就是最后一个root的最left节点,对应索引为top-1,栈大小为size
root = treeStack[--top]; // pop出来栈顶元素
Student *stu = (Student *)root->data;
printf("{id:%d,name:%s}\t", stu->age, stu->name);
root = root->right;
}
}
4 二叉树的释放
void freeTree(Tree *root)
{
if (root == NULL)
return;
freeTree(root->left);
freeTree(root->right);
free(root);
}
5 函数测试与运行结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
Student stu[7] = {
{1, "jakes1"},
{2, "jakes2"},
{3, "jakes3"},
{4, "jakes4"},
{5, "jakes5"},
{6, "jakes6"},
{7, "jakes7"},
};
Tree *root = (Tree *)malloc(sizeof(Tree));
root->data = &stu[0];
root->left = createTreeNode(&stu[1]);
root->right = createTreeNode(&stu[2]);
root->left->left = createTreeNode(&stu[3]);
root->left->left->right = createTreeNode(&stu[6]);
root->right->left = createTreeNode(&stu[4]);
root->right->right = createTreeNode(&stu[5]);
printf("原树-中序遍历:");
inOrderList(root);
Tree *copyroot = copyTree(root);
printf("\ncopy树-中序遍历:");
inOrderList(copyroot);
return 0;
}
main函数中构建的树如下:(同前文)
运行结果如下
点击关注不迷路