1.为什么创建二叉树时使用二级指针?
C都是值传递,只传指针相当于把外部指针的地址传入了而已,在函数内部你又创建了一个指针,也是指向那个地址,操作完后,其实只是改变了你创建的指针,并未改变外部的指针。
如同这一个函数,并未交换两个值。
你要改变的是指针的地址,那就要用到指针的指针,即二重指针
void change(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
1.有同学问如何终止输入?
输入时必须将所有叶子节点填充,如同ABD##C##EF##H##,ABC##D##E##这样完整的树
二叉树的创建本质上其实就是遍历
先序遍历:跟,左,右
中序遍历:左,跟,右
后序遍历:左,右,跟
层次遍历:从根节点开始,依次往下从左到右
其他的操作不难,大家看看源码即可。
递归实现二叉树并不难
#include<stdio.h>
#include<stdlib.h>
typedef struct binTree {
char data;
struct binTree * left;
struct binTree * right;
}* BinTree, Node;
void createTree(BinTree * tree) {
char ch;
ch = getchar();
if (ch == '#') {
*tree = NULL;
} else {
*tree = (BinTree) malloc (sizeof(Node));
(*tree)->data = ch;
(*tree)->left = NULL;
(*tree)->right = NULL;
createTree(&(*tree)->left);
createTree(&(*tree)->right);
}
}
void preOrder(BinTree tree) {
if (tree) {
printf("%c", tree->data);
preOrder(tree->left);
preOrder(tree->right);
}
}
void midOrder(BinTree tree) {
if (tree) {
midOrder(tree->left);
printf("%c", tree->data);
midOrder(tree->right);
}
}
void postOrder(BinTree tree) {
if (tree) {
postOrder(tree->left);
postOrder(tree->right);
printf("%c", tree->data);
}
}
void insertLeft(BinTree tree, char ch) {
BinTree p, node;
if (!tree) {
printf("树为空\n");
return ;
}
p = tree->left;
node = (BinTree)malloc(sizeof(Node));
node->right = NULL;
node->data = ch;
node->left = p;
tree->left = node;
}
void insertRight(BinTree tree, char ch) {
BinTree p, node;
if (!tree) {
printf("树为空\n");
return ;
}
p = tree->right;
node = (BinTree)malloc(sizeof(Node));
node->data = ch;
node->left = NULL;
node->right = p;
tree->right = node;
}
int countLeaf(BinTree tree) {
if (tree == NULL) {
return 0;
}
if (!(tree->left) && !(tree->right)) {
return 1;
} else {
return countLeaf(tree->left) + countLeaf(tree->right);
}
}
int countNode(BinTree tree) {
if (!tree) {
return 0;
} else {
return countNode(tree->left) + countNode(tree->right) + 1;
}
}
int depthTree(BinTree tree) {
int left, right;
if (!tree) {
return 0;
}
left = depthTree(tree->left);
right = depthTree(tree->right);
return (left > right)?(1+left):(1+right);
}
void printNode(BinTree tree, int level) {
if (!tree || level < 1) {
return ;
}
if (level == 1) {
printf("%c", tree->data);
}
printNode(tree->left, level - 1);
printNode(tree->right, level - 1);
}
void printAtLevel(BinTree tree) {
int depth = depthTree(tree);
int i;
if (!tree) {
printf("树为空");
}
for (i = 1; i <= depth; i++) {
printNode(tree, i);
printf("\n");
}
}
int main(void)
{
BinTree tree;
char ch;
int num;
printf("输入二叉树,#为空:");
createTree(&tree);
printf("1.先序遍历 2.中序遍历 3.后序遍历 4.层次遍历\n");
printf("5.叶子节点数 6.节点数 7.左节点插入 8.右节点插入 9.树深度 10.退出\n");
while (scanf("%d", &num) != EOF && num != 10) {
switch (num) {
case 1:preOrder(tree);putchar('\n');break;
case 2:midOrder(tree);putchar('\n');break;
case 3:postOrder(tree);putchar('\n');break;
case 4:printAtLevel(tree);putchar('\n');break;
case 5:printf("叶子节点数:%d\n", countLeaf(tree));break;
case 6:printf("节点数:%d\n", countNode(tree));break;
case 7:printf("请输入插入节点:");getchar();scanf("%c", &ch);insertLeft(tree, ch);
printf("插入成功\n\n");break;
case 8:printf("请输入插入节点:");getchar();scanf("%c", &ch);insertRight(tree, ch);
printf("插入成功\n\n");break;
case 9:printf("树深度为:%d\n\n", depthTree(tree));break;
default:printf("请输入合法操作!\n");break;
}
}
return 0;
}