user-0 提问: 数据结构  递归创建二叉树

回复:
user: user-0
content: 楼上的代码需要运行时输入，我希望的是能够自动从一个数组里面读入数据。即在代码里面就有数据，类似与5楼这位哥们的代码

user: user-1
content: 仅供参考：#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

user: user-2
content: else if (*ch == '#') 要加else  可能还有bug, 你自己试试吧

user: user-2
content: 你参考一下,  1.字符数组最后加了个\n, 用来结束递归   t->lchild=create(ch);     t->rchild=create(ch); 2, 左右child, 在create的时候是同一个ch.  所以需要BTnode *create(const char * &ch), 参数改成引用. 这样递归的时候, 内层ch++的时候, 外层ch也会被修改    #include <stdio.h> #include <stdlib.h>  struct BTnode { 	char data; 	BTnode *lchild; 	BTnode *rchild; };  const char *pCh = NULL;  BTnode *create(const char * &ch)/*建立二叉树*/ { 	BTnode *t; 	if (*ch == '\n') 	{ 		t = NULL; 	} 	if (*ch == '#') 	{ 		t = NULL; 		ch++; 	} 	else 	{ 		t = (BTnode *)malloc(sizeof(BTnode)); 		printf("%c\n", *ch); 		t->data = *ch++; 		t->lchild = create(ch); 		t->rchild = create(ch); 	} 	return t; }  void printTree(BTnode *T) { 	if (T) 	{  		printf("%c", T->data);  		if (T->lchild != NULL) 		{ 			printTree(T->lchild); 		}  		if (T->rchild != NULL) 		{ 			printTree(T->rchild); 		} 	} } int main() { 	const char ch[] = { 'D','E','H','#','#','F','J','#','#', 		'G','#','C','K','#','#','#', 		'A','#','B','#','#', '\n' 	}; 	pCh = ch; 	BTnode *t = create(pCh); 	printTree(t); 	getchar(); 	return 0; }

user: user-0
content: http://paste.ubuntu.com/10731143/    还是贴代码吧  #include "stdio.h"  #include "malloc.h"  #define M 100  typedef struct node 	{  /* 链式存储的指针类型和结点定义 */ 	   char data; 	   struct node *lchild,*rchild; 	}BTnode;  BTnode *create( const char * ch)/*建立二叉树*/ 	{ 		 BTnode *t; 		if( * ch=='#') 		{ 			 t=NULL; 			 ch++; 		}   		else 		   { 		   t=(BTnode *)malloc(sizeof(BTnode)) ; 		    t->data= *ch; 		    ch++; 		    t->lchild=create(ch); 		    t->rchild=create(ch); 		    } 		  return t; 	} void preorder(BTnode *t)/*先序遍历二叉树*/ 	{ 		 if(t!=NULL) 		 printf("%c ",t->data); 		 if(t->lchild!=NULL) 		 preorder(t->lchild); 		 if(t->rchild!=NULL) 		 preorder(t->rchild); 	 	} void inorder(BTnode *t)/*中序遍历二叉树*/ 	{ 	  if(t!=NULL) 	  { 	    if(t->lchild!=NULL) 	    inorder(t->lchild); 	    printf("%c ",t->data); 	    if(t->rchild!=NULL) 	    inorder(t->rchild); 	  } 	} void postorder(BTnode *t)/*后序遍历二叉树*/ 	{ 	  if(t!=NULL) 	  { if(t->lchild!=NULL) 	    postorder(t->lchild); 	    if(t->rchild!=NULL) 	    postorder(t->rchild); 	    printf("%c ",t->data); 	  } 	} int main() 	{ 		BTnode *t; //		printf("Input data:") ; 		char ch[21]={'D','E','H','#','#','F','J','#','#','G','#','C','K','#','#','#','A','#','B','#','#'}; 		t=create(ch); //		printf("==================The result==========================/n"); 		printf("The preorder is:"); 		preorder(t); 		printf("\n"); 		printf("The inorder is:"); 		inorder(t); 		printf("\n"); 		printf("The postorder is:"); 		postorder(t); 		printf("\n"); 		return 0; 	}

user: user-2
content: 引用 2 楼 xialibaran 的回复:我的思路对吗？ 字符数组末尾应该设一个标志位, 要不然怎么判断没元素了 if( * ch=='#')的时候, 也应该ch++吧

user: user-0
content: 我的思路对吗？

user: user-2
content: 请单步调试.