#include<stdio.h> #include<stdlib.h> #define STACKSIZE 50 #define bitree_size(tree) ((tree)->size) #define bitree_root(tree) ((tree)->root) #define bitree_left(node) ((node)->left) #define bitree_right(node) ((node)->right) /* * 定义二叉树结点以及二叉树的结构 * */ typedef struct BiTreeNode_ { char data; struct BiTreeNode_ *left; struct BiTreeNode_ *right; }BiTreeNode; typedef struct BiTree_ { int size; BiTreeNode *root; }BiTree; /* * 定义栈的结构 * */ typedef struct Stack_ { BiTreeNode * base[STACKSIZE]; int top; int stacksize; }Stack; void stack_init(Stack *stack) { stack->top = -1; stack->stacksize = 0; } void push(Stack *stack, BiTreeNode *node) { if(stack->stacksize == STACKSIZE) exit(-1); stack->base[++stack->top] = node; stack->stacksize++; } int stack_empty(Stack *stack) { if((-1 == stack->top) && (0 == stack->stacksize)) return 1; else return 0; } BiTreeNode* pop(Stack *stack) { if(stack->top < 0) exit(-1); else { return stack->base[stack->top--]; } } BiTreeNode* get_stack_top(Stack *stack) { if(stack->top < 0) exit(-1); return stack->base[stack->top]; } void bitree_init(BiTree *tree) { tree->size = 0; tree->root = NULL; } /*在看下面代码之前,先搞清楚指针,和指向指针的指针,在这详细解释一下 * int i = 0; * int *p, **q; stack->stacksize--; *p=&i; //指针p的值是int变量 i 的地址,所以 *p 的值 和 i 的值是相等的。 * 重点来了: q = &p; // 同理,q 保存的是指针 p 的地址,那么*q 就是指针 p 的值,所 以我们可以看出**q == i; * 回到这个二叉树的程序中 * position 是个指向 BiTreeNode 指针类型的指针, * 我们需要在函数 bitree_ins_left 给二叉树的某个左节点赋值 而节点 node 是指针类型, 由于函数作用域的关系, * 使得我们假如要改变一个指针的值,就必须通过指向指针的指针来实现。 */ //给树 tree 的某个结点 node 插入数据域为 data 的左子树 int bitree_ins_left(BiTree *tree, BiTreeNode *node, const char data) { BiTreeNode *new_node, **position; if(NULL == node) { if(bitree_size(tree) > 0) return -1; position = &tree->root; } else { if(bitree_left(node) != NULL) return -1; position = &node->left; } if( NULL == (new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) ) //判断内存能否分配 成功 return -1; new_node->data = data; new_node->left = NULL; new_node->right = NULL; *position = new_node; tree->size++; return 0; } int bitree_ins_right(BiTree *tree, BiTreeNode *node, const char data) { BiTreeNode *new_node, **position; if(NULL == node) { if(bitree_size(tree) > 0) return -1; position = &tree->root; } else { if(bitree_right(node) != NULL) return -1; position = &node->right; } if( NULL == (new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) ) return -1; new_node->data = data; new_node->left = NULL; new_node->right = NULL; *position = new_node; tree->size++; return 0; } // 先序遍历函数 void pre_order(const BiTreeNode *node) { if(node) { printf("%c",node->data); pre_order(node->left); pre_order(node->right); } } // 中序遍历函数 void in_order(const BiTreeNode *node) { if(node) { in_order(node->left); printf("%c",node->data); in_order(node->right); } } // 后序遍历函数 void end_order(const BiTreeNode *node) { if(node) { end_order(node->left); end_order(node->right); printf("%c",node->data); } } int main() { char data; Stack stack; BiTree tree; BiTreeNode *node; stack_init(&stack); bitree_init(&tree); printf("请以先序顺序输入结点值: \n"); data = getchar(); if( 0 == bitree_size(&tree) ) { if( " " == data ) return -1; bitree_ins_left(&tree,NULL,data); push(&stack,tree.root); } while(!stack_empty(&stack)) { data = getchar(); if( " " == data ) { node = pop(&stack); if(NULL == node->left) { data = getchar(); if( " " != data ) { bitree_ins_right(&tree,node,data); push(&stack,node->right); } } } else { node = get_stack_top(&stack); if( NULL == node->left ) { bitree_ins_left(&tree,node,data); push(&stack,node->left); } else { node = pop(&stack); bitree_ins_right(&tree,node,data); push(&stack,node->right); } } } printf("--先序遍历二叉树--\n"); pre_order(tree.root); putchar("\n"); printf("--中序遍历二叉树--\n"); in_order(tree.root); putchar("\n"); printf("--后序遍历二叉树--\n"); end_order(tree.root); putchar("\n"); return 0; }
感觉主函数的创建方法不能创建图片中的二叉树图片中的二叉树,帮忙鉴定一下是不是。
解决方案
40
仅供参考:
#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点 char data; //数据 struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树 char data; scanf("%c",&data);//按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树 if (data == "#") { T = NULL; } else { T = (BiTree)malloc(sizeof(BiTNode)); T->data = data; //生成根结点 CreateBiTree(T->lchild);//构造左子树 CreateBiTree(T->rchild);//构造右子树 } return 0; } void Visit(BiTree T) {//输出 if (T->data != "#") { printf("%c ",T->data); } } void PreOrder(BiTree T) {//先序遍历 if (T != NULL) { Visit(T); //访问根节点 PreOrder(T->lchild); //访问左子结点 PreOrder(T->rchild); //访问右子结点 } } void InOrder(BiTree T) {//中序遍历 if (T != NULL) { InOrder(T->lchild); //访问左子结点 Visit(T); //访问根节点 InOrder(T->rchild); //访问右子结点 } } void PostOrder(BiTree T) {//后序遍历 if (T != NULL) { PostOrder(T->lchild); //访问左子结点 PostOrder(T->rchild); //访问右子结点 Visit(T); //访问根节点 } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。 stack<BiTree> stack; BiTree p = T;//p是遍历指针 while (p || !stack.empty()) { //栈不空或p不空时循环 if (p != NULL) { stack.push(p); //存入栈中 printf("%c ",p->data); //访问根节点 p = p->lchild; //遍历左子树 } else { p = stack.top(); //退栈 stack.pop(); p = p->rchild; //访问右子树 } } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。 //先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。 stack<BiTree> stack; BiTree p = T;//p是遍历指针 while (p || !stack.empty()) { //栈不空或p不空时循环 if (p != NULL) { stack.push(p); //存入栈中 p = p->lchild; //遍历左子树 } else { p = stack.top(); //退栈,访问根节点 printf("%c ",p->data); stack.pop(); p = p->rchild; //访问右子树 } } } typedef struct BiTNodePost{ BiTree biTree; char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归) stack<BiTreePost> stack; BiTree p = T;//p是遍历指针 BiTreePost BT; while (p != NULL || !stack.empty()) {//栈不空或p不空时循环 while (p != NULL) {//遍历左子树 BT = (BiTreePost)malloc(sizeof(BiTNodePost)); BT->biTree = p; BT->tag = "L";//访问过左子树 stack.push(BT); p = p->lchild; } while (!stack.empty() && (stack.top())->tag == "R") {//左右子树访问完毕访问根节点 BT = stack.top(); stack.pop();//退栈 printf("%c ",BT->biTree->data); } if (!stack.empty()) {//遍历右子树 BT = stack.top(); BT->tag = "R";//访问过右子树 p = BT->biTree; p = p->rchild; } } } void LevelOrder(BiTree T) {//层次遍历 if (T == NULL) return; BiTree p = T; queue<BiTree> queue;//队列 queue.push(p);//根节点入队 while (!queue.empty()) { //队列不空循环 p = queue.front(); //对头元素出队 printf("%c ",p->data); //访问p指向的结点 queue.pop(); //退出队列 if (p->lchild != NULL) {//左子树不空,将左子树入队 queue.push(p->lchild); } if (p->rchild != NULL) {//右子树不空,将右子树入队 queue.push(p->rchild); } } } int main() { BiTree T; setlocale(LC_ALL,"chs"); CreateBiTree(T); printf("先序遍历 :");PreOrder (T);printf("\n"); printf("先序遍历(非递归):");PreOrder2 (T);printf("\n"); printf("\n"); printf("中序遍历 :");InOrder (T);printf("\n"); printf("中序遍历(非递归):");InOrder2 (T);printf("\n"); printf("\n"); printf("后序遍历 :");PostOrder (T);printf("\n"); printf("后序遍历(非递归):");PostOrder2(T);printf("\n"); printf("\n"); printf("层次遍历 :");LevelOrder(T);printf("\n"); return 0; } //ABC##DE#G##F### //先序遍历 :A B C D E G F //先序遍历(非递归):A B C D E G F // //中序遍历 :C B E G D F A //中序遍历(非递归):C B E G D F A // //后序遍历 :C G E F D B A //后序遍历(非递归):C G E F D B A // //层次遍历 :A B C D E F G // /// A /// / /// B /// / \ /// C D /// / \ /// E F /// \ /// G