

如何定义n叉树,n是多少的问题?




可以使用广义表来表示一颗二叉树


#include <stdio.h>#include <stdlib.h>#include <time.h>typedef struct Node { int data; struct Node *lchild, *rchild;} Node;typedef struct Tree { Node *root; int length; // 记录二叉树的节点个数} Tree;Node *getNewNode(int val);Tree *getNewTree();Node *insert_node(Node *, int, int *);void insert(Tree *, int);void pre_order_node(Node *);void pre_order(Tree *);void in_order_node(Node *);void in_order(Tree *);void post_order_node(Node *);void post_order(Tree *);void clear_node(Node *);void clear(Tree *);void output_node(Node *);void output(Tree *);int main() { srand(time(0)); Tree *tree = getNewTree(); #define MAX_OP 10 for (int i = 0; i < MAX_OP; i++) { int val = rand() % 100; insert(tree, val); output(tree); } #undef MAX_OP pre_order(tree); in_order(tree); post_order(tree); clear(tree); return 0;}Node *getNewNode(int val) { Node *p = (Node *)malloc(sizeof(Node)); p->data = val; p->lchild = p->rchild = NULL; return p;}Tree *getNewTree() { Tree *t = (Tree *)malloc(sizeof(Tree)); t->root = NULL; t->length = 0; return t;}// ?叉排序树插入操作// 性质:一颗二叉树中的任何三元组都满足 B(左孩子) < A(根节点) < C (右孩子)的这种关系,故中序遍历可实现排序// 插入过程(尾插法):从根节点开始,找到待插入位置前的叶子节点(向下寻找),然后返回各个节点地址(向上回溯)Node *insert_node(Node *root, int val, int *flag) { if (root == NULL) { *flag = 1; return getNewNode(val); } if (root->data == val) return root; // ?叉排序树的性质:任何三元组都满足 B(左孩子) < A(根节点) < C (右孩子) if (root->data > val) root->lchild = insert_node(root->lchild, val, flag); else root->rchild = insert_node(root->rchild, val, flag); return root;}void insert(Tree *t, int val) { if (t == NULL) return ; int flag = 0; // 传出参数,标记当前插入节点是否成功,成功:1,失败:0 t->root = insert_node(t->root, val, &flag); t->length += flag; return ;}// 前序:根->左->右void pre_order_node(Node *root) { if (root == NULL) return ; printf("%d ", root->data); pre_order_node(root->lchild); pre_order_node(root->rchild); return ;}void pre_order(Tree *t) { if (t == NULL) return ; printf("pre_order : "); pre_order_node(t->root); printf("\n"); return ;}// 中序:左->根->右void in_order_node(Node *root) { if (root == NULL) return ; in_order_node(root->lchild); printf("%d ", root->data); in_order_node(root->rchild); return ;}void in_order(Tree *t) { if (t == NULL) return ; printf("in_order : "); in_order_node(t->root); printf("\n"); return ;}// 后序:左->右->根void post_order_node(Node *root) { if (root == NULL) return ; post_order_node(root->lchild); post_order_node(root->rchild); printf("%d ", root->data); return ;}void post_order(Tree *t) { if (t == NULL) return ; printf("post_order : "); post_order_node(t->root); printf("\n"); return ;}// 从叶子节点开始删除void clear_node(Node *node) { if (node == NULL) return ; clear_node(node->lchild); clear_node(node->rchild); free(node); return ;}void clear(Tree *t) { if (t == NULL) return ; clear_node(t->root);}// 相当于前序遍历void output_node(Node *root) { if (root == NULL) return ; printf("%d", root->data); if (root->lchild == NULL && root->rchild == NULL) return ; // 若是叶子节点,则结束 printf("("); output_node(root->lchild); printf(","); output_node(root->rchild); printf(")"); return ;}void output(Tree *t) { if (t == NULL) return ; printf("tree(%d) : ", t->length); output_node(t->root); printf("\n");}// tree(1) : 6// tree(2) : 6(,28)// tree(3) : 6(,28(9,))// tree(4) : 6(,28(9,87))// tree(5) : 6(,28(9,87(61,)))// tree(6) : 6(,28(9,87(61(34,),)))// tree(7) : 6(,28(9,87(61(34(,40),),)))// tree(8) : 6(,28(9,87(61(34(,40),65),)))// tree(9) : 6(,28(9(,20),87(61(34(,40),65),)))// tree(9) : 6(,28(9(,20),87(61(34(,40),65),)))// pre_order : 6 28 9 20 87 61 34 40 65 // in_order : 6 9 20 28 34 40 61 65 87 // post_order : 20 9 40 34 65 61 87 28 6#include <stdio.h>#include <stdlib.h>#include <string.h> //?叉树的结构定义typedef struct Node { char data; struct Node *lchild, *rchild;} Node;typedef struct Tree { Node *root; int length;} Tree;//栈的结构定义(存储?叉树节点地址)typedef struct Stack { Node **data; // 定义二级指针的原因:使用数组来存放每个节点的地址,即数组的每个元素都是 Node* int top, size; // top: 标记栈顶位置,默认为-1;size: 当前栈空间的大小} Stack;Node *getNewNode(char); // 节点的初始化Tree *getNewTree(); // ?叉树的初始化void clear_node(Node *); // 销毁?叉树的节点void clear_tree(Tree *); // 销毁?叉树Stack *init_stack(int); // 栈的初始化void clear_stack(Stack *); // 栈的销毁Node *top(Stack *); // 输出栈顶元素int empty(Stack *); // 栈的判空int push(Stack *, Node *); // 压栈操作int pop(Stack *); // 弹栈操作void pre_order_node(Node *);void pre_order(Tree *); // 前序遍历void in_order_node(Node *);void in_order(Tree *); // 中序遍历void post_order_node(Node *);void post_order(Tree *); // 后序遍历Node *build(const char *, int *); // 构建一颗二叉树int main() { char str[1000] = { 0 }; int node_num = 0; scanf("%[^\n]s", str); getchar(); Tree *tree = getNewTree(); tree->root = build(str, &node_num); tree->length = node_num; pre_order(tree); in_order(tree); post_order(tree); clear_tree(tree); return 0;}Node *getNewNode(char val) { Node *p = (Node *)malloc(sizeof(Node)); p->lchild = p->rchild = NULL; p->data = val; return p;}Tree *getNewTree() { Tree *t = (Tree *)malloc(sizeof(Tree)); t->root = NULL; t->length = 0; return t;}void clear_node(Node *root) { if (root == NULL) return; clear_node(root->lchild); clear_node(root->rchild); free(root); return;}void clear_tree(Tree *t) { if (t == NULL) return; clear_node(t->root); free(t); return;}Stack *init_stack(int n) { Stack *s = (Stack *)malloc(sizeof(Stack)); s->data = (Node **)malloc(sizeof(Node *) * n); s->top = -1; s->size = n; return s;}void clear_stack(Stack *s) { if (s == NULL) return; free(s->data); free(s); return;}Node *top(Stack *s) { return s->data[s->top];}int empty(Stack *s) { return s->top == -1;}int push(Stack *s, Node *val) { if (s == NULL) return 0; if (s->top == s->size - 1) return 0; s->data[++(s->top)] = val; return 1;}int pop(Stack *s) { if (s == NULL) return 0; if (empty(s)) return 0; s->top -= 1; return 1;}// 二叉树的广义表表示:str = "A(B(, D), C(E))"// '(': 根节点入栈,设置flag=0; ')': 出栈; ',': 设置flag=1;// flag=0: 表示是左子节点, flag=1: 表示是右子节点// 将广义表转化为二叉树// 前序|后续遍历 && 中序遍历 ==> 二叉树// 本方法:栈实现广义表转二叉树// 方法2:系统栈(递归)实现广义表转二叉树Node *build(const char *str, int *node_num) { Stack *s = init_stack(strlen(str)); int flag = 0; Node *temp = NULL, *p = NULL; // temp:指向每层的父节点,p:指向根节点 while (str[0]) { switch (str[0]) { case '(': push(s, temp); flag = 0; break; case ')': p = top(s); pop(s); break; case ',': flag = 1; break; case ' ': break; default: temp = getNewNode(str[0]); if (!empty(s) && flag == 0) { top(s)->lchild = temp; } else if (!empty(s) && flag == 1) { top(s)->rchild = temp; } ++(*node_num); break; } ++str; } clear_stack(s); if (temp && p == NULL) p = temp; // 只有根节点的情况 return p;}void in_order_node(Node *root) { if (root == NULL) return; in_order_node(root->lchild); printf("%c ", root->data); in_order_node(root->rchild); return;}void in_order(Tree *tree) { if (tree == NULL) return; printf("in_order(%d) : ", tree->length); in_order_node(tree->root); printf("\n"); return;}void pre_order_node(Node *root) { if (root == NULL) return; printf("%c ", root->data); pre_order_node(root->lchild); pre_order_node(root->rchild); return;}void pre_order(Tree *tree) { if (tree == NULL) return; printf("pre_order(%d) : ", tree->length); pre_order_node(tree->root); printf("\n"); return;}void post_order_node(Node *root) { if (root == NULL) return; post_order_node(root->lchild); post_order_node(root->rchild); printf("%c ", root->data); return;}void post_order(Tree *tree) { if (tree == NULL) return; printf("post_order(%d) : ", tree->length); post_order_node(tree->root); printf("\n"); return;}