zoukankan      html  css  js  c++  java
  • 非递归实现树的遍历

    方法1:使用指针

    View Code
      1 #include <iostream>
      2 using namespace std;
      3 
      4 struct node
      5 {
      6 int key;
      7 node *left;
      8 node *right;
      9 node *parent;
     10 node(){}
     11 node(int x):key(x),left(NULL),right(NULL){}
     12 };
     13 
     14 struct tree
     15 {
     16 node *root;
     17 tree():root(NULL){}
     18 };
     19 
     20 void Tree_Print(tree *T)
     21 {
     22 node *t = T->root;
     23 while(t)
     24 {
     25 if(t->left)
     26 {
     27 t = t->left;
     28 continue;
     29 }
     30 else
     31 {
     32 cout<<t->key<<' ';
     33 if(t->right)
     34 {
     35 t = t->right;
     36 continue;
     37 }
     38 while(1)
     39 {
     40 
     41 if(t == t->parent->left && t->parent->right)
     42 {
     43 cout<<t->parent->key<<' ';
     44 t = t->parent->right;
     45 break;
     46 }
     47 
     48 if(t == t->parent->left && t->parent->right == NULL)
     49 cout<<t->parent->key<<' ';
     50 t = t->parent;
     51 if(t == T->root)
     52 {
     53 cout<<endl;
     54 return;
     55 }
     56 }
     57 }
     58 }
     59 }
     60 /*input:0=NIL
     61 12 7 3
     62 15 8 0
     63 4 10 0
     64 10 5 9
     65 2 0 0
     66 18 1 4
     67 7 0 0
     68 14 6 2
     69 21 0 0
     70 5 0 0
     71 */
     72 int main()
     73 {
     74 //    构造一棵树按照10.4-1
     75 int i;
     76 node A[11];//这个数组仅仅用于构造10.4-1中的树,在遍历时不使用
     77 for(i = 1; i <= 10; i++)
     78 {
     79 int key, left, right;
     80 cin>>key>>left>>right;
     81 A[i].key = key;
     82 if(left)
     83 {
     84 A[i].left = &A[left];
     85 A[left].parent = &A[i];
     86 }
     87 else 
     88 A[i].left = NULL;
     89 if(right)
     90 {
     91 A[i].right = &A[right];
     92 A[right].parent = &A[i];
     93 }
     94 else A[i].right = NULL;
     95 }
     96 //生成一棵树
     97 tree *T = new tree();
     98 T->root = &A[6];
     99 10.4-5
    100 Tree_Print(T);
    101 system("pause");
    102 return 0;
    103 }

    方法2:使用栈实现

    View Code
      1 #include<iostream>
      2 #include <malloc.h>
      3 
      4 typedef struct _Bin_Tree
      5 {
      6 _Bin_Tree *pLeft;
      7 _Bin_Tree *pRight;
      8 int nData;
      9 }Bin_Tree;
     10 
     11 typedef struct _STACK
     12 {
     13 Bin_Tree *pData;
     14 _STACK *pNext;
     15 } STACK;
     16 
     17 //将一个节点置0
     18 void ZeroNode(Bin_Tree *pNode)
     19 {
     20 pNode->nData = 0;
     21 pNode->pLeft = 0;
     22 pNode->pRight = 0;
     23 }
     24 
     25 
     26 void CreateATree(Bin_Tree *pNode,int n)
     27 {
     28 Bin_Tree *pLeft=0,*pRight=0;
     29 if ( pNode == 0 ) return;
     30 
     31 pLeft = (_Bin_Tree *)malloc( sizeof(Bin_Tree) );
     32 ZeroNode( pLeft );
     33 pLeft->nData = n;
     34 pRight = (_Bin_Tree *)malloc( sizeof(Bin_Tree) );
     35 ZeroNode( pRight );
     36 pRight->nData = n+1;
     37 
     38 pNode->pLeft = pLeft;
     39 pNode->pRight = pRight;
     40 }
     41 
     42 //释放一个二叉树所占的内存
     43 void ReleaseTree(Bin_Tree **pNode)
     44 {
     45 if ( (*pNode) == 0 ) return;
     46 ReleaseTree( &((*pNode)->pLeft) );
     47 ReleaseTree( &((*pNode)->pRight) );
     48 free( (*pNode) );
     49 (*pNode) = 0;
     50 }
     51 
     52 //压栈
     53 void push( STACK * pS,STACK **pTop )
     54 {
     55 if( (*pTop) == 0 )
     56 {
     57 (*pTop) = pS;
     58 }
     59 else
     60 {
     61 pS->pNext = *pTop;
     62 (*pTop) = pS;//将栈指针上移
     63 }
     64 }
     65 
     66 //出栈
     67 STACK * pop( STACK **pTop )
     68 {
     69 if ( (*pTop) == 0 ) return 0;
     70 (*pTop) = (*pTop)->pNext;//栈顶指针下移
     71 return (*pTop);
     72 }
     73 
     74 //栈遍历前序
     75 //最要思想:
     76 //第一步将树的左分支的左节点压入栈,最后栈顶将是树最左边节点
     77 //然后从底部将栈中的每个节点放弹出,遍历其右节点,如果右节点还有分支,重复第一步.
     78 void PreOrder_stack( Bin_Tree *pRoot )
     79 {
     80 STACK *pSTop=0,*pSTemp=0;
     81 Bin_Tree *pTemp = pRoot;
     82 if ( pRoot == 0) return;
     83 
     84 while ( pTemp || pSTop != 0 )
     85 {
     86 if( pTemp )
     87 {
     88 STACK *pStack = (STACK *)malloc( sizeof( STACK ) );
     89 pStack->pData = pTemp;
     90 pStack->pNext = 0;
     91 printf("%d,",pTemp->nData);
     92 push( pStack, &pSTop );
     93 pTemp = pTemp->pLeft;
     94 }
     95 else
     96 {
     97 Bin_Tree *pSubRight = pSTop->pData->pRight;
     98 pSTemp = pSTop;
     99 pSTop = pop( &pSTop );
    100 pTemp = pSubRight;
    101 free(pSTemp);
    102 pSTemp = 0;
    103 }
    104 }
    105 }
    106 
    107 //栈遍历中序
    108 //主要思想是将按左边寻址的方式,进行寻址,将每个节点压入栈。
    109 //当左子到头后,再出弹栈,这样必然是先左、后中,再右。
    110 void InOrder_stack( Bin_Tree *pRoot )
    111 {
    112 STACK *pSTop=0,*pSTemp=0;
    113 Bin_Tree *pTemp = pRoot;
    114 if ( pRoot == 0) return;
    115 
    116 while ( pTemp || pSTop != 0 )
    117 {
    118 if( pTemp )
    119 {
    120 STACK *pStack = (STACK *)malloc( sizeof( STACK ) );
    121 pStack->pData = pTemp;
    122 pStack->pNext = 0;
    123 push( pStack, &pSTop );
    124 pTemp = pTemp->pLeft;
    125 }
    126 else
    127 {
    128 pSTemp = pSTop;
    129 pSTop = pop( &pSTop );
    130 printf("%d,",pSTemp->pData->nData);
    131 pTemp = pSTemp->pData->pRight;
    132 free(pSTemp);
    133 pSTemp = 0;
    134 }
    135 }
    136 }
    137 
    138 //栈遍历后序
    139 //主要思想是先遍历左右两个子树,再遍历根节点。
    140 //后序遍历有一个需要主意的地方,就是从右树遍历完后,
    141 //开始弹栈的时候,需要加一个pPre标记,该无数已经访问过,否则无法遍历完成。
    142 void PostOrder_stack( Bin_Tree *pRoot )
    143 {
    144 STACK *pSTop=0,*pSTemp=0;
    145 Bin_Tree *pTemp = pRoot, *pPre=0;
    146 if ( pRoot == 0) return;
    147 
    148 while ( pTemp || pSTop != 0 )
    149 {
    150 while( pTemp )
    151 {//遍历左子树
    152 STACK *pStack = (STACK *)malloc( sizeof( STACK ) );
    153 pStack->pData = pTemp;
    154 pStack->pNext = 0;
    155 push( pStack, &pSTop );
    156 pTemp = pTemp->pLeft;
    157 }
    158 if ( pSTop->pData->pRight == 0 || pPre == pSTop->pData->pRight )
    159 {//没有右子树或该节点刚被访问过
    160 printf("%d,", pSTop->pData->nData);
    161 pSTemp = pSTop;
    162 pPre = pSTop->pData;
    163 pSTop = pop( &pSTop );
    164 pSTemp = 0;
    165 }
    166 else
    167 {
    168 pTemp = pSTop->pData->pRight;
    169 }
    170 }
    171 }
    172 
    173  
  • 相关阅读:
    随机数组找丢失数据
    js打开新页面 关闭当前页 关闭父页面
    Markdown测试
    ThinkPHP中的时间自动填充 无法获取时间
    页面在谷歌浏览器和IE浏览器顶部多出空白行,火狐显示正常
    Thinkphp中验证码不显示解决办法
    106运用SWITCH语句打印星期几的单词
    声明两个变量并赋值计算出矩形的面积
    不用*用移位运算符计算21*16的数值是多少
    97.经典实例,计算球形的面积和体积
  • 原文地址:https://www.cnblogs.com/sanshuiyijing/p/3017852.html
Copyright © 2011-2022 走看看