user-0 提问: 自学数据结构时遇到一些问题，自己看了一下午还没发现，愿不吝赐教，谢谢

回复:
user: user-0
content: 谢谢赵老师，谢谢版主大人，还有那个大哥，我弄懂了非常感谢

user: user-1
content: “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

user: user-2
content: 1.你应该把printf("请输入相应的数据(*表示置空):");这句放到函数外，不然每次递归都会调用到 2.你的输入也是不对的，应该输入类似:SA**D**这样的才行  #include <stdio.h> #include <stdlib.h> #include <conio.h> typedef char ElementType; typedef struct BiTreeNode { 	ElementType data; 	struct BiTreeNode *lchild; 	struct BiTreeNode *rchild; }BiTreeNode, *BiTree; BiTree Initate() { 	BiTreeNode *p; 	p = NULL; 	return p; } void CreateBiTree(BiTree &T) { 	ElementType data; 	 	data = getchar(); 	if (data == '*') 		T = NULL; 	else 	{ 		T = (BiTreeNode *)malloc(sizeof(BiTreeNode)); 		if (T == NULL) 			return; 		T->data = data; 		CreateBiTree(T->lchild); 		CreateBiTree(T->rchild); 	} } void InOrderTraverse(BiTree &T) { 	if (T) 	{ 		InOrderTraverse(T->lchild); 		printf("%c", T->data); 		InOrderTraverse(T->rchild); 	} } BiTree SearchNode(BiTree &T, ElementType data) { 	BiTree p; 	if (T) 	{ 		if (T->data == data) 			return T; 		if (T->lchild) 		{ 			p = SearchNode(T->lchild, data); 			if (p) 				return p; 		} 		if (T->rchild) 		{ 			p = SearchNode(T->rchild, data); 			if (p) 				return p; 		} 	} 	return NULL; } int InsertNode(BiTree &T, ElementType data) { 	BiTree p, q; 	p = SearchNode(T, data); 	if (p) 		return 1; 	else 	{ 		q = (BiTreeNode *)malloc(sizeof(BiTreeNode)); 		if (q == NULL) 			return -1; 		q->data = data; 		q->lchild = NULL; 		q->rchild = NULL; 		if (p == NULL) 			T = q; 		else if (p->lchild == NULL) 			p->lchild = q; 		else 		{ 			q->lchild = p->lchild; 			p->lchild = q->lchild; 		} 	} } int DeleteNode(BiTree &T, ElementType data) { 	BiTree p, q; 	p = SearchNode(T, data); 	if (p == NULL) 		return -1; 	q = p; 	p = NULL; 	free(q); } void DestroyBiTree(BiTree &T) { 	if (T) 	{ 		DestroyBiTree(T->lchild); 		DestroyBiTree(T->rchild); 		T = NULL; 	} } int main(void) { 	BiTree T; 	T = Initate(); 	int a; 	ElementType data; 	do 	{ 		printf("二叉树的基本操作:\n"); 		printf("1.建立二叉树\n2.输出二叉树\n3.查找结点\n4.插入结点\n5.删除结点\n6.销毁二叉树\n0.退出\n"); 		printf("请选择对应的功能:\n"); 		scanf("%d", &a); 		getchar(); 		if (a == 0) 			break; 		switch (a) 		{ 		case 1: 			printf("请输入相应的数据(*表示置空):"); 			CreateBiTree(T); 			break; 		case 2: 			InOrderTraverse(T); 			break; 		case 3: 			printf("请输入结点的数据值:\n"); 			scanf("%c", &data); 			SearchNode(T, data); 			break; 		case 4: 			printf("请输入结点的数据值:\n"); 			scanf("%c", &data); 			InsertNode(T, data); 			break; 		case 5: 			printf("请输入结点的数据值:\n"); 			scanf("%c:", &data); 			DeleteNode(T, data); 			break; 		case 6: 			DestroyBiTree(T); 			break; 		} 	} while (a != 0); 	return 0; }

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-3
content: 我觉得你出现问题的最主要的原因在于这两句： printf("请输入相应的数据(*表示置空):");     data=getchar();  这两句代码应该在函数外面，因为你要递归这个函数，放到这每次递归都会打印这句话； 而且使用getchar当你当前的输入结束时，在递归过程中标准输入的字符被读完时会发生阻塞，最好的办法是使用fgets获取整个字符串在递归中进行循环读取。  没有细调，仅供参考。

user: user-4
content: http://study.163.com/course/introduction/468002.htm#/courseDetail 数据结构教学 感觉还不错

user: user-0

user: user-0
content: 谢谢版主大大，不过这个问题改了还是出错，我上传一张图片看看

user: user-5
content: InsertNode 函数中：  q->lchild==NULL; q->rchild==NULL;  == 改成 =