亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

二叉樹先序遍歷的非遞歸算法具體實現

2019-11-20 21:17:13
字體:
來源:轉載
供稿:網友

在前面一文,說過二叉樹的遞歸遍歷算法(二叉樹先根(先序)遍歷的改進),此文主要講二叉樹的非遞歸算法,采用棧結構

總結先根遍歷得到的非遞歸算法思想如下:

1)入棧,主要是先頭結點入棧,然后visit此結點

2)while,循環遍歷當前結點,直至左孩子沒有結點

3)if結點的右孩子為真,轉入1)繼續遍歷,否則退出當前結點轉入父母結點遍歷轉入1)

先看符合此思想的算法:

復制代碼 代碼如下:

int PreOrderTraverseNonRecursiveEx(const BiTree &T, int (*VisitNode)(TElemType data))
{
 if (T == NULL)
 {
  return -1;
 }

 BiTNode *pBiNode = T;
 SqStack S;
 InitStack(&S);
 Push(&S, (SElemType)T);

 while (!IsStackEmpty(S))
 {
  while (pBiNode)
  {
   VisitNode(pBiNode->data);
   if (pBiNode != T)
   {
    Push(&S, (SElemType)pBiNode);
   }   
   pBiNode = pBiNode->lchild;
  }
  if(pBiNode == NULL)
  {
   Pop(&S, (SElemType*)&pBiNode);
  }  
  if ( pBiNode->rchild == NULL)
  {
   Pop(&S, (SElemType*)&pBiNode); //如果此時棧已空,就有問題
  }
  pBiNode = pBiNode->rchild;
 }

 return 0;
}

注意:1)這里使用了棧結構,可參看上文順序結構存儲的棧

            2)這里在保存結點的時候,我保存的是指針也就是結點的地址,將其變為int型存儲,在pop的時候里面使用的是指針,所以取的是&pBiNode,而不是pBiNode,為什么請自行思考指針的使用,最好理解的就是BiTNode *pBiNode;定義改為BiTree pBiNode就很好理解了。


上面這個算法其實是錯誤的!為什么呢? 這里我檢查好久,期間出現還出現過無限循環,也出現過從左子樹退出后右邊子樹不顯示,最后我修改了第一個while判斷條件,為什么呢?因為如果在pop之后,棧已空但是右子樹還有,就無法繼續了,這個在我寫出后并沒有進行太多驗證,后面再闡述,這里并沒有壓入null指針,看一下壓入空指針的例子,主要是左子樹為空的時候才壓入棧的,如下:

復制代碼 代碼如下:

int PreOrderTraverseNonRecursive(const BiTree &T, int (*VisitNode)(TElemType data))
{
 if (T == NULL)
 {
  return -1;
 }

 BiTNode *pBiNode = T;
 SqStack S;
 InitStack(&S);
 Push(&S, (SElemType)T);

 while (!IsStackEmpty(S))
 {
  GetTop(S, (SElemType*)&pBiNode);
  while (pBiNode)
  {
   VisitNode(pBiNode->data);  
   pBiNode = pBiNode->lchild;
   Push(&S, (SElemType)pBiNode);
  }
  if(pBiNode == NULL)
  {
   Pop(&S, (SElemType*)&pBiNode);
  }  
  if ( !IsStackEmpty(S))
  {
   Pop(&S, (SElemType*)&pBiNode);
   pBiNode = pBiNode->rchild;
   Push(&S, (SElemType)pBiNode);
  }
 }

 return 0;
}

這里是這樣的,先壓入根節點,然后判斷左子樹是否為空,不為空就壓入棧,否則退出while循環之后就將NULL結點出棧,再判斷當前棧是否為空,如果非空就出棧得到父節點然后判斷右孩子,壓入右孩子結點,再判斷此右子樹的左孩子是否為空,繼續循環。

這里有兩個浪費的地方:一個就是壓入空孩子結點入棧,二就是頻繁使用GetTop獲得棧頂元素


這里返回過來再看初開始設計的算法,那里正好沒有壓入NULL指針或者說空的孩子結點,但是并不能輸出完整,這里我們想到可以在判斷棧的時候加入,當前的結點是否為NULL就可以了,這樣就不會出現不會顯示退出左子樹結點不能顯示右子樹結點的尷尬了,如下:

復制代碼 代碼如下:

//非遞歸先序遍歷二叉樹
int PreOrderTraverseNonRecursiveEx(const BiTree &T,
           int (*VisitNode)(TElemType data))
{
 if (T == NULL)
 {
  return -1;
 }

 BiTNode *pBiNode = T;
 SqStack S;
 InitStack(&S);
 Push(&S, (SElemType)T);

 while ( !IsStackEmpty(S) || pBiNode)  //主要修改的就是這句
 {
  while (pBiNode)
  {
   VisitNode(pBiNode->data);
   if (pBiNode != T)
   {
    Push(&S, (SElemType)pBiNode);
   }   
   pBiNode = pBiNode->lchild;
  }
  if(pBiNode == NULL)
  {
   Pop(&S, (SElemType*)&pBiNode);
  }  
  if ( pBiNode->rchild == NULL)
  {
   Pop(&S, (SElemType*)&pBiNode); //如果此時棧已空,就有問題
  }
  pBiNode = pBiNode->rchild;
 }
 return 0;
}

在第一個while循環加入這個之后,就可以了,測試用例與二叉樹先序遍歷類似。如下測試上節的二叉樹例子:

此時輸入的數據仍然還是 12 34 0 0 78 0 0,測試結果如下:


--- BiTree ---
Please Enter BiTree Node data:
12
Please Enter BiTree Node data:
34
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
78
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
12 34 78

這個還不足以測試,再看如下的二叉樹

此時輸入數據應該為:12 34 24 0 0 50 0 0 78 37 0 0 0,測試結果如下:

--- BiTree ---
Please Enter BiTree Node data:
12
Please Enter BiTree Node data:
34
Please Enter BiTree Node data:
24
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
50
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
78
Please Enter BiTree Node data:
37
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
12 34 24 50 78 37

由先序遍歷可知,正好是正確的,另外這些算法不光是對先序遍歷的,如果想變為中序或者后序,只需將上面算法中的visit之類的先去掉,然后將它加入合適的位置,就可以了

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产成人一区| 国产视频精品在线| 欧美亚洲成人精品| 91探花福利精品国产自产在线| 欧美性jizz18性欧美| 亚洲欧洲国产伦综合| 亚洲高清一二三区| 欧美资源在线观看| 久久久久久久影视| 精品国产老师黑色丝袜高跟鞋| 欧美丰满老妇厨房牲生活| 在线看日韩av| 日本a级片电影一区二区| 8x海外华人永久免费日韩内陆视频| 日本乱人伦a精品| 国产成人精品视| 亚洲精品美女在线观看| 成人妇女免费播放久久久| 亚洲欧洲av一区二区| 中国人与牲禽动交精品| 欧美www视频在线观看| 韩剧1988在线观看免费完整版| 92看片淫黄大片欧美看国产片| 国产精品久久99久久| 国产精品福利久久久| 日韩欧美精品在线观看| 这里只有精品丝袜| 亚洲色无码播放| 午夜美女久久久久爽久久| 九九九热精品免费视频观看网站| 日韩成人av一区| 亚洲网址你懂得| 4438全国亚洲精品在线观看视频| 在线观看中文字幕亚洲| 91色琪琪电影亚洲精品久久| 国产精品色悠悠| 2018中文字幕一区二区三区| 久久久久久久久久久久久久久久久久av| 在线日韩欧美视频| 久久激情五月丁香伊人| 日韩美女毛茸茸| 一本一本久久a久久精品牛牛影视| 亚洲色图狂野欧美| 亚洲精品一区av在线播放| 深夜福利日韩在线看| 久久久噜噜噜久久中文字免| 欧美激情成人在线视频| 亚洲精品成人免费| 国产精品999999| 成人444kkkk在线观看| 亚洲加勒比久久88色综合| 欧美精品一区在线播放| 精品自拍视频在线观看| 欧美精品一区在线播放| 中文综合在线观看| 久久精品电影网| 欧美精品videofree1080p| 欧美电影在线观看完整版| 国产在线精品成人一区二区三区| 国产欧美一区二区| 日韩中文视频免费在线观看| 久久久99免费视频| 国产精品美女免费| 久久成人精品一区二区三区| 日韩在线视频网| 亚洲第一精品福利| 亚洲最大福利视频| 欧美成人激情视频免费观看| 日韩av网址在线观看| 亚洲成人网在线观看| 欧美日本高清视频| 日韩欧美中文免费| 欧美精品生活片| 在线观看精品自拍私拍| 国产精品视频网址| 日韩欧美黄色动漫| 亚洲全黄一级网站| 色综合久综合久久综合久鬼88| 国产精品99久久久久久www| 欧美日韩国产一区二区三区| 亚洲曰本av电影| 91色视频在线观看| 在线a欧美视频| 欧美孕妇性xx| 亚洲已满18点击进入在线看片| 国产精品黄页免费高清在线观看| 欧美激情区在线播放| 欧美激情在线播放| 成人综合网网址| 欧美老女人在线视频| 日韩中文字幕av| 社区色欧美激情 | 国产精品视频导航| 日韩一区二区三区在线播放| 欧美成人精品在线| 在线观看亚洲区| 91久久久久久久久久| 亚洲欧美在线一区| 欧美激情一区二区三区在线视频观看| 午夜精品久久久久久久99热| 亚洲色图五月天| 少妇高潮 亚洲精品| 欧美成人精品三级在线观看| 色综合久久精品亚洲国产| 欧美亚洲一区在线| 亚洲夜晚福利在线观看| 国产视频精品一区二区三区| 国产精品免费看久久久香蕉| 亚洲精品国产美女| 精品久久久免费| 亚洲国产精品小视频| 亚洲成人动漫在线播放| 欧美在线视频网| 亚洲国产精品yw在线观看| 欧美日韩国产中文精品字幕自在自线| 欧美黑人性视频| 久久人人爽人人爽爽久久| 国产视频精品va久久久久久| 欧美在线视频播放| 精品爽片免费看久久| 国产z一区二区三区| 精品欧美一区二区三区| 日韩高清免费观看| 这里只有精品在线播放| 中文.日本.精品| 国产一区二区黑人欧美xxxx| 国产精品91一区| 色婷婷亚洲mv天堂mv在影片| 久久久这里只有精品视频| 日本欧美精品在线| 久久久精品久久久| 国产精品无码专区在线观看| 丝袜一区二区三区| 亚洲精品xxx| 亚洲性视频网站| 97久久国产精品| 97国产真实伦对白精彩视频8| 久久久久久这里只有精品| 亚洲桃花岛网站| 97在线视频精品| 九九热精品视频| 九九视频直播综合网| 日本一区二区不卡| 91精品视频专区| 成人免费网视频| 久久久精品国产| 精品国产乱码久久久久久婷婷| 成人xxxxx| 日韩欧美国产高清91| 精品久久久久久亚洲国产300| 中文字幕日韩在线观看| 国产91久久婷婷一区二区| 欧美成人剧情片在线观看| 久久久久久久久久久免费精品| 中文字幕日韩欧美在线| 国产91在线播放精品91| 日韩欧美中文第一页| 神马久久久久久| 欧美理论电影在线播放| 午夜精品久久久久久久久久久久久| 亚洲大胆人体av| 日韩中文字幕在线视频| 国产精品99免视看9| 国产91九色视频|