1. 程式人生 > >二叉樹的遍歷(從遞迴到非遞迴)

二叉樹的遍歷(從遞迴到非遞迴)

遞迴

前序遍歷

//遞迴前序遍歷
void preorderTraversal(Binarytree biTree){
    if (biTree == nullptr) {
        return;
    }
    cout<<biTree->data<<" ";
    preorderTraversal(biTree->left);
    preorderTraversal(biTree->right);
}

中序遍歷

//遞迴中序遍歷
void inorderTraversal(Binarytree biTree){
    if
(biTree == nullptr) { return; } inorderTraversal(biTree->left); cout<<biTree->data<<" "; inorderTraversal(biTree->right); }

後序遍歷

//遞迴後序遍歷
void postorderTraversal(Binarytree biTree){
    if (biTree == nullptr) {
        return;
    }
    postorderTraversal(biTree->
left); postorderTraversal(biTree->right); cout<<biTree->data<<" "; }

樹的定義

//二叉樹節點
typedef struct BitNode{
    int data;
    BitNode* left;
    BitNode* right;
}BitNode,*Binarytree;

typedef struct BitNodeStackBit{
    BitNode* node;
    BitNodeStackBit* next;
}
BitNodeStackBit,*BitNodeStack;
void
initBitNodeStack(BitNodeStack& bitNodeStack){ bitNodeStack = new BitNodeStackBit; bitNodeStack->node =nullptr; bitNodeStack->next =nullptr; } void pushBitNode(BitNodeStack& bitNodeStack,BitNode *newNode){ BitNodeStackBit* p = new BitNodeStackBit{newNode,bitNodeStack}; bitNodeStack = p; } BitNode* popBitNode(BitNodeStack& bitNodeStack){ if (bitNodeStack == nullptr) { PerException("the stack is empty"); } BitNodeStackBit* p = bitNodeStack; bitNodeStack = bitNodeStack->next; BitNode* cur = p->node; delete p; return cur; } BitNode* peepBitNode(BitNodeStack& bitNodeStack){ if (bitNodeStack == nullptr) { PerException("the stack is empty"); } BitNodeStackBit* p = bitNodeStack; BitNode* cur = p->node; return cur; } BitNode* getPopBitNode(BitNodeStack& bitNodeStack){ return popBitNode(bitNodeStack); } bool isEmpty(BitNodeStack & bitNodeStack){ if (bitNodeStack->node == nullptr) { return true; } else { return false; } }

非遞迴

前序遍歷

void preorderTraversalN(Binarytree bitTree){
    BitNodeStack stack;
    initBitNodeStack(stack);

    //問題一bitTree取了非
    //二叉樹不為空,並且棧中還有元素
    while (bitTree || !isEmpty(stack)) {
        while(bitTree){
            //先列印後壓棧,在訪問左子樹
            cout<<bitTree->data<<" ";
            pushBitNode(stack, bitTree);
            bitTree = bitTree->left;
        }
        if (!isEmpty(stack)) {
            //左子樹沒有了,拿出棧中的元素 找到其右子樹,繼續上面的迴圈
            BitNode*p = getPopBitNode(stack);
            bitTree = p->right;
        }
    }
}

中序遍歷

void inorderTraversalN(Binarytree biTree){
    BitNodeStack stack = new BitNodeStackBit;
    initBitNodeStack(stack);
    while (biTree|| !isEmpty(stack)) {
        while (biTree) {
            pushBitNode(stack, biTree);
            biTree = biTree->left;
        }
        if (!isEmpty(stack)) {
            BitNode* p = getPopBitNode(stack);
            biTree = p->right;
            cout<<p->data<<" ";
        }
    }
}

後序遍歷—根右左思想

string change(string str){
    string newStr ="";
    for (int i =(int)str.length()-1 ; i>=0; i--)
    {
        newStr += str[i];
    }
    return newStr;
}
void postorderTraversalNF(Binarytree biTree){
    BitNodeStack stack;
    initBitNodeStack(stack);
    string res ="";
    while (biTree || !isEmpty(stack)) {
        while (biTree) {
            res += to_string(biTree->data);
            res += " ";
            pushBitNode(stack, biTree);
            biTree = biTree->right;
        }
        if (!isEmpty(stack)) {
            BitNode *p =  getPopBitNode(stack);
            biTree = p->left;
        }
    }
    cout<<change(res).substr(1,res.length());
}

後序遍歷—標記思想

void postorderTraversalND(Binarytree biTree){
    BitNodeStack stack1;
    LinkStack stack2;
    initBitNodeStack(stack1);
    initStack(stack2);
    //1、左結點全壓棧1。隨之棧2壓入0  2、遍歷該節點的右子樹棧2彈0壓1     如此迴圈 3、棧2為1,迴圈列印
    while (biTree ||!isEmpty(stack1)) {
        while (biTree) {
            pushBitNode(stack1, biTree);
            push(stack2, 0);
            biTree = biTree->left;
        }
        while (!isEmpty(stack1) && getTop(stack2) == 1) {
            pop(stack2);
            cout<<popBitNode(stack1)->data<<" ";
        }
        if (!isEmpty(stack1)) {
            BitNode* p =  peepBitNode(stack1);
            biTree = p->right;
            pop(stack2);
            push(stack2, 1);
        }
    }
}

棧的定義

//鏈式棧的定義(不帶頭結點,頭插法)
//N->H->d->b->c->R
typedef struct LSNode{
    int data;
    LSNode* next;
}LSNode ,*LinkStack;

//初始化一個棧
void initStack(LinkStack &top){
    top =nullptr;
}
//清空一個棧
void clearStack(LinkStack &top){
    while (top != nullptr) {
        LSNode* p =top;
        top = top->next;
        delete p;
    }
}
//進棧
void push(LinkStack &top,int data){
    LSNode*p = new LSNode{data,top};
    top = p;
}
//出棧
int pop(LinkStack &top){
    if (top == nullptr) {
        PerException("the stack is empty");
    }
    int res = 0;
    LSNode* p = top;
    top = top->next;
    res = p->data;
    return res;
}
//檢視棧頂元素
int getTop(LinkStack top){
    if (top == nullptr) {
        PerException("the stack is empty");
    }
    return top->data;
}
//求棧的長度
int length(LinkStack top){
    int count =0;
    LSNode* p =top;
    while (p!=nullptr) {
        p = p->next;
        count++;
    }
    return count;
}
//棧是否為空
bool isEmpty(LinkStack top){
    if (top == nullptr) {
        return true;
    }
    return false;
}
//棧是否為滿
bool isFull(LinkStack top){
    return false;
}

測試資料

int main(){
    BitNode head  = {.data = 0};
    BitNode head1 = {.data = 1};
    BitNode head2 = {.data = 2};
    BitNode head3 = {.data = 3};
    BitNode head4 = {.data = 4};
    BitNode head5 = {.data = 5};
    BitNode head6 = {.data = 6};
    BitNode head7 = {.data = 7};

    head.left = &head1;
    head.right = &head2;
    head.left->left = &head3;
    head.right->left = &head4;
    head.right->right = &head5;
    head.left->left->right = &head6;
    head.left->left->left  = &head7;

    Binarytree  biTree = &head;
    printTree(biTree);
    preorderTraversal(biTree);
    cout<<endl;
    preorderTraversalN(biTree);
    inorderTraversal(biTree);
    cout<<endl;
    inorderTraversalN(biTree);
    postorderTraversal(biTree);
    cout<<endl;
    postorderTraversalNF(biTree);
    cout<<endl;
    postorderTraversalND(biTree);
    return 0;
}

巨集觀列印二叉樹

string getSpace(int num) {
    string space = " ";
    string buf = "";
    for (int i = 0; i < num; i++) {
        buf.append(space);
    }
    return buf;
}
void printInOrder(Binarytree head, int height, string to, int len) {
    if (head == nullptr) {
        return;
    }
    printInOrder(head->right, height + 1, "v", len);
    string val = to ;
    val += to_string(head->data);
    val += to;
    int lenM = (int)val.length();
    int lenL = (len - lenM) / 2;
    int lenR = len - lenM - lenL;
    val = getSpace(lenL) + val + getSpace(lenR);
    cout<<getSpace(height * len) + val<<endl;
    printInOrder(head->left, height + 1, "^", len);
}
void printTree(Binarytree head) {
    cout<<"Binary Tree:";
    printInOrder(head, 0, "H", 17);
    cout<< endl;
}