可可西

二叉树遍历算法

1. 前序/中序/后序遍历(递归实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 前序遍历
void BT_PreOrder(BiTreePtr pNode)
{
    if (!pNode)  return;
     
    visit(pNode);
    BT_PreOrder(pNode->left);
    BT_PreOrder(pNode->right);  
}
// 中序遍历
void BT_PreOrder(BiTreePtr pNode)
{
    if (!pNode)  return;
     
    BT_PreOrder(pNode->left);
    visit(pNode);
    BT_PreOrder(pNode->right);
}
// 后序遍历
void BT_PreOrder(BiTreePtr pNode)
{
    if (!pNode)  return;
     
    BT_PreOrder(pNode->left);
    BT_PreOrder(pNode->right);
    visit(pNode);
}

2. 前序遍历(非递归实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 用栈实现
void BT_PreOrderNoRec1(BiTreePtr pNode)
{
    stack<BiTreePtr> s;
    while (!pNode || !s.empty())
    {
        if (!pNode)
        {
            visit(pNode);
            s.push(pNode);
            pNode = pNode->left;
        }
        else
        {
            pNode = s.pop();
            pNode = pNode->right;
        }
    }
}
 
// 用栈实现
void BT_PreOrderNoRec2(BiTreePtr pNode)
{
    if (!pNode)
    {
        stack<BiTreePtr> s;
        s.push(pNode);
        while (!s.empty())
        {
            BiTreePtr pvNode = s.pop();
            visit(pvNode);
            s.push(pvNode->right);
            s.push(pvNode->left);
        }
    }
}
 
// 不用栈实现 每个节点含父节点指针和isVisited【默认为false】状态变量 且该二叉树含一个头节点
void BT_PreOrderNoRec3(BiTreePtr pNode)
{
    while (!pNode)// 回溯到指向根节点的头节点时退出
    {
        if( !pNode->bVisited )// 判定是否已被访问
        {  
            visit(pNode);
            pNode->isVisited = true;
        }
        if ( pNode->left && !pNode->left->isVisited )
            pNode = pNode->left;
        else if( pNode->right && !pNode->right->isVisited )
            pNode = pNode->right;
        else   //回溯
            pNode = pNode->parent;
    }
}

3. 中序遍历(非递归实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 用栈实现
void BT_InOrderNoRec1(BiTreePtr pNode)
{
    stack<BiTreePtr> s;
    while (!pNode || !s.empty())
    {
        if (!pNode)
        {
            s.push(pNode);
            pNode = pNode->left;
        }
        else
        {
            pNode = s.pop();
            visit(pNode);
            pNode = pNode->right;
        }
    }
}
// 不用栈实现 每个节点含父节点指针和isVisited【默认为false】的状态变量 且该二叉树含一个头节点
void BT_InOrderNoRec2(BiTreePtr pNode)
{
    while (!pNode) // 回溯到指向根节点的头节点时退出
    {
        while (pNode->left && !pNode->left->isVisited)
            pNode = pNode->left;
        if (!pNode->isVisited)
        {
            visit(pNode);
            pNode->isVisited=true;
        }
        if (pNode->right && !pNode->right->isVisited)
            pNode = pNode->right;
        else
            pNode = pNode->parent;
    }
}

4. 后序遍历(非递归实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void BT_PostOrderNoRec(BiTreePtr pNode)
{
    if(!pNode) return;
 
    stack<BiTreePtr> s;
    s.push(pNode);
 
    while (!s.empty())
    {
        BiTreePtr pvNode = s.pop();
        if (pvNode->isPushed)// 表示其左右子树都已入栈,访问该节点
            visit(pvNode);
        else
        {
            if (pvNode->right)
            {
                pvNode->right->isPushed = false;
                S.push(pvNode->right);
            }
            if (pvNode->left)
            {
                pvNode->left->isPushed = false;
                s.push(pvNode->left);
            }
            pvNode->isPushed = true;
            s.push(pvNode);
        }
    }
}

5. 层序遍历(使用队列)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void BT_LevelOrder(BiTreePtr pNode)
{
    if (!pNode) return;
 
    queue<BiTreePtr> q;
    q.push(pNode);
 
    BiTreePtr pvNode;
    while (!q.empty())
    {
        pvNode = q.pop();
        visit(pvNode);
 
        if (pvNode->left)
            q.push(pvNode->left);   
        if (pvNode->right)
            q.push(pvNode->right);           
    }
}

  参考:http://blog.csdn.net/kofsky/article/details/2886453

              http://www.cppblog.com/ngaut/archive/2006/01/01/2351.aspx

posted on   可可西  阅读(2029)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)

导航

统计信息

点击右上角即可分享
微信分享提示