数据结构实验:二叉树遍历

目录

1、实验要求

2、函数实现

(1)容错处理

(2)建立二叉树存储结构

(3)二叉树先序遍历

(4)二叉树中序遍历

(5)二叉树后续遍历

(6)二叉树层次遍历

(7)求根到给定结点的路径

3、完整代码


1、实验要求

        实现功能:建立二叉树存储结构、求二叉树的先序遍历、求二叉树的中序遍历、求二叉树的后序遍历、求二叉树的层次遍历、求根到给定结点的路径。主控菜单:

        1.建立二叉树存储结构

        2.求二叉树的先序遍历

        3.求二叉树的中序遍历

        4.求二叉树的后序遍历

        5.求二叉树的层次遍历

        6.求根到给定结点的路径

        0.退出系统

        此外还要实现容错处理,检测任何不合规的输入,并给出必要提示。并优化交互界面,让非专业者(陌生人)也能顺利完成运算。

2、函数实现

(1)容错处理

         由于存在容错处理防止程序崩溃,所以需要将输入过程封装成一个函数,如果输入的为正常数字则继续执行功能,如果输入的为乱码或字符,则需重新输入。创建好容错处理函数后,后面的输入只需“int a = Judge()”即可。

//容错处理函数
int Judge() {
    int j;
    while (true) {
        if (!scanf_s("%d", &j)) {
            cout << "非法字符!请重新输入:";
            while (getchar() != '\n');
        }
        else if (getchar() != '\n') {
            cout << "非法字符!请重新输入:";
            while (getchar() != '\n');
        }
        else if (j < -1) cout << "非法字符!请重新输入:";
        else break;
    }
    return j;
}

(2)建立二叉树存储结构

typedef struct Node {//建立二叉树结构体
    int data;
    struct Node* left, * right;
}BTNode, * BTree;
int flag = 1;//作为空树标志,用以遍历时判断树是否为空树

//建立二叉树存储结构
void CreatBTree(BTree& T, int num, int c) {
    if (num == 1) cout << "请输入" << c << "的左孩子(-1代表空):";
    if (num == 2) cout << "请输入" << c << "的右孩子(-1代表空):";
    int ch;
    ch = Judge();
    if (ch <= -1) T = nullptr;
    else {
        T = new BTNode;
        T->data = ch;
        CreatBTree(T->left, 1, ch);
        CreatBTree(T->right, 2, ch);
    }
}

(3)二叉树先序遍历

//二叉树先序遍历
void InOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树";
    if (T) {
        cout << T->data << " ";
        InOrderTraverse(T->left);
        InOrderTraverse(T->right);
    }
}

(4)二叉树中序遍历

//二叉树中序遍历
void MidOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树";
    if (T) {
        MidOrderTraverse(T->left);
        cout << T->data << " ";
        MidOrderTraverse(T->right);
    }
}

(5)二叉树后续遍历

//二叉树后序遍历
void LastOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树";
    if (T) {
        LastOrderTraverse(T->left);
        LastOrderTraverse(T->right);
        cout << T->data << " ";
    }

(6)二叉树层次遍历

        二叉树的层次遍历不同于其他遍历一样简单,需要用到队列的先进先出。在这里我利用了stl中的队列,算是偷了个小懒(实在懒得自己写队列了)。

//二叉树层次遍历
void LevelOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树" ;
    if (T) {
        queue  lev;
        lev.push(T);
        while (!lev.empty()) {
            cout << lev.front()->data << " ";
            if (lev.front()->left != nullptr) {
                lev.push(lev.front()->left);
            }
            if (lev.front()->right != nullptr) {
                lev.push(lev.front()->right);
            }
            lev.pop();
        }
    }
}

(7)求根到给定结点的路径

//寻找给定节点的路径
void FindPath(BTree& T, int point, vector&path) {
    if (T == nullptr) return;
    path.push_back(T);
    if (T->data == point) {
        PrintPath(path);
        return;
    }
    if (T->left != nullptr) FindPath(T->left, point, path);
    if (T->right != nullptr) FindPath(T->right, point, path);
    path.pop_back();
}

//输出给定节点的路径
void PrintPath(vector&path) {
    cout << "根节点到该节点的路径如下:" << endl;
    vector::const_iterator p = path.begin();
    for (; p != path.end() - 1; p++) cout << (*p)->data << "->";
    cout << (*p)->data;
    cout << endl;
}

3、完整代码

#include 
#include 
#include 
using namespace std;

typedef struct Node {
    int data;
    struct Node* left, * right;
}BTNode, * BTree;
int flag = 1;//空树标记

int Judge();//容错函数
void CreatBTree(BTree& T, int num, int c);//建立二叉树存储结构
void InOrderTraverse(BTree& T);//二叉树先序遍历
void MidOrderTraverse(BTree& T);//二叉树中序遍历
void LastOrderTraverse(BTree& T);//二叉树后序遍历
void LevelOrderTraverse(BTree& T);//二叉树层次遍历
void FindPath(BTree& T, int point, vector&path);//寻找给定节点的路径
void PrintPath(vector&path);//输出给定节点的路径

int main() {
    int n;//功能序号
    //进行功能选项
    cout << "==================================" << endl;
    cout << "||请输入功能编号,运行相应功能\t||" << endl;
    cout << "||1.建立二叉树存储结构\t\t||" << endl;
    cout << "||2.求二叉树的先序遍历\t\t||" << endl;
    cout << "||3.求二叉树的中序遍历\t\t||" << endl;
    cout << "||4.求二叉树的后序遍历\t\t||" << endl;
    cout << "||5.求二叉树的层次遍历\t\t||" << endl;
    cout << "||6.求给定节点的路径\t\t||" << endl;
    cout << "||0.退出程序\t\t\t||" << endl;
    cout << "==================================" << endl;
    while (true) {
        n = Judge();
        BTree T;
        int point;
        vectorpath;
        if (n < 1 || n>6) break;
        switch (n) {
        case 1: 
            T = new BTNode;
            cout << "请输入根节点:(-1代表空)";
            T->data = Judge();
            if (T->data != -1) {
                flag = 1;
                CreatBTree(T->left, 1, T->data);
                CreatBTree(T->right, 2, T->data);
            }
            else {
                T = nullptr;
                flag = 0;
            }
            cout << "二叉树建立成功!" << endl;
            break;
        case 2:
            InOrderTraverse(T);
            cout << endl;
            break;
        case 3:
            MidOrderTraverse(T);
            cout << endl;
            break;
        case 4:
            LastOrderTraverse(T);
            cout << endl;
            break;
        case 5: 
            LevelOrderTraverse(T);
            cout << endl;
            break;
        case 6: 
            if (flag == 0)cout << "该树为空树" << endl;
            else {
                cout << "请输入查询节点:";
                point = Judge();
                FindPath(T, point, path);
                while (path.empty()) {
                    cout << "二叉树中无此节点,请重新输入:";
                    point = Judge();
                    FindPath(T, point, path);
                }
            }
            break;
        default:
            break;
        }
        cout << "==================================" << endl;
        cout << "||请输入功能编号,运行相应功能\t||" << endl;
        cout << "||1.建立二叉树存储结构\t\t||" << endl;
        cout << "||2.求二叉树的先序遍历\t\t||" << endl;
        cout << "||3.求二叉树的中序遍历\t\t||" << endl;
        cout << "||4.求二叉树的后序遍历\t\t||" << endl;
        cout << "||5.求二叉树的层次遍历\t\t||" << endl;
        cout << "||6.求给定节点的路径\t\t||" << endl;
        cout << "||0.退出程序\t\t\t||" << endl;
        cout << "==================================" << endl;
    }
    return 0;
}

//寻找给定节点的路径
void FindPath(BTree& T, int point, vector&path) {
    if (T == nullptr) return;
    path.push_back(T);
    if (T->data == point) {
        PrintPath(path);
        return;
    }
    if (T->left != nullptr) FindPath(T->left, point, path);
    if (T->right != nullptr) FindPath(T->right, point, path);
    path.pop_back();
}

//输出给定节点的路径
void PrintPath(vector&path) {
    cout << "根节点到该节点的路径如下:" << endl;
    vector::const_iterator p = path.begin();
    for (; p != path.end() - 1; p++) cout << (*p)->data << "->";
    cout << (*p)->data;
    cout << endl;
}

//二叉树层次遍历
void LevelOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树" ;
    if (T) {
        queue  lev;
        lev.push(T);
        while (!lev.empty()) {
            cout << lev.front()->data << " ";
            if (lev.front()->left != nullptr) {
                lev.push(lev.front()->left);
            }
            if (lev.front()->right != nullptr) {
                lev.push(lev.front()->right);
            }
            lev.pop();
        }
    }
}

//二叉树后序遍历
void LastOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树";
    if (T) {
        LastOrderTraverse(T->left);
        LastOrderTraverse(T->right);
        cout << T->data << " ";
    }
}

//二叉树中序遍历
void MidOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树";
    if (T) {
        MidOrderTraverse(T->left);
        cout << T->data << " ";
        MidOrderTraverse(T->right);
    }
}

//二叉树先序遍历
void InOrderTraverse(BTree& T) {
    if (flag == 0)cout << "该树为空树";
    if (T) {
        cout << T->data << " ";
        InOrderTraverse(T->left);
        InOrderTraverse(T->right);
    }
}

//建立二叉树存储结构
void CreatBTree(BTree& T, int num, int c) {
    if (num == 1) cout << "请输入" << c << "的左孩子(-1代表空):";
    if (num == 2) cout << "请输入" << c << "的右孩子(-1代表空):";
    int ch;
    ch = Judge();
    if (ch <= -1) T = nullptr;
    else {
        T = new BTNode;
        T->data = ch;
        CreatBTree(T->left, 1, ch);
        CreatBTree(T->right, 2, ch);
    }
}

//容错处理函数
int Judge() {
    int j;
    while (true) {
        if (!scanf_s("%d", &j)) {
            cout << "非法字符!请重新输入:";
            while (getchar() != '\n');
        }
        else if (getchar() != '\n') {
            cout << "非法字符!请重新输入:";
            while (getchar() != '\n');
        }
        else if (j < -1) cout << "非法字符!请重新输入:";
        else break;
    }
    return j;
}

        以上代码仅供实验参考,若想自身代码能力有确切的提升,还需要融入自己的推演和思考,感谢观看!

你可能感兴趣的:(数据结构实验,数据结构,算法,链表)