根据访问结点操作发生位置命名:
① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问根结点的操作发生在遍历其左右子树之前。
② LNR:中序遍历(InorderTraversal) ——访问根结点的操作发生在遍历其左右子树之中(间)。
③ LRN:后序遍历(PostorderTraversal) ——访问根结点的操作发生在遍历其左右子树之后。
注意:由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。
前中后是指根结点的访问时机,在左右子树之前、中间或之后。
层序就是从根结点开始从上至下、从左到右地依次访问。
先上代码:
#include<stdio.h> #include<stdlib.h> #define Maxsize 100; typedef int ElemType; typedef struct BT { int data; struct BT *lch, *rch; } BT; BT *CreatBT (); void preorder (BT * T); void inorder (BT * T); void postorder (BT * T); void leafnum (BT * T); void ShowTree (BT * T); void Nodenum (BT * T); void printTree(BT *T,int n); int main (void) { BT *T = NULL; int choice; do { printf ("\n"); printf (" 二叉树 \n"); printf (" ***************************\n"); printf (" * *\n"); printf (" * 主菜单 *\n"); printf (" * 1 建立二叉树 *\n"); printf (" * 2 先序遍历二叉树 *\n"); printf (" * 3 中序遍历二叉树 *\n"); printf (" * 4 后序遍历二叉树 *\n"); printf (" * 5 二叉树的叶子结点数 *\n"); printf (" * 6 显示二叉树 *\n"); printf (" * 7 二叉树的所有结点数 *\n"); printf (" * 8 退出程序运行 *\n"); printf (" ****************************\n"); printf (" 请输入您的选择(1,2,3,4,5,6,7,8): \n"); scanf ("%d", &choice); if (choice == 1) { printf ("二叉树的建立,以输入“0”表示结束:!\n"); printf ("请输入根结点:\n"); T = CreatBT (); printf ("二叉树成功建立"); } else if (choice == 2) { printf ("先序遍历二叉树 :\n"); preorder (T); } else if (choice == 3) { printf ("中序遍历二叉树:\n"); inorder (T); } else if (choice == 4) { printf ("后序遍历二叉树 :\n "); postorder (T); } else if (choice == 5) { printf (" 二叉树的叶子结点数为 : \n"); leafnum (T); } else if (choice == 6) // ShowTree (T); printTree(T,1); else if (choice == 7) { Nodenum (T); } else if (choice == 8) exit (0); } while (choice <= 8); } BT * CreatBT () { BT *t; int x; scanf ("%d", &x); if (x == 0) { t = NULL; } else { t = (BT *) malloc (sizeof (BT)); t->data = x; printf ("\n请输入%d结点的左子结点:", t->data); t->lch = CreatBT (); printf ("\n请输入%d结点的右子结点:", t->data); t->rch = CreatBT (); } return t; } void preorder (BT * T) { if (T == NULL) return; else { printf ("%3d", T->data); preorder (T->lch); preorder (T->rch); } } void inorder (BT * T) { if (T == NULL) return; else { inorder (T->lch); printf ("%3d", T->data); inorder (T->rch); } } void postorder (BT * T) { if (T == NULL) return; else { postorder (T->lch); postorder (T->rch); printf ("%3d", T->data); } } void leafnum (BT * T) { static int count = 0; if (T) { if (T->lch == NULL && T->rch == NULL) { count++; printf("叶子是%4d\n",T->data); } leafnum (T->lch); leafnum (T->rch); printf ("叶子总数是%4d", count); } } void ShowTree (BT * T) { BT *stack[100]; BT *p; int level[100][2]; int top, n, i; int width = 4; if (T != NULL) { printf ("\n二叉树的表示法f:\n"); top = 1; stack[top] = T; level[top][0] = width; while (top > 0) { p = stack[top]; n = level[top][0]; for (i = 1; i <= n; i++) printf (" "); printf ("%d", p->data); for (i = n + 1; i < 60; i += 2) printf ("*"); printf ("\n\t\t"); top--; if (p->rch != NULL) { top++; stack[top] = p->rch; level[top][0] = n + width; level[top][1] = 2; } if (p->lch != NULL) { top++; stack[top] = p->lch; level[top][0] = n + width; level[top][1] = 1; } } } } void Nodenum (BT * T) { static int count = 0; if (T) { count++; Nodenum (T->lch); Nodenum (T->rch); } else { printf ("该二叉树总共有%d个结点。\n", count); } } void printTree(BT *T,int n) { int i; if(T == NULL) return ; else { printTree(T->lch,n+1); for(i=0;i<n;i++) printf(" "); printf("%d\n",T->data); printTree(T->rch,n+1); } }
下面我用递归处理二叉树的前序、中序和后序遍历。
void visit(bt t,char *order) { if(t) { if(strcmp(order,"NLR")==0) printf("%4d",t->data); visit(t->lch,order); if(strcmp(order,"LNR")==0) printf("%4d",t->data); visit(t->rch,order); if(strcmp(order,"LRN")==0) printf("%4d",t->data); } }