算法之二叉树各种遍历

[置顶] 算法之二叉树各种遍历

标签: 算法
125748人阅读 评论(38) 收藏 举报
本文章已收录于:
分类:

树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。

二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则n0 = n2 + 1。

二叉树的链式存储结构是一类重要的数据结构,其形式定义如下:

  1. //二叉树结点  
  2. typedef struct BiTNode{  
  3.     //数据  
  4.     char data;  
  5.     //左右孩子指针  
  6.     struct BiTNode *lchild,*rchild;  
  7. }BiTNode,*BiTree;  
//二叉树结点
typedef struct BiTNode{
	//数据
	char data;
	//左右孩子指针
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;


二叉树的创建:

通过读入一个字符串,建立二叉树的算法如下:

  1. //按先序序列创建二叉树  
  2. int CreateBiTree(BiTree &T){  
  3.     char data;  
  4.     //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树  
  5.     scanf("%c",&data);  
  6.     if(data == '#'){  
  7.         T = NULL;  
  8.     }  
  9.     else{  
  10.         T = (BiTree)malloc(sizeof(BiTNode));  
  11.         //生成根结点  
  12.         T->data = data;  
  13.         //构造左子树  
  14.         CreateBiTree(T->lchild);  
  15.         //构造右子树  
  16.         CreateBiTree(T->rchild);  
  17.     }  
  18.     return 0;  
  19. }  
//按先序序列创建二叉树
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;
}

二叉树的遍历:

遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。

递归算法:

  1. //输出  
  2. void Visit(BiTree T){  
  3.     if(T->data != '#'){  
  4.         printf("%c ",T->data);  
  5.     }  
  6. }  
  7. //先序遍历  
  8. void PreOrder(BiTree T){  
  9.     if(T != NULL){  
  10.         //访问根节点  
  11.         Visit(T);  
  12.         //访问左子结点  
  13.         PreOrder(T->lchild);  
  14.         //访问右子结点  
  15.         PreOrder(T->rchild);  
  16.     }  
  17. }  
  18. //中序遍历  
  19. void InOrder(BiTree T){  
  20.     if(T != NULL){  
  21.         //访问左子结点  
  22.         InOrder(T->lchild);  
  23.         //访问根节点  
  24.         Visit(T);  
  25.         //访问右子结点  
  26.         InOrder(T->rchild);  
  27.     }  
  28. }  
  29. //后序遍历  
  30. void PostOrder(BiTree T){  
  31.     if(T != NULL){  
  32.         //访问左子结点  
  33.         PostOrder(T->lchild);  
  34.         //访问右子结点  
  35.         PostOrder(T->rchild);  
  36.         //访问根节点  
  37.         Visit(T);  
  38.     }  
  39. }  
//输出
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);
	}
}

非递归算法:

<1>先序遍历:

【思路】:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。

  1. /* 先序遍历(非递归) 
  2.    思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。 
  3. */  
  4. void PreOrder2(BiTree T){  
  5.     stack<BiTree> stack;  
  6.     //p是遍历指针  
  7.     BiTree p = T;  
  8.     //栈不空或者p不空时循环  
  9.     while(p || !stack.empty()){  
  10.         if(p != NULL){  
  11.             //存入栈中  
  12.             stack.push(p);  
  13.             //访问根节点  
  14.             printf("%c ",p->data);  
  15.             //遍历左子树  
  16.             p = p->lchild;  
  17.         }  
  18.         else{  
  19.             //退栈  
  20.             p = stack.top();  
  21.             stack.pop();  
  22.             //访问右子树  
  23.             p = p->rchild;  
  24.         }  
  25.     }//while  
  26. }  
/* 先序遍历(非递归)
   思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
*/
void PreOrder2(BiTree T){
	stack<BiTree> stack;
	//p是遍历指针
	BiTree p = T;
	//栈不空或者p不空时循环
	while(p || !stack.empty()){
		if(p != NULL){
			//存入栈中
			stack.push(p);
			//访问根节点
			printf("%c ",p->data);
			//遍历左子树
			p = p->lchild;
		}
		else{
			//退栈
			p = stack.top();
			stack.pop();
			//访问右子树
			p = p->rchild;
		}
	}//while
}


<2>中序遍历

【思路】:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
         先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。

  1. void InOrder2(BiTree T){  
  2.     stack<BiTree> stack;  
  3.     //p是遍历指针  
  4.     BiTree p = T;  
  5.     //栈不空或者p不空时循环  
  6.     while(p || !stack.empty()){  
  7.         if(p != NULL){  
  8.             //存入栈中  
  9.             stack.push(p);  
  10.             //遍历左子树  
  11.             p = p->lchild;  
  12.         }  
  13.         else{  
  14.             //退栈,访问根节点  
  15.             p = stack.top();  
  16.             printf("%c ",p->data);  
  17.             stack.pop();  
  18.             //访问右子树  
  19.             p = p->rchild;  
  20.         }  
  21.     }//while  
  22. }  
void InOrder2(BiTree T){
	stack<BiTree> stack;
	//p是遍历指针
	BiTree p = T;
	//栈不空或者p不空时循环
	while(p || !stack.empty()){
		if(p != NULL){
			//存入栈中
			stack.push(p);
			//遍历左子树
			p = p->lchild;
		}
		else{
			//退栈,访问根节点
			p = stack.top();
			printf("%c ",p->data);
			stack.pop();
			//访问右子树
			p = p->rchild;
		}
	}//while
}

<3>后序遍历

【思路】:T是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。

  1. //后序遍历(非递归)  
  2. typedef struct BiTNodePost{  
  3.     BiTree biTree;  
  4.     char tag;  
  5. }BiTNodePost,*BiTreePost;  
  6.   
  7. void PostOrder2(BiTree T){  
  8.     stack<BiTreePost> stack;  
  9.     //p是遍历指针  
  10.     BiTree p = T;  
  11.     BiTreePost BT;  
  12.     //栈不空或者p不空时循环  
  13.     while(p != NULL || !stack.empty()){  
  14.         //遍历左子树  
  15.         while(p != NULL){  
  16.             BT = (BiTreePost)malloc(sizeof(BiTNodePost));  
  17.             BT->biTree = p;  
  18.             //访问过左子树  
  19.             BT->tag = 'L';  
  20.             stack.push(BT);  
  21.             p = p->lchild;  
  22.         }  
  23.         //左右子树访问完毕访问根节点  
  24.         while(!stack.empty() && (stack.top())->tag == 'R'){  
  25.             BT = stack.top();  
  26.             //退栈  
  27.             stack.pop();  
  28.             BT->biTree;  
  29.             printf("%c ",BT->biTree->data);  
  30.         }  
  31.         //遍历右子树  
  32.         if(!stack.empty()){  
  33.             BT = stack.top();  
  34.             //访问过右子树  
  35.             BT->tag = 'R';  
  36.             p = BT->biTree;  
  37.             p = p->rchild;  
  38.         }  
  39.     }//while  
  40. }  
//后序遍历(非递归)
typedef struct BiTNodePost{
	BiTree biTree;
	char tag;
}BiTNodePost,*BiTreePost;

void PostOrder2(BiTree T){
	stack<BiTreePost> stack;
	//p是遍历指针
	BiTree p = T;
	BiTreePost BT;
	//栈不空或者p不空时循环
	while(p != NULL || !stack.empty()){
		//遍历左子树
		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();
			BT->biTree;
			printf("%c ",BT->biTree->data);
		}
		//遍历右子树
		if(!stack.empty()){
			BT = stack.top();
			//访问过右子树
			BT->tag = 'R';
			p = BT->biTree;
			p = p->rchild;
		}
	}//while
}


<4>层次遍历

【思路】:按从顶向下,从左至右的顺序来逐层访问每个节点,层次遍历的过程中需要用队列。

  1. //层次遍历  
  2. void LevelOrder(BiTree T){  
  3.     BiTree p = T;  
  4.     //队列  
  5.     queue<BiTree> queue;  
  6.     //根节点入队  
  7.     queue.push(p);  
  8.     //队列不空循环  
  9.     while(!queue.empty()){  
  10.         //对头元素出队  
  11.         p = queue.front();  
  12.         //访问p指向的结点  
  13.         printf("%c ",p->data);  
  14.         //退出队列  
  15.         queue.pop();  
  16.         //左子树不空,将左子树入队  
  17.         if(p->lchild != NULL){  
  18.             queue.push(p->lchild);  
  19.         }  
  20.         //右子树不空,将右子树入队  
  21.         if(p->rchild != NULL){  
  22.             queue.push(p->rchild);  
  23.         }  
  24.     }  
  25. }  
//层次遍历
void LevelOrder(BiTree T){
	BiTree p = T;
	//队列
	queue<BiTree> queue;
	//根节点入队
	queue.push(p);
	//队列不空循环
	while(!queue.empty()){
		//对头元素出队
		p = queue.front();
		//访问p指向的结点
		printf("%c ",p->data);
		//退出队列
		queue.pop();
		//左子树不空,将左子树入队
		if(p->lchild != NULL){
			queue.push(p->lchild);
		}
		//右子树不空,将右子树入队
		if(p->rchild != NULL){
			queue.push(p->rchild);
		}
	}
}


测试用例:


输入:

ABC##DE#G##F###

输出:


代码:

  1. #include<iostream>  
  2. #include<stack>  
  3. #include<queue>  
  4. using namespace std;  
  5.   
  6. //二叉树结点  
  7. typedef struct BiTNode{  
  8.     //数据  
  9.     char data;  
  10.     //左右孩子指针  
  11.     struct BiTNode *lchild,*rchild;  
  12. }BiTNode,*BiTree;  
  13.   
  14. //按先序序列创建二叉树  
  15. int CreateBiTree(BiTree &T){  
  16.     char data;  
  17.     //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树  
  18.     scanf("%c",&data);  
  19.     if(data == '#'){  
  20.         T = NULL;  
  21.     }  
  22.     else{  
  23.         T = (BiTree)malloc(sizeof(BiTNode));  
  24.         //生成根结点  
  25.         T->data = data;  
  26.         //构造左子树  
  27.         CreateBiTree(T->lchild);  
  28.         //构造右子树  
  29.         CreateBiTree(T->rchild);  
  30.     }  
  31.     return 0;  
  32. }  
  33. //输出  
  34. void Visit(BiTree T){  
  35.     if(T->data != '#'){  
  36.         printf("%c ",T->data);  
  37.     }  
  38. }  
  39. //先序遍历  
  40. void PreOrder(BiTree T){  
  41.     if(T != NULL){  
  42.         //访问根节点  
  43.         Visit(T);  
  44.         //访问左子结点  
  45.         PreOrder(T->lchild);  
  46.         //访问右子结点  
  47.         PreOrder(T->rchild);  
  48.     }  
  49. }  
  50. //中序遍历    
  51. void InOrder(BiTree T){    
  52.     if(T != NULL){    
  53.         //访问左子结点    
  54.         InOrder(T->lchild);    
  55.         //访问根节点    
  56.         Visit(T);    
  57.         //访问右子结点    
  58.         InOrder(T->rchild);    
  59.     }    
  60. }    
  61. //后序遍历  
  62. void PostOrder(BiTree T){  
  63.     if(T != NULL){  
  64.         //访问左子结点  
  65.         PostOrder(T->lchild);  
  66.         //访问右子结点  
  67.         PostOrder(T->rchild);  
  68.         //访问根节点  
  69.         Visit(T);  
  70.     }  
  71. }  
  72. /* 先序遍历(非递归) 
  73.    思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。 
  74. */  
  75. void PreOrder2(BiTree T){  
  76.     stack<BiTree> stack;  
  77.     //p是遍历指针  
  78.     BiTree p = T;  
  79.     //栈不空或者p不空时循环  
  80.     while(p || !stack.empty()){  
  81.         if(p != NULL){  
  82.             //存入栈中  
  83.             stack.push(p);  
  84.             //访问根节点  
  85.             printf("%c ",p->data);  
  86.             //遍历左子树  
  87.             p = p->lchild;  
  88.         }  
  89.         else{  
  90.             //退栈  
  91.             p = stack.top();  
  92.             stack.pop();  
  93.             //访问右子树  
  94.             p = p->rchild;  
  95.         }  
  96.     }//while  
  97. }  
  98. /* 中序遍历(非递归) 
  99.    思路:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。 
  100.          先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。 
  101. */  
  102. void InOrder2(BiTree T){  
  103.     stack<BiTree> stack;  
  104.     //p是遍历指针  
  105.     BiTree p = T;  
  106.     //栈不空或者p不空时循环  
  107.     while(p || !stack.empty()){  
  108.         if(p != NULL){  
  109.             //存入栈中  
  110.             stack.push(p);  
  111.             //遍历左子树  
  112.             p = p->lchild;  
  113.         }  
  114.         else{  
  115.             //退栈,访问根节点  
  116.             p = stack.top();  
  117.             printf("%c ",p->data);  
  118.             stack.pop();  
  119.             //访问右子树  
  120.             p = p->rchild;  
  121.         }  
  122.     }//while  
  123. }  
  124.   
  125. //后序遍历(非递归)  
  126. typedef struct BiTNodePost{  
  127.     BiTree biTree;  
  128.     char tag;  
  129. }BiTNodePost,*BiTreePost;  
  130.   
  131. void PostOrder2(BiTree T){  
  132.     stack<BiTreePost> stack;  
  133.     //p是遍历指针  
  134.     BiTree p = T;  
  135.     BiTreePost BT;  
  136.     //栈不空或者p不空时循环  
  137.     while(p != NULL || !stack.empty()){  
  138.         //遍历左子树  
  139.         while(p != NULL){  
  140.             BT = (BiTreePost)malloc(sizeof(BiTNodePost));  
  141.             BT->biTree = p;  
  142.             //访问过左子树  
  143.             BT->tag = 'L';  
  144.             stack.push(BT);  
  145.             p = p->lchild;  
  146.         }  
  147.         //左右子树访问完毕访问根节点  
  148.         while(!stack.empty() && (stack.top())->tag == 'R'){  
  149.             BT = stack.top();  
  150.             //退栈  
  151.             stack.pop();  
  152.             printf("%c ",BT->biTree->data);  
  153.         }  
  154.         //遍历右子树  
  155.         if(!stack.empty()){  
  156.             BT = stack.top();  
  157.             //访问过右子树  
  158.             BT->tag = 'R';  
  159.             p = BT->biTree;  
  160.             p = p->rchild;  
  161.         }  
  162.     }//while  
  163. }  
  164. //层次遍历  
  165. void LevelOrder(BiTree T){  
  166.     BiTree p = T;  
  167.     //队列  
  168.     queue<BiTree> queue;  
  169.     //根节点入队  
  170.     queue.push(p);  
  171.     //队列不空循环  
  172.     while(!queue.empty()){  
  173.         //对头元素出队  
  174.         p = queue.front();  
  175.         //访问p指向的结点  
  176.         printf("%c ",p->data);  
  177.         //退出队列  
  178.         queue.pop();  
  179.         //左子树不空,将左子树入队  
  180.         if(p->lchild != NULL){  
  181.             queue.push(p->lchild);  
  182.         }  
  183.         //右子树不空,将右子树入队  
  184.         if(p->rchild != NULL){  
  185.             queue.push(p->rchild);  
  186.         }  
  187.     }  
  188. }  
  189. int main()  
  190. {  
  191.     BiTree T;  
  192.     CreateBiTree(T);  
  193.     printf("先序遍历:\n");  
  194.     PreOrder(T);  
  195.     printf("\n");  
  196.     printf("先序遍历(非递归):\n");  
  197.     PreOrder2(T);  
  198.     printf("\n");  
  199.     printf("中序遍历:\n");  
  200.     InOrder(T);  
  201.     printf("\n");  
  202.     printf("中序遍历(非递归):\n");  
  203.     InOrder2(T);  
  204.     printf("\n");  
  205.     printf("后序遍历:\n");  
  206.     PostOrder(T);  
  207.     printf("\n");  
  208.     printf("后序遍历(非递归):\n");  
  209.     PostOrder2(T);  
  210.     printf("\n");  
  211.     printf("层次遍历:\n");  
  212.     LevelOrder(T);  
  213.     printf("\n");  
  214.     return 0;  
  215. }  
#include<iostream>
#include<stack>
#include<queue>
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);
	}
}
/* 先序遍历(非递归)
   思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
*/
void PreOrder2(BiTree T){
	stack<BiTree> stack;
	//p是遍历指针
	BiTree p = T;
	//栈不空或者p不空时循环
	while(p || !stack.empty()){
		if(p != NULL){
			//存入栈中
			stack.push(p);
			//访问根节点
			printf("%c ",p->data);
			//遍历左子树
			p = p->lchild;
		}
		else{
			//退栈
			p = stack.top();
			stack.pop();
			//访问右子树
			p = p->rchild;
		}
	}//while
}
/* 中序遍历(非递归)
   思路:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
         先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
*/
void InOrder2(BiTree T){
	stack<BiTree> stack;
	//p是遍历指针
	BiTree p = T;
	//栈不空或者p不空时循环
	while(p || !stack.empty()){
		if(p != NULL){
			//存入栈中
			stack.push(p);
			//遍历左子树
			p = p->lchild;
		}
		else{
			//退栈,访问根节点
			p = stack.top();
			printf("%c ",p->data);
			stack.pop();
			//访问右子树
			p = p->rchild;
		}
	}//while
}

//后序遍历(非递归)
typedef struct BiTNodePost{
	BiTree biTree;
	char tag;
}BiTNodePost,*BiTreePost;

void PostOrder2(BiTree T){
	stack<BiTreePost> stack;
	//p是遍历指针
	BiTree p = T;
	BiTreePost BT;
	//栈不空或者p不空时循环
	while(p != NULL || !stack.empty()){
		//遍历左子树
		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;
		}
	}//while
}
//层次遍历
void LevelOrder(BiTree T){
	BiTree p = T;
	//队列
	queue<BiTree> queue;
	//根节点入队
	queue.push(p);
	//队列不空循环
	while(!queue.empty()){
		//对头元素出队
		p = queue.front();
		//访问p指向的结点
		printf("%c ",p->data);
		//退出队列
		queue.pop();
		//左子树不空,将左子树入队
		if(p->lchild != NULL){
			queue.push(p->lchild);
		}
		//右子树不空,将右子树入队
		if(p->rchild != NULL){
			queue.push(p->rchild);
		}
	}
}
int main()
{
	BiTree T;
	CreateBiTree(T);
	printf("先序遍历:\n");
	PreOrder(T);
	printf("\n");
	printf("先序遍历(非递归):\n");
	PreOrder2(T);
	printf("\n");
	printf("中序遍历:\n");
	InOrder(T);
	printf("\n");
	printf("中序遍历(非递归):\n");
	InOrder2(T);
	printf("\n");
	printf("后序遍历:\n");
	PostOrder(T);
	printf("\n");
	printf("后序遍历(非递归):\n");
	PostOrder2(T);
	printf("\n");
	printf("层次遍历:\n");
	LevelOrder(T);
	printf("\n");
    return 0;
}


新版:点击打开链接



66
3
 
 
我的同类文章
http://blog.csdn.net 更多文章

参考知识库

img
软件测试知识库

img
算法与数据结构知识库

更多资料请参考:
猜你在找
数据结构基础系列(3):栈和队列
数据结构基础系列(6):树和二叉树
C语言系列之 数据结构栈的运用
数据结构和算法
数据结构与算法在实战项目中的应用
关闭
查看评论
34楼 qq_36693849 2016-11-13 10:28发表 [回复] [引用] [举报]
如何增加一个判断功能 即判断键盘输入的二叉树是否合法
33楼 赵尽朝 2016-10-30 21:36发表 [回复] [引用] [举报]
代码很清晰,非常感谢楼主。
32楼 赵尽朝 2016-10-30 20:58发表 [回复] [引用] [举报]
前序遍历和后序遍历中叶子节点的顺序是一致的吗?
31楼 AnXT 2016-08-25 21:57发表 [回复] [引用] [举报]
因为你输入的时候每敲一个数字后面跟了一个回车吧?scanf函数会把回车符返回输入流中,下次就从剩余的那个回车符开始读,但是回车符是读不进去的,所以就一直停在那里了,加一个小函数就行了void eatline()
{
while (getchar()!='\n')
{
getchar();
}
}
30楼 烟花散尽13141 2016-08-25 11:09发表 [回复] [引用] [举报]
东西很不错,和我的一个观点,大家也可以看看我的,在我的博客里
29楼 二叉树 2016-07-12 11:06发表 [回复] [引用] [举报]
代码写的不错,就是非递归的后序遍历是不是有内存泄露?另外加一个销毁二叉树的函数就更好了
28楼 07H_JH 2016-06-20 22:24发表 [回复] [引用] [举报]
博主是西电的吧
27楼 07H_JH 2016-06-20 22:23发表 [回复] [引用] [举报]
博主是西电的吗
26楼 大杰瑞_TEL 2016-06-08 10:09发表 [回复] [引用] [举报]
  1. //输出    
  2. void Visit(BiTree T){    
  3.     if(T->data != '#'){    
  4.         printf("%c ",T->data);    
  5.     }    
  6. }    
//输出  
void Visit(BiTree T){  
    if(T->data != '#'){  
        printf("%c ",T->data);  
    }  
}  

您好,这段代码T->data好像应该永远等于不了‘#’,因为当时创建树,判断新建树节点T输入#值的时候,T就指向了NULL;
不知是否存在这个问题。
25楼 尼晓健 2016-04-13 17:21发表 [回复] [引用] [举报]
建议楼主将二叉树的构建采用的是中序遍历构造的,这点说一下,不然容易让人对于二叉树的构建理解不了。
24楼 mnbvcxz_lkjhgfdsa 2015-12-25 11:24发表 [回复] [引用] [举报]
#include<iostream>
#include<stack>
#include<queue>
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 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);
}
}
新手不懂为什么会这么多错误
23楼 happy的涵 2015-11-26 19:01发表 [回复] [引用] [举报]
写的很棒,受益匪浅
22楼 K_9527 2015-11-25 19:48发表 [回复] [引用] [举报]
博主你好,我对程序中的创建函数有些疑问,想问下int CreateBiTree(BiTree &T)中的符号“&”是表示引用还是表示取地址?
我的想法是将T的地址传进函数,这样才可以去改变T的值。
21楼 ww_hahha 2015-10-23 11:26发表 [回复] [引用] [举报]
谢谢,学习了!
20楼 str_yyn 2015-10-01 23:09发表 [回复] [引用] [举报]
大赞
19楼 ziyuxuan7177 2015-07-08 22:19发表 [回复] [引用] [举报]
试了一下
一直处于输入状态
18楼 txdzdlxx 2015-04-22 20:32发表 [回复] [引用] [举报]
gooooooooooooooooooooooooood
17楼 wang1shuang2cheng3 2015-04-21 14:13发表 [回复] [引用] [举报]
ths
16楼 Nitpicking 2015-04-13 21:38发表 [回复] [引用] [举报]
楼主,不知您代码跑通了么? 为什么我非要把scanf("%c",&data); 改成 cin>>data;才能跑通?否则一直处于输入状态。。。。有人和我一样的么?
还有,楼主写博客是怎么把代码写的那么漂亮的?
Re: baidu_32784641 2015-11-13 15:44发表 [回复] [引用] [举报]
回复Nitpicking:我就是这个问题,请问怎么解决啊?
Re: sjf0115 2015-07-11 14:43发表 [回复] [引用] [举报]
回复Nitpicking:很长时间了,应该能跑通的。
15楼 独孤_子喻 2015-03-30 12:09发表 [回复] [引用] [举报]
清楚明了。 感谢。
14楼 Gave_Ge 2015-02-14 21:15发表 [回复] [引用] [举报]
楼猪。。。。BT->biTree=NULL;少写了个NULL;快醒醒。。。。都陷入死循环了呢;
13楼 qq_24027947 2014-12-13 10:59发表 [回复] [引用] [举报]
12楼 qq_23590961 2014-11-20 15:18发表 [回复] [引用] [举报]
好东西啊,顶起来
11楼 huzi741 2014-10-20 17:48发表 [回复] [引用] [举报]
代码很清晰,非常感谢楼主。
10楼 long_Xu_Oracle 2014-10-20 10:27发表 [回复] [引用] [举报]
写的非常好,非常详细,感谢楼主分享
9楼 李大学heart 2014-10-18 16:15发表 [回复] [引用] [举报]
写的非常好,想问下啊int CreateBiTree(BiTree &T)与int CreateBiTree(BiTree T) 之间的区别是什么
Re: Gave_Ge 2015-02-12 09:43发表 [回复] [引用] [举报]
回复qq_17672863:这里应该是必须要引用吧,因为你需要返回一个BiTree级别的。。所以必须用**或者&*;
8楼 jdkwky 2014-10-13 22:28发表 [回复] [引用] [举报]
学习加收藏,谢谢博主了
7楼 浸在咫尺 2014-09-03 10:26发表 [回复] [引用] [举报]
必须得顶!!
6楼 SmileLing~ 2014-08-14 15:15发表 [回复] [引用] [举报]
值得学习学习
5楼 yulinxx 2014-07-21 23:12发表 [回复] [引用] [举报]
非常不错 . 逻辑清晰 有图有码 转之~~~~
4楼 曦花 2014-06-28 14:05发表 [回复] [引用] [举报]
while(!stack.empty() && (stack.top())->tag == 'R'){
BT = stack.top();
//退栈
stack.pop();
BT->biTree; -----笔误还是??
printf("%c ",BT->biTree->data);
}

在非递归的后序遍历中,
while循环里的第二个while循环里,
BT->biTree; 这是什么意思?为什么单独一行?
笔误还是??
Re: sjf0115 2015-07-11 14:44发表 [回复] [引用] [举报]
回复wangyunxiaoyu:可能是多加了一行。。。。。。你去掉试试
3楼 未提交的遗漏者 2014-05-07 22:43发表 [回复] [引用] [举报]
注释太好了,对理解非常有帮助
2楼 edgargwj 2014-04-17 14:18发表 [回复] [引用] [举报]
感谢博主
1楼 andrewcarmack 2014-03-23 12:11发表 [回复] [引用] [举报]
代码写的很好;非常清晰明了!给32个赞
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
  • 个人资料
    • 访问:2337606次
    • 积分:26778
    • 等级:
      积分:26778
    • 排名:第185名
    • 原创:496篇
    • 转载:223篇
    • 译文:0篇
    • 评论:550条
  • 博客专栏
  • 最新评论
您有 0条新通知
收藏助手

提问

您的问题将会被发布在“技术问答”频道 ×
该问题已存在,请勿重复提问
插入图片
| | | | | |
  
0 0 0:0
推荐标签:
我要悬赏
取消 发布
可能存在类似的问题:

保存代码片

整理和分享保存的代码片,请访问代码笔记
  • *标题
  • *描述
  •  标签
    算法x
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值