1. 程式人生 > >C++實現二叉樹的遞迴與非遞迴遍歷

C++實現二叉樹的遞迴與非遞迴遍歷

#include<iostream>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;

typedef char ElemType;

//二叉樹的二叉連結串列結構,也就是二叉樹的儲存結構,1個數據域,2個指標域(分別指向左右孩子)

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

//二叉樹的建立,按前序遍歷的方式建立二叉樹,當然也可以以中序或後序的方式建立二叉樹
void CreateBiTree(BiTree *T)
{
    ElemType ch;
    cin >> ch;
    if (ch == '#')
        *T = NULL;  //保證是葉結點
    else
    {
        *T = (BiTree)malloc(sizeof(BiTNode));
        //if (!*T)
            //exit(OVERFLOW); //記憶體分配失敗則退出。
        (*T)->data = ch;//生成結點
        CreateBiTree(&(*T)->lchild);//構造左子樹
        CreateBiTree(&(*T)->rchild);//構造右子樹    
    }
}

//表示對遍歷到的結點資料進行的處理操作,此處操作是將樹結點前序遍歷輸出
void operation1(ElemType ch)
{
    cout << ch << " ";
}
//此處在輸出的基礎上,並輸出層數
void operation2(ElemType ch, int level)
{
       cout << ch << "在第" << level << "層" << "  ";
}


//遞迴方式前序遍歷二叉樹 void PreOrderTraverse(BiTree T, int level) { if (T == NULL) return; /*此處表示對遍歷的樹結點進行的操作,根據你自己的要求進行操作,這裡只是輸出了結點的資料*/ operation1(T->data); //operation2(T->data, level); //輸出了層數 PreOrderTraverse(T->lchild, level + 1); PreOrderTraverse(T->rchild, level + 1); } //遞迴方式中序遍歷二叉樹 void InOrderTraverse(BiTree T,int level) { if(T==NULL) return; InOrderTraverse(T->lchild,level+1); operation1(T->data); //operation2(T->data, level); //輸出了層數 InOrderTraverse(T->rchild,level+1); } //遞迴方式後序遍歷二叉樹 void PostOrderTraverse(BiTree T,int level) { if(T==NULL) return; PostOrderTraverse(T->lchild,level+1); PostOrderTraverse(T->rchild,level+1); operation1(T->data); //operation2(T->data, level); //輸出了層數 }
//非遞迴方式前序遍歷 /* 思路:將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,再先序遍歷T的右子樹。*/ void PreOrder(BiTree T){ stack<BiTree> stack; //p是遍歷指標 BiTree p = T; //p不為空或者棧不空時迴圈 while (p || !stack.empty()) { if (p != NULL) { //存入棧中 stack.push(p); //對樹中的結點進行操作 operation1(p->data); //遍歷左子樹 p = p->lchild; } else { //退棧 p = stack.top(); stack.pop(); //訪問右子樹 p = p->rchild; } } } //非遞迴中序遍歷 void InOrder(BiTree T) { stack<BiTree> stack; //p是遍歷指標 BiTree p = T; //p不為空或者棧不空時迴圈 while (p || !stack.empty()) { if (p != NULL) { //存入棧中 stack.push(p); //遍歷左子樹 p = p->lchild; } else { //退棧 p = stack.top(); operation1(p->data); //對樹中的結點進行操作 stack.pop(); //訪問右子樹 p = p->rchild; } } } //非遞迴後序遍歷 typedef struct BiTNodePost{ BiTree biTree; char tag; }BiTNodePost, *BiTreePost; void PostOrder(BiTree T) { stack<BiTreePost> stack; //p是遍歷指標 BiTree p = T; BiTreePost BT; //棧不空或者p不空時迴圈 while (p != NULL || !stack.empty()) { //遍歷左子樹 while (p != NULL) { BT = (BiTreePost)malloc(sizeof(BiTNodePost)); BT->biTree = p; //訪問過左子樹 BT->tag = 'L'; stack.push(BT); p = p->lchild; } //左右子樹訪問完畢訪問根節點 while (!stack.empty() && (stack.top())->tag == 'R') { BT = stack.top(); //退棧 stack.pop(); BT->biTree; cout<<BT->biTree->data<<" "; } //遍歷右子樹 if (!stack.empty()) { BT = stack.top(); //訪問過右子樹 BT->tag = 'R'; p = BT->biTree; p = p->rchild; } } }
//層次遍歷 void LevelOrder(BiTree T) { BiTree p = T; queue<BiTree> queue; //根節點入隊 queue.push(p); //佇列不空迴圈
// 迴圈使用入隊出隊操作
    while (!queue.empty())
       {
        //對頭元素出隊  
        p = queue.front();
        //訪問p指向的結點  
        operation1(p->data);
        //退出佇列  
        queue.pop();
        //左孩子不為空,將左孩子入隊  
        if (p->lchild != NULL)
                {
            queue.push(p->lchild);
        }
        //右孩子不空,將右孩子入隊  
        if (p->rchild != NULL)
                {
            queue.push(p->rchild);
        }
    }
}
int main()
{
    int level = 1; //表層數
    BiTree T = NULL;
    cout << "請以前序遍歷的方式輸入擴充套件二叉樹:"; //類似輸入AB#D##C##
    CreateBiTree(&T);// 建立二叉樹,沒有樹,怎麼遍歷
    cout << "遞迴前序遍歷輸出為:" << endl;
    PreOrderTraverse(T, level);//進行前序遍歷,其中operation1()和operation2()函式表示對遍歷的結點資料進行的處理操作
    cout << endl;
    cout << "遞迴中序遍歷輸出為:" << endl;
    InOrderTraverse(T, level);
    cout << endl;
    cout << "遞迴後序遍歷輸出為:" << endl;
    PostOrderTraverse(T, level);
    cout << endl;
        cout<<"非遞迴前序遍歷輸出為:"<<endl;
        PreOrder(T);
        cout<<endl;
        cout<<"非遞迴前序遍歷輸出為:"<<endl;
        InOrder(T);
        cout<<endl;
        cout<<"非遞迴前序遍歷輸出為:"<<endl;
        PostOrder(T);
        cout<<endl;
        cout<<"層序遍歷輸出為:"<<endl;
        LevelOrder(T);
        cout<<endl;
    return 0;
}