算法之二叉树各种遍历

CSDN日报20170322——《关于软件研发的一些体会总结》     同步博客至 CSDN ,让更多开发者看到你的文章     看微博技术大咖解析互联网应用架构实战

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

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

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

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

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

    [cpp] view plain copy
    print ?
    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;


    二叉树的创建:

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

    [cpp] view plain copy
    print ?
    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;
    }

    二叉树的遍历:

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

    递归算法:

    [cpp] view plain copy
    print ?
    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的右子树。

    [cpp] view plain copy
    print ?
    1. /* 先序遍历(非递归) 
    2.    思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。 
    3. */  
    4. void PreOrder2(BiTree T){  
    5.     stack 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 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的右子树。

    [cpp] view plain copy
    print ?
    1. void InOrder2(BiTree T){  
    2.     stack 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 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是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。

    [cpp] view plain copy
    print ?
    1. //后序遍历(非递归)  
    2. typedef struct BiTNodePost{  
    3.     BiTree biTree;  
    4.     char tag;  
    5. }BiTNodePost,*BiTreePost;  
    6.   
    7. void PostOrder2(BiTree T){  
    8.     stack 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 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>层次遍历

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

    [cpp] view plain copy
    print ?
    1. //层次遍历  
    2. void LevelOrder(BiTree T){  
    3.     BiTree p = T;  
    4.     //队列  
    5.     queue 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 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###

    输出:


    代码:

    [cpp] view plain copy
    print ?
    1. #include  
    2. #include  
    3. #include  
    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 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 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 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 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
    #include
    #include
    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 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 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 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 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
     
     
    我的同类文章
    算法(53)
    http://blog.csdn.net
    • 算法:字符串消除问题的数学证明2013-11-03阅读1944
    • 算法之素数筛法2013-03-20阅读4425
    • 算法之优先级队列2013-03-16阅读2768
    • 算法之中缀表达式和后缀表达式2013-03-11阅读1426
    • 算法之堆排序2013-02-25阅读1084
    • 算法之最长递增子序列,最长公共子序列2013-03-25阅读3072
    • 浅谈大数的进制转换2013-03-19阅读4972
    • ACM进阶之路2013-03-12阅读2147
    • 算法之二叉树中序前序序列(或后序)求解树2013-03-08阅读11810
    • 算法之快速排序2013-02-22阅读1021
    更多文章

    参考知识库

    软件测试知识库

    4118关注|310收录

    算法与数据结构知识库

    14665关注|2320收录

    更多资料请参考:
    猜你在找
    数据结构基础系列(3):栈和队列
    数据结构基础系列(6):树和二叉树
    C语言系列之 数据结构栈的运用
    数据结构和算法
    数据结构与算法在实战项目中的应用
    算法系列之二二叉树各种遍历
    数据结构与算法 之二叉树二非递归遍历算法
    SDUTOJ 2136--数据结构实验之二叉树的建立与遍历
    数据结构实验之二叉树五层序遍历
    数据结构实验之二叉树五层序遍历
    关闭
    查看评论
    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发表 [回复] [引用] [举报]
    [cpp] view plain copy print ?
    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
    #include
    #include
    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网站的观点或立场
    核心技术类目
    全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPN Spark ERP IE10 Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5 Spring Apache .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech Perl Tornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap
    • 个人资料

    • sjf0115
      4
      • 访问:2337606次
      • 积分:26778
      • 等级:
        积分:26778
      • 排名:第185名
      • 原创:496篇
      • 转载:223篇
      • 译文:0篇
      • 评论:550条
    • 博客专栏
    • 算法之二叉树各种遍历_第1张图片 Android进阶2

      文章:16篇

      阅读:139387
      算法之二叉树各种遍历_第2张图片 Android菜鸟分享

      文章:44篇

      阅读:385265
    • 友情链接
    • 九度OJ
      杭电OJ
      POJ
      天勤OJ
      好友博客:SunnyYoona
    • 文章分类
    • Java系列(2)
    • Android(55)
    • Android进阶(38)
    • Android总结(3)
    • Android进阶2(23)
    • Android开发技巧(7)
    • OJ(70)
    • 算法(54)
    • 九度&天勤OJ(198)
    • Linux(3)
    • 剑指Offer(18)
    • Mysql(0)
    • Hadoop(1)
    • 文章存档
      • 2016年12月(2)
      • 2016年01月(1)
      • 2015年11月(1)
      • 2014年04月(2)
      • 2014年03月(2)
      • 2014年02月(1)
      • 2013年12月(1)
      • 2013年11月(2)
      • 2013年10月(1)
      • 2013年07月(3)
      • 2013年05月(9)
      • 2013年04月(18)
      • 2013年03月(76)
      • 2013年02月(111)
      • 2013年01月(37)
      • 2012年09月(1)
      • 2012年07月(3)
      • 2012年06月(17)
      • 2012年05月(26)
      • 2012年04月(9)
      • 2012年03月(54)
      • 2012年02月(108)
      • 2012年01月(40)
      • 2011年12月(74)
      • 2011年11月(78)
      • 2011年10月(41)
      • 2010年08月(1)
        展开
    • 阅读排行
    • 算法之二叉树各种遍历(125704)
    • Android得到控件在屏幕中的坐标(81831)
    • Android进阶2之Activity之间数据交流(onActivityResult的用法)(43524)
    • Java课程设计之学习成绩管理系统(26990)
    • JVM内存的设置(解决eclipse下out of memory问题)(26596)
    • Android进阶2之 阴影制作(Shadow)(26430)
    • Android学习笔记之滑动翻页(屏幕切换)(24759)
    • android图片特效处理之模糊效果(23515)
    • Android学习笔记之ProgressDialog(21887)
    • Android学习笔记之RatingBar(21710)
    • 评论排行
    • 算法之二叉树各种遍历(38)
    • 计算机复试上机题解题报告(24)
    • Java课程设计之学习成绩管理系统(14)
    • Android学习笔记进阶之在图片上涂鸦(能清屏)(13)
    • Android进阶2之Activity之间数据交流(onActivityResult的用法)(12)
    • Android得到控件在屏幕中的坐标(11)
    • Android进阶2之Http访问网络资源(获取网络图片)(11)
    • 编程之美读书笔记(3) 统计在从1到n的正整数中1出现的次数(10)
    • Android学习笔记之百度地图(周边检索poiSearchNearBy跳转页面并输出搜索结果)(9)
    • android图像处理(3)浮雕效果(9)
    • 最新评论
    • 九度1165 字符串匹配

      haohaohaoxu:试下下面的测试用例5Aaba2BabABBa2bab3AvsSdfaV2SdfAssdfavsdf2...

    • 九度OJ 题目1193:矩阵转置

      ofandof:不是不让使用数组吗?

    • Android得到控件在屏幕中的坐标

      silingcanggui:这个解决大问题了,多谢

    • 九度OJ 题目1206:字符串连接

      Fore_ver:按照题目要求,需要无冗余接受连接两个字符串,同时将这两个字符串无冗余的连接起来。通过数组实现的话,满...

    • 九度OJ 题目1206:字符串连接

      Fore_ver:按照题目要求,需要无冗余接受连接两个字符串,同时将这两个字符串无冗余的连接起来。通过数组实现的话,满...

    • Android学习笔记之图像颜色处理(ColorMatrix)

      zhc_LR:不错,用到了。

    • android图片特效处理之怀旧效果

      Simon347670037:为什么不用颜色矩阵?

    • Android学习笔记进阶16之BitmapShader

      Sugar先生:橙光

    • Android学习笔记进阶之在图片上涂鸦(能清屏)

      qq_34137716:@liangzi7:你看报的什么错,百度一下,就会发现啊,android系统本身是不允许在代码中对r...

    • 算法之素数筛法

      Lhj0616:谢谢分享

    您有 0条新通知
    收藏助手

    提问

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

    保存代码片

    整理和分享保存的代码片,请访问代码笔记
    • *标题
    • *描述
    •  标签
      算法x
    取消 确定

    你可能感兴趣的:(算法之二叉树各种遍历)