第一步,先定义链表的链式结构:

typedef struct BiTNode {
    char data ;
    struct BiTNode *lchild , *rchild;
}BiTNode, *BiTree;

第二部,再定义栈的链式结构结构,和栈的基本操作:

typedef struct Snode{
    BiTree  data;
    struct Snode *next;
}Snode , *LinkStack;
//初始化
bool InitStack(LinkStack &s){
    s = NULL;
    return true;
}
//判断是否为空
bool Empty(LinkStack s){
    if(s == NULL) return true;
    return false;
}
//入栈
bool Push(LinkStack &s , BiTree e){
    LinkStack p = new Snode;
    p -> data = e;
    p -> next = s;
    s = p;
    return true;
}
//出栈
bool Pop(LinkStack &s , BiTree &e){
    if(Empty(s)) return false;
    e = s->data;
    LinkStack p = s;
    s = s->next;
    delete p;
    return true;
}
//取栈顶元素
BiTree GetTop(LinkStack s){
    return s->data;
}

第三步,用树的先序序列创建二叉树:

void CreateBiTree(BiTree &T){
    char ch;
    cin >> ch;
    if(ch == '#') {
        T = NULL;
    }
    else {
        T = new BiTNode;
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

第四部:中序遍历:

非递归的算法,就是一种用递归的思想,来代替较为浪费时间的递归,本质还是递归
仔细看看课本算法5.2 下面的图,好好理解下,先序和中序都不难,这里就不给大家细讲

void InOrderTraverse (BiTree T) {
    InitStack(s);
    BiTree p = new BiTNode;
    p = T;
    BiTree q = new BiTNode;
//    BiTree q1 = new BiTNode;
    while(p || !Empty(s)){
        if(p) {
            Push(s,p);
            p = p ->lchild;
        }
        else {
            Pop(s,q);

            cout << q->data;
            p = q->rchild;
        }
    }  
}

第五步,先序遍历:

void PriorityTraverse(BiTree T){
    InitStack(s);
    BiTree p = new BiTNode;
    p = T;
    BiTree q = new BiTNode;
//    BiTree q1 = new BiTNode;
    while(p || !Empty(s)){
        if(p) {
            Push(s, p);
            cout << p->data;
            p = p ->lchild;

        }
        else {
            Pop(s,q);
            p = q->rchild;
        }
    }
}

第六步,难点:

二叉树的后序遍历:
我的思路是:
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了 每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
所以代码如下:

void RearTraverse(BiTree T) {
    InitStack(s);
    BiTree p = new BiTNode;
    p = T;
    BiTree q = new BiTNode;
    BiTree q1 = new BiTNode;
    Push(s, p);
    while (!Empty(s)){
        p = GetTop(s);
        if ((p->lchild == NULL&&p->rchild == NULL) ||
                    ((q == p->lchild || q == p->rchild) && q != NULL))
                {
                    cout << p->data;
                    Pop(s, q1);
                    q = p;
                }
        else
                {
                    if (p->rchild != NULL)
                        Push(s,p->rchild);
                    if (p->lchild != NULL)
                        Push(s, p->lchild);
                }
    }
}

当然了,还有一种比较常见的思路,在网上可以找到大家可以看看:

第七步:二叉树的深度;

递归算法,很好理解

int Depth (BiTree T){
    int n=0,m=0;
    if(T == NULL) return 0;
    else{
        m = Depth(T->lchild);
        n = Depth(T->rchild);
    }
    if(m > n)  return m+1;
    else return n+1;
}

第八步:求节点的总度数:

int NodeCount(BiTree T) {
    if(T == NULL) return 0;
    else return NodeCount(T->lchild) + NodeCount(T->rchild)+1;
}

第九步: 求一度节点度数

int one(BiTree bt)
{
    if(bt)
    {
        int ret=0;
        if(bt->lchild)
        {
            ret++;
        }
        if(bt->rchild)
        {
            ret++;
        }

        if(ret==1)
            return one(bt->lchild) + one(bt->rchild) + ret;
        else
            return one(bt->lchild) + one(bt->rchild);
    }
    else
        return 0;
}

第十步:完工main()函数:

int main()
{
    BiTree T = new BiTNode;
    CreateBiTree(T);
    cout << "请输入操作序号:"<<"\n";
    cout << "输入1,先序遍历"<<"\n";
    cout << "输入2,后序遍历" << "\n";
    cout << "输入3,中序遍历"  << "\n";
    cout << "输入4,求树高" <<"\n";
    cout << "输入5,输出,度为1,2,3的个数" << "\n";
    int n ;
    int count = NodeCount(T);
    int on = one(T);
    while(cin>>n && n){
        switch (n) {
            case 1:
                PriorityTraverse(T);
                cout << "\n";
                break;
            case 2:
                RearTraverse(T);
                cout << "\n";
                break;
            case 3:
                InOrderTraverse(T);
                cout << "\n";
                break;
            case 4:
                cout << Depth(T) <<"\n";
                break;
            case 5:
                cout <<(count-on+1)/2-1<<" "<< on<<" " << (count-on+1)/2<<endl;
            default:
                break;
        }
    }
     //
//    PriorityTraverse( T);

//    P(T);
}

//abc##de#g##f###

完整代码:

//
//  main.cpp
//  数据结构实验五
//
//  Created by 宋玉良 on 2020/11/28.
//

#include<bits/stdc++.h>
using namespace std ;
typedef struct BiTNode {
    char data ;
    struct BiTNode *lchild , *rchild;
}BiTNode, *BiTree;

typedef struct Node{
    BiTree btnode;
    bool isfirst;
}Node , *node;

typedef struct Snode{
    BiTree  data;
    struct Snode *next;
}Snode , *LinkStack;
//初始化
bool InitStack(LinkStack &s){
    s = NULL;
    return true;
}
//判断是否为空
bool Empty(LinkStack s){
    if(s == NULL) return true;
    return false;
}
//入栈
bool Push(LinkStack &s , BiTree e){
    LinkStack p = new Snode;
    p -> data = e;
    p -> next = s;
    s = p;
    return true;
}
//出栈
bool Pop(LinkStack &s , BiTree &e){
    if(Empty(s)) return false;
    e = s->data;
    LinkStack p = s;
    s = s->next;
    delete p;
    return true;
}
//取栈顶元素
BiTree GetTop(LinkStack s){
    return s->data;
}
LinkStack s,s1,s2;
void InOrderTraverse (BiTree T) {
    InitStack(s);
    BiTree p = new BiTNode;
    p = T;
    BiTree q = new BiTNode;
//    BiTree q1 = new BiTNode;
    while(p || !Empty(s)){
        if(p) {
            Push(s,p);
            p = p ->lchild;
        }
        else {
            Pop(s,q);

            cout << q->data;
            p = q->rchild;
        }
    }

}
void CreateBiTree(BiTree &T){
    char ch;
    cin >> ch;
    if(ch == '#') {
        T = NULL;
    }
    else {
        T = new BiTNode;
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

void PriorityTraverse(BiTree T){
    InitStack(s);
    BiTree p = new BiTNode;
    p = T;
    BiTree q = new BiTNode;
//    BiTree q1 = new BiTNode;
    while(p || !Empty(s)){
        if(p) {
            Push(s, p);
            cout << p->data;
            p = p ->lchild;

        }
        else {
            Pop(s,q);
            p = q->rchild;
        }
    }
}
void RearTraverse(BiTree T) {
    InitStack(s);
    BiTree p = new BiTNode;
    p = T;
    BiTree q = new BiTNode;
    BiTree q1 = new BiTNode;
    Push(s, p);
    while (!Empty(s)){
        p = GetTop(s);
        if ((p->lchild == NULL&&p->rchild == NULL) ||
                    ((q == p->lchild || q == p->rchild) && q != NULL))
                {
                    cout << p->data;
                    Pop(s, q1);
                    q = p;
                }
        else
                {
                    if (p->rchild != NULL)
                        Push(s,p->rchild);
                    if (p->lchild != NULL)
                        Push(s, p->lchild);
                }
    }
}

int NodeCount(BiTree T) {
    if(T == NULL) return 0;
    else return NodeCount(T->lchild) + NodeCount(T->rchild)+1;
}

int Depth (BiTree T){
    int n=0,m=0;
    if(T == NULL) return 0;
    else{
        m = Depth(T->lchild);
        n = Depth(T->rchild);
    }
    if(m > n)  return m+1;
    else return n+1;
}

int one(BiTree bt)
{
    if(bt)
    {
        int ret=0;
        if(bt->lchild)
        {
            ret++;
        }
        if(bt->rchild)
        {
            ret++;
        }

        if(ret==1)
            return one(bt->lchild) + one(bt->rchild) + ret;
        else
            return one(bt->lchild) + one(bt->rchild);
    }
    else
        return 0;
}


int main()
{
    BiTree T = new BiTNode;
    cout << "请输入您要创建二叉树的先序序列(空指针用#代替)"<< endl;
    CreateBiTree(T);
    cout << "请输入操作序号:"<<"\n";
    cout << "输入1,先序遍历"<<"\n";
    cout << "输入2,后序遍历" << "\n";
    cout << "输入3,中序遍历"  << "\n";
    cout << "输入4,求树高" <<"\n";
    cout << "输入5,输出,度为0,1,2的个数" << "\n";
    int n ;
    int count = NodeCount(T);
    int on = one(T);
    while(cin>>n && n){
        switch (n) {
            case 1:
                PriorityTraverse(T);
                cout << "\n";
                break;
            case 2:
                RearTraverse(T);
                cout << "\n";
                break;
            case 3:
                InOrderTraverse(T);
                cout << "\n";
                break;
            case 4:
                cout << Depth(T) <<"\n";
                break;
            case 5:
                cout <<(count-on+1)/2<<" "<< on<<" " << (count-on+1)/2-1<<endl;
            default:
                break;
        }
    }
     //
//    PriorityTraverse( T);

//    P(T);
}

//输入样例:abc##de#g##f###
//按一棵树的先序序列来输入,空指针用#代替