二叉树是一种常见的树状数据结构,它由结点的有限集合组成。一个二叉树要么是空集,被称为空二叉树,要么由一个根结点和两棵不相交的子树组成,分别称为左子树和右子树。每个结点最多有两个子结点,分别称为左子结点和右子结点。
二叉树的顺序存储是指将二叉树中所有结点按层次顺序存放在一块地址连续的存储空间中,详见:
【数据结构】树与二叉树(五):二叉树的顺序存储(初始化,插入结点,获取父节点、左右子节点等)
二叉树的链接存储系指二叉树诸结点被随机存放在内存空间中,结点之间的关系用指针说明。在链式存储中,每个二叉树结点都包含三个域:数据域(Data)、左指针域(Left)和右指针域(Right),用于存储结点的信息和指向子结点的指针,详见:
【数据结构】树与二叉树(六):二叉树的链式存储
【数据结构】树与二叉树(七):二叉树的遍历(先序、中序、后序及其C语言实现)
【数据结构】树与二叉树(八):二叉树的中序遍历(非递归算法NIO)
【数据结构】树与二叉树(九):二叉树的后序遍历(非递归算法NPO)
【数据结构】树与二叉树(十):二叉树的先序遍历(非递归算法NPO)
【数据结构】树与二叉树(十一):二叉树的层次遍历(算法LevelOrder)
由二叉树的遍历,很容易想到用遍历方法去创建二叉树,我们考虑从先根遍历思想出发来构造二叉树。
方法:输入当前被创建结点的数据域的值,如果不空,申请空间用指针指向,然后对数据域进行赋值,再递归对该结点的左右指针域进行赋值,这就是先根创建过程。当输入为空,则算法返回一个空指针(即空树。递归出口)。
【数据结构】树与二叉树(十二):二叉树的递归创建(算法CBT)
设二叉树有n个结点,算法CopyTree中,每个结点都要进行1次复制,即复制操作要执行n次,每次复制都是常数级的操作,因此算法CopyTree的时间复杂度为O(n)。
struct Node* CopyTree(struct Node* t) {
if (t == NULL) {
return NULL;
}
struct Node* p = createNode('\0'); // 创建新结点
struct Node* newlptr = NULL; // 初始化左指针
struct Node* newrptr = NULL; // 初始化右指针
// 复制左子树
if (t->left != NULL) {
newlptr = CopyTree(t->left);
}
// 复制右子树
if (t->right != NULL) {
newrptr = CopyTree(t->right);
}
// 复制数据和指针
p->data = t->data;
p->left = newlptr;
p->right = newrptr;
return p;
}
#include
#include
// 二叉树结点的定义
struct Node {
char data;
struct Node* left;
struct Node* right;
};
// 创建新结点
struct Node* createNode(char data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed!\n");
exit(1);
}
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// 复制二叉树
struct Node* CopyTree(struct Node* t) {
if (t == NULL) {
return NULL;
}
struct Node* p = createNode('\0'); // 创建新结点
struct Node* newlptr = NULL; // 初始化左指针
struct Node* newrptr = NULL; // 初始化右指针
// 复制左子树
if (t->left != NULL) {
newlptr = CopyTree(t->left);
}
// 复制右子树
if (t->right != NULL) {
newrptr = CopyTree(t->right);
}
// 复制数据和指针
p->data = t->data;
p->left = newlptr;
p->right = newrptr;
return p;
}
// 中序遍历二叉树
void inorderTraversal(struct Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%c ", root->data);
inorderTraversal(root->right);
}
}
struct Node* CBT(char data[], int* index, char tostop) {
char ch = data[(*index)++];
if (ch == tostop) {
return NULL;
} else {
struct Node* t = createNode(ch);
t->left = CBT(data, index, tostop);
t->right = CBT(data, index, tostop);
return t;
}
}
int main() {
// 创建一棵二叉树
char tostop = '#';
char input_data[] = {'a', 'b', 'd', '#', '#', 'e', 'f', '#', '#', 'g', '#', '#', 'c', '#', '#'};
int index = 0;
struct Node* original = CBT(input_data, &index, tostop);
// 复制二叉树
struct Node* copy = CopyTree(original);
// 中序遍历并输出原始二叉树
printf("Original Inorder Traversal: ");
inorderTraversal(original);
printf("\n");
// 中序遍历并输出复制后的二叉树
printf(" Copied Inorder Traversal: ");
inorderTraversal(copy);
printf("\n");
return 0;
}