(eden)排序二叉树VS二叉树链表
排序二叉树
Description:
题目大意:请完成下面四个函数的定义(在tree.h文件中),使整个程序能够利用排序二叉树的结构对输入的数(不会出现相同的数),进行排序输出。节点的结构体在下面已给出,这个二叉树的特征是,左子数的值肯定比父节点小,右子树的值肯定比父节点的大。要求大家按照这个结构特征去构建二叉树,最后中序遍历输出就是我们要求的升序输出。
树的节点结构体为:
typedef struct Node {
struct Node *left;
struct Node *right;
int value;
} Node;
中序遍历这个二叉树,按照升序输出,每个数之间有一个空格,最后一个数后也有一个空格。
void traverse_tree_inorder(Node *p);
回收建立二叉树时开辟的内存空间,提示类似后序遍历。
void recycle_nodes(Node *p);
将一个值为value的数插入到这个树中,但是要注意,需要插到那个地方,按照排序二叉树的要求来。
void insert_node(Node *p, int value);
初始化根节点的值。
Node* init_root(int value);
输入示例:
5
23 3 53 333 2
输出示例:
2 3 23 53 333 (最后一个数后有空格)
前置知识要求:数据结构二叉树,二叉树的中序遍历和后序遍历,递归函数设计,指针的使用,结构体。
知识介绍:
先序遍历:对一棵二叉树的前序遍历,先访问根结点,再访问左子树,然后访问右子树。
void preorder(Treenode *p) {
if (p!=NULL){
visit(p);
preorder(p->left);
preorder(p->right);
}
}
中序遍历:对一棵二叉树的中序遍历,先访问左子树,再访问根结点,然后访问右子树。
void inorder(Treenode *p) {
if (p!=NULL){
inorder(p->left);
visit(p);
inorder(p->right);
}
}
后序遍历:对一棵二叉树的后序遍历,先访问左子树,再访问右子树,然后访问根结点。
void postorder(Treenode *p) {
if (p!=NULL){
postorder(p->left);
postorder(p->right);
visit(p);
}
}
Hint:
代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define MAXI 50 4 typedef struct Node { 5 6 struct Node *left; 7 8 struct Node *right; 9 10 int value; 11 12 } Node; 13 14 void traverse_tree_inorder(Node *p) { 15 if (p -> left != NULL) { 16 traverse_tree_inorder(p -> left); 17 } 18 printf("%d ", p -> value); 19 if (p -> right != NULL) { 20 traverse_tree_inorder(p -> right); 21 } 22 } 23 void recycle_nodes(Node *p) { 24 Node* que[50]; 25 que[0] = p; 26 int head = 0; 27 int tail = 1; 28 while (head != tail) { 29 if (que[head]->left != NULL) { 30 que[tail] = que[head]->left; 31 tail = (tail + 1) % MAXI; 32 } 33 if (que[head]->right != NULL) { 34 que[tail] = que[head]->right; 35 tail = (tail + 1) % MAXI; 36 } 37 free(que[head]); 38 head = (head + 1) % MAXI; 39 } 40 } 41 void insert_node(Node *p, int value) { 42 Node* q; 43 int t = 0; 44 while (p != NULL) { 45 q = p; 46 if (value <= (p -> value)) { 47 p = p -> left; 48 t = 1; 49 } else { 50 p = p -> right; 51 t = 2; 52 } 53 } 54 p = (Node*)malloc(sizeof(Node));//in the eden,there should be 隐形类型转换 55 p -> value = value; 56 p -> left = NULL; 57 p -> right = NULL; 58 if (t == 1) { 59 q -> left = p; 60 } else { 61 q -> right = p; 62 } 63 } 64 Node* init_root(int value) { 65 Node* p = (Node*)malloc(sizeof(Node));//in the eden,(Node*)is not needed 66 p -> value = value; 67 p -> left = NULL; 68 p -> right = NULL; 69 return p; 70 } 71 int main() { 72 int node_num, i = 0, temp; 73 Node *root = NULL; 74 scanf("%d", &node_num); 75 while (i < node_num) { 76 scanf("%d", &temp); 77 if (i == 0) root = init_root(temp); 78 else insert_node(root, temp); 79 i++; 80 } 81 traverse_tree_inorder(root); 82 printf("\n"); 83 recycle_nodes(root); 84 return 0; 85 }
二叉树链表
Description:
使用链表实现二叉树的构造并完成中序遍历。
首先在头文件中定义结点结构体如下:
typedef struct node {
int x;
struct node* left;
struct node* right;
} BN;
其次要实现两个函数,函数buildTree通过读入一串整数以层次优先从左到右的方式构建一个二叉树,函数outputTree输出此树的中序遍历。两个函数的原型如下:
void buildTree(BN** rootptr);
void outputTree(BN* root);
输入:N个正整数,1<=N<=30,以空格间隔,以-1结束。注意-1不包含在此树的结构中,只是作为输入结束的符号。
输出:一行按照中序遍历排列的正整数,以空格间隔,最后一个输出的元素后仍然有空格,且没有换行
注意:main函数已经给出,并且在其中给出了树的根节点的指针以及整棵树free的过程,buildTree函数内所有的结点应以malloc形式生成,如果一个结点没有左儿子或者右儿子,则相应的指针应该等于NULL。
Sample:
input:
1 2 3 4 5 6 7 8 9 -1
output:
8 4 9 2 5 1 6 3 7
Hint:
如果以层次优先从左向右构建二叉树的过程感觉有难度,可以参考main函数中释放所有结点空间的做法。思想就是使用一个“队列”数据结构存储要处理的指针。
关于前序中序后序遍历的知识请自行查找书本及网上相应内容进行学习。
代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #define MAXI 50 5 typedef struct node { 6 int x; 7 struct node* left; 8 struct node* right; 9 }BN; 10 void outputTree(BN* root); 11 void buildTree(BN** rootptr) { 12 int num, tot = 1, head = 1; 13 BN* a[50]; 14 scanf("%d", &num); 15 BN* p = (BN*)malloc(sizeof(BN)); 16 *rootptr = p; 17 (*rootptr) -> x = num; 18 a[1] = *rootptr; 19 a[1] -> left = NULL; 20 a[1] -> right = NULL; 21 while (num != -1) { 22 scanf("%d", &num); 23 if (num != -1) { 24 tot++; 25 BN* left = (BN*)malloc(sizeof(BN)); 26 left -> x = num; 27 left -> left = NULL; 28 left -> right = NULL; 29 a[tot] = left; 30 a[head] -> left = left; 31 scanf("%d", &num); 32 } 33 if (num != -1) { 34 tot++; 35 BN* right = (BN*)malloc(sizeof(BN)); 36 right -> x = num; 37 right -> right = NULL; 38 right -> left = NULL; 39 a[tot] = right; 40 a[head] -> right = right; 41 } 42 head++; 43 } 44 } 45 void outputTree(BN* root) { 46 if (root -> left != NULL) { 47 outputTree(root -> left); 48 } 49 printf("%d ", root -> x); 50 if (root -> right != NULL) { 51 outputTree(root -> right); 52 } 53 } 54 int main() { 55 BN* root; 56 BN* que[MAXI]; /*used for free*/ 57 int head = 0; /*head of que*/ 58 int tail = 1; /*tail of que*/ 59 buildTree(&root); 60 outputTree(root); 61 /*the free procedure*/ 62 que[0] = root; 63 while (head != tail) { 64 if (que[head]->left != NULL) { 65 que[tail] = que[head]->left; 66 tail = (tail + 1) % MAXI; 67 } 68 if (que[head]->right != NULL) { 69 que[tail] = que[head]->right; 70 tail = (tail + 1) % MAXI; 71 } 72 free(que[head]); 73 head = (head + 1) % MAXI; 74 } 75 return 0; 76 }