最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

二叉樹先序遍歷的非遞歸算法具體實(shí)現(xiàn)

 更新時(shí)間:2014年01月09日 15:22:56   作者:  
這篇文章主要介紹了二叉樹先序遍歷的非遞歸算法,有需要的朋友可以參考一下

在前面一文,說(shuō)過二叉樹的遞歸遍歷算法(二叉樹先根(先序)遍歷的改進(jìn)),此文主要講二叉樹的非遞歸算法,采用棧結(jié)構(gòu)

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

1)入棧,主要是先頭結(jié)點(diǎn)入棧,然后visit此結(jié)點(diǎn)

2)while,循環(huán)遍歷當(dāng)前結(jié)點(diǎn),直至左孩子沒有結(jié)點(diǎn)

3)if結(jié)點(diǎn)的右孩子為真,轉(zhuǎn)入1)繼續(xù)遍歷,否則退出當(dāng)前結(jié)點(diǎn)轉(zhuǎn)入父母結(jié)點(diǎn)遍歷轉(zhuǎn)入1)

先看符合此思想的算法:

復(fù)制代碼 代碼如下:

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); //如果此時(shí)棧已空,就有問題
  }
  pBiNode = pBiNode->rchild;
 }

 return 0;
}

注意:1)這里使用了棧結(jié)構(gòu),可參看上文順序結(jié)構(gòu)存儲(chǔ)的棧

            2)這里在保存結(jié)點(diǎn)的時(shí)候,我保存的是指針也就是結(jié)點(diǎn)的地址,將其變?yōu)閕nt型存儲(chǔ),在pop的時(shí)候里面使用的是指針,所以取的是&pBiNode,而不是pBiNode,為什么請(qǐng)自行思考指針的使用,最好理解的就是BiTNode *pBiNode;定義改為BiTree pBiNode就很好理解了。


上面這個(gè)算法其實(shí)是錯(cuò)誤的!為什么呢? 這里我檢查好久,期間出現(xiàn)還出現(xiàn)過無(wú)限循環(huán),也出現(xiàn)過從左子樹退出后右邊子樹不顯示,最后我修改了第一個(gè)while判斷條件,為什么呢?因?yàn)槿绻趐op之后,棧已空但是右子樹還有,就無(wú)法繼續(xù)了,這個(gè)在我寫出后并沒有進(jìn)行太多驗(yàn)證,后面再闡述,這里并沒有壓入null指針,看一下壓入空指針的例子,主要是左子樹為空的時(shí)候才壓入棧的,如下:

復(fù)制代碼 代碼如下:

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;
}

這里是這樣的,先壓入根節(jié)點(diǎn),然后判斷左子樹是否為空,不為空就壓入棧,否則退出while循環(huán)之后就將NULL結(jié)點(diǎn)出棧,再判斷當(dāng)前棧是否為空,如果非空就出棧得到父節(jié)點(diǎn)然后判斷右孩子,壓入右孩子結(jié)點(diǎn),再判斷此右子樹的左孩子是否為空,繼續(xù)循環(huán)。

這里有兩個(gè)浪費(fèi)的地方:一個(gè)就是壓入空孩子結(jié)點(diǎn)入棧,二就是頻繁使用GetTop獲得棧頂元素


這里返回過來(lái)再看初開始設(shè)計(jì)的算法,那里正好沒有壓入NULL指針或者說(shuō)空的孩子結(jié)點(diǎn),但是并不能輸出完整,這里我們想到可以在判斷棧的時(shí)候加入,當(dāng)前的結(jié)點(diǎn)是否為NULL就可以了,這樣就不會(huì)出現(xiàn)不會(huì)顯示退出左子樹結(jié)點(diǎn)不能顯示右子樹結(jié)點(diǎn)的尷尬了,如下:

復(fù)制代碼 代碼如下:

//非遞歸先序遍歷二叉樹
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); //如果此時(shí)棧已空,就有問題
  }
  pBiNode = pBiNode->rchild;
 }
 return 0;
}

在第一個(gè)while循環(huán)加入這個(gè)之后,就可以了,測(cè)試用例與二叉樹先序遍歷類似。如下測(cè)試上節(jié)的二叉樹例子:

此時(shí)輸入的數(shù)據(jù)仍然還是 12 34 0 0 78 0 0,測(cè)試結(jié)果如下:


--- 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

這個(gè)還不足以測(cè)試,再看如下的二叉樹

此時(shí)輸入數(shù)據(jù)應(yīng)該為:12 34 24 0 0 50 0 0 78 37 0 0 0,測(cè)試結(jié)果如下:

--- 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

由先序遍歷可知,正好是正確的,另外這些算法不光是對(duì)先序遍歷的,如果想變?yōu)橹行蚧蛘吆笮颍恍鑼⑸厦嫠惴ㄖ械膙isit之類的先去掉,然后將它加入合適的位置,就可以了

相關(guān)文章

  • 小程序?qū)崿F(xiàn)人臉識(shí)別的項(xiàng)目實(shí)踐

    小程序?qū)崿F(xiàn)人臉識(shí)別的項(xiàng)目實(shí)踐

    人臉識(shí)別在現(xiàn)在很多地方都可以用的到,例如支付,解鎖等,本文就來(lái)介紹一下小程序?qū)崿F(xiàn)人臉識(shí)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • Javascript中的prototype與繼承

    Javascript中的prototype與繼承

    本文主要介紹了Javascript中的prototype與繼承,具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 微信小程序checkbox組件使用詳解

    微信小程序checkbox組件使用詳解

    這篇文章主要介紹了微信小程序checkbox組件的使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • javascript基本包裝類型介紹

    javascript基本包裝類型介紹

    這篇文章主要介紹了javascript的基本包裝類型,JS為了便于操作基本類型,提供了3個(gè)特殊的引用類型:Boolean/Number和String,需要的朋友可以參考下
    2015-04-04
  • 詳解javascript立即執(zhí)行函數(shù)表達(dá)式IIFE

    詳解javascript立即執(zhí)行函數(shù)表達(dá)式IIFE

    本文主要介紹了javascript立即執(zhí)行函數(shù)表達(dá)式IIFE的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • javascript中indexOf技術(shù)詳解

    javascript中indexOf技術(shù)詳解

    indexOf()函數(shù)用于查找子字符串在當(dāng)前字符串中第一次出現(xiàn)的位置。該函數(shù)屬于String對(duì)象,所有主流瀏覽器均支持該函數(shù)。下面我們就來(lái)詳細(xì)探討下javascript的index0f()函數(shù)
    2015-05-05
  • 詳解微信小程序膠囊按鈕返回|首頁(yè)自定義導(dǎo)航欄功能

    詳解微信小程序膠囊按鈕返回|首頁(yè)自定義導(dǎo)航欄功能

    對(duì)于一些電商平臺(tái)來(lái)說(shuō),當(dāng)商品被轉(zhuǎn)發(fā)后會(huì)很影響客戶查看其它產(chǎn)品和首頁(yè),這時(shí)候就需要使用自定義導(dǎo)航欄自己寫一個(gè)“膠囊按鈕”。這篇文章主要介紹了詳見微信小程序膠囊按鈕返回|首頁(yè)自定義導(dǎo)航欄,需要的朋友可以參考下
    2019-06-06
  • 小程序原生實(shí)現(xiàn)左滑抽屜菜單

    小程序原生實(shí)現(xiàn)左滑抽屜菜單

    在移動(dòng)端,側(cè)滑菜單是一個(gè)很常用的組件,本文就詳細(xì)的介紹小程序原生實(shí)現(xiàn)左滑抽屜菜單,具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-07-07
  • javascript的函數(shù)

    javascript的函數(shù)

    javascript的函數(shù)...
    2006-07-07
  • d3.js實(shí)現(xiàn)立體柱圖的方法詳解

    d3.js實(shí)現(xiàn)立體柱圖的方法詳解

    這篇文章主要給大家介紹了利用d3.js實(shí)現(xiàn)立體柱圖的方法,文中給出了詳細(xì)的介紹和示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來(lái)一起看看吧。
    2017-04-04

最新評(píng)論

邢台县| 商河县| 新昌县| 团风县| 千阳县| 彰化市| 深圳市| 禹城市| 东乡县| 静安区| 朔州市| 焉耆| 巴彦县| 邵阳市| 廉江市| 安徽省| 大余县| 中超| 夏河县| 商洛市| 儋州市| 景德镇市| 德化县| 微博| 澄迈县| 丽水市| 榕江县| 宁都县| 望谟县| 鹤岗市| 茌平县| 尼玛县| 大名县| 太仓市| 惠东县| 酒泉市| 博野县| 福州市| 太康县| 河源市| 渭南市|