編寫程序,用先序遞歸遍歷法(或輸入先序及中序遞歸遍歷結點訪問序列)創建二叉樹的二叉鏈表存儲結構,計算並輸出二叉樹的結點總數以及樹的高度;而後輸出其先序、中序、後序以及層次遍歷結點訪問次序。其中層次遍歷的實現需使用循環隊列。二叉樹結點數據類型建議選用字符類型。node
採用C++的模板類,建立隊列。每一個隊列對象中,elem指針用來創建長度爲n的數組,n表示隊列的容量,front表示隊頭指針,rear表示隊尾指針,c表示隊列中當前元素的個數。
採用結構體創建二叉樹,其中,data表示數據域,lchild表示左指針,rchild表示右指針,BiT表示二叉樹結構體指針類型變量,BiTNode表示二叉樹結構體類型變量。ios
#include <conio.h> #include <iostream> using namespace std; typedef char ElemTp; #define MAX 20 template <typename T> class Queue //模板類:隊列 { public: Queue(); //默認構造函數 Queue(int n); //構造函數,調用函數createQueue(int n),建立長度爲n的隊列 ~Queue(); //虛構函數 int createQueue(int n); //建立長度爲n的隊列 int empty(); //判斷隊列是否爲空 int full(); //判斷隊列是否爲滿 int enQueue(T e); //元素e入隊 int dlQueue(T &e); //元素出隊,保存在e中 private: T *elem; //創建長度爲n的數組 int n; //隊列容量 int front; //隊頭指針 int rear; //隊尾指針 int c; //隊列當前元素個數 }; typedef struct node { ElemTp data; //數據域 struct node *lchild, //左指針 *rchild; //右指針 }*BiT,BiTNode; void visit(BiT e) //訪問函數 { if (e->data != NULL) //輸出二叉樹的數據域 cout << e->data << " "; } void preorder(BiT bt) //先序遍歷二叉樹 { if (bt) { visit(bt); //訪問根節點 preorder(bt->lchild); //遞歸調用遍歷左子樹 preorder(bt->rchild); //遞歸調用遍歷右子樹 } } void midorder(BiT bt) //中序遍歷二叉樹 { if (bt) { midorder(bt->lchild); //遞歸調用遍歷左子樹 visit(bt); //訪問根節點 midorder(bt->rchild); //遞歸調用遍歷右子樹 } } void lasorder(BiT bt) //後序遍歷二叉樹 { if (bt) { lasorder(bt->lchild); //遞歸調用遍歷左子樹 lasorder(bt->rchild); //遞歸調用遍歷右子樹 visit(bt); //訪問根節點 } } void layertravel(BiT bt) //層次遍歷二叉樹 { if (bt == NULL) return; Queue<BiT> q(MAX); //創建隊列 q.enQueue(bt); //根節點入隊 while (!q.empty()) { q.dlQueue(bt); //根節點出隊 visit(bt); //訪問根節點 if (bt->lchild) q.enQueue(bt->lchild); //左子樹不空,訪問左子樹 if (bt->rchild) q.enQueue(bt->rchild); //右子樹不空,訪問右子樹 } } BiT crtPreBT() //先序遞歸遍歷創建二叉樹算法 { BiT bt; char ch; ch = getchar(); if (ch == '#') //讀到‘#’返回NULL指針 return NULL; bt = new BiTNode(); //創建新的二叉樹結點 bt->data = ch; bt->lchild = crtPreBT(); //遞歸創建左子樹 bt->rchild = crtPreBT(); //遞歸創建右子樹 return bt; } BiT crtPreMidBT(char *pr, int &i, char *mi, int u, int v) //先序及中序遞歸遍歷結點訪問序列創建二叉樹算法 { BiT bt; int k; if (u > v) return NULL; bt = new BiTNode(); bt->data = pr[i++]; //pr[i]爲子樹根節點 for (k = u; k <= v; k++) //mi[u...v]爲子樹中序序列 { if (mi[k] == bt->data) //查找根節點在中序序列中的位置 break; } bt->lchild = crtPreMidBT(pr, i, mi, u, k - 1); //遞歸創建左子樹 bt->rchild = crtPreMidBT(pr, i, mi, k + 1, v); //遞歸創建右子樹 return bt; } int height(BiT bt) //計算二叉樹的高度 { int hl, hr; if (!bt) return 0; hl = height(bt->lchild); //遞歸計算左子樹的高度 hr = height(bt->rchild); //遞歸計算右子樹的高度 return (hl > hr) ? (hl + 1) : (hr + 1); //返回整個二叉樹的高度(左、右子樹高度較大的值加一) } int nodeNum(BiT bt) //計算二叉樹的總結點數 { int nl, nr; if (!bt) return 0; nl = nodeNum(bt->lchild); //遞歸計算左子樹的結點數 nr = nodeNum(bt->rchild); //遞歸計算右子樹的結點數 return nl + nr + 1; //返回整個二叉樹的結點數(左、右子樹結點數之和加一) } void choose(BiT &bt) //選擇創建二叉樹的方式 { char num, pre[MAX], mid[MAX]; int i = 0, u = 0, v; cout << "請選擇創建二叉樹的方式: " << endl; cout << "1. 先序遍歷創建二叉樹" << endl; cout << "2. 先序和中序遍歷創建二叉樹" << endl; num = _getch(); switch (num) { case '1': //先序遍歷創建二叉樹 { cout << "您選擇了第一種方式." << endl; cout << "請輸入先序遍歷的字符序列: " << endl; bt = crtPreBT(); } break; case '2': //先序和中序遍歷創建二叉樹 { cout << "您選擇了第二種方式." << endl; cout << "請輸入先序遍歷的字符序列: " << endl; cin.getline(pre, MAX); cout << "請輸入中序遍歷的字符序列: " << endl; cin.getline(mid, MAX); v = strlen(mid) - 1; bt = crtPreMidBT(pre, i, mid, u, v); } break; } } template<typename T> Queue<T>::Queue() { front = rear = -1; c = 0; } template<typename T> Queue<T>::Queue(int n) { createQueue(n); } template<typename T> Queue<T>::~Queue() { c = 0; front = rear = -1; delete[]elem; } template<typename T> int Queue<T>::createQueue(int n) { if (n <= 0) return 0; this->n = n; c = 0; front = rear = -1; elem = new T[n]; if (!elem) return 0; return 1; } template<typename T> int Queue<T>::empty() { return c == 0; } template<typename T> int Queue<T>::full() { return c == n; } template<typename T> int Queue<T>::enQueue(T e) { if (c == n) return 0; //隊滿,入隊失敗 rear = (rear + 1) % n; elem[rear] = e; c++; return 1; //入隊成功返回1 } template<typename T> int Queue<T>::dlQueue(T & e) { if (c == 0) return 0; //隊空,出隊失敗 front = (front + 1) % n; e = elem[front]; c--; return 1; //出隊成功返回1 } int main() { int h, num; BiT bt; choose(bt); h = height(bt); cout << "二叉樹的高度是: " << h << endl; num = nodeNum(bt); cout << "二叉樹的總結點數是: " << num << endl; cout << "先序遍歷結點訪問次序: " << endl; preorder(bt); cout << endl; cout << "中序遍歷結點訪問次序: " << endl; midorder(bt); cout << endl; cout << "後序遍歷結點訪問次序: " << endl; lasorder(bt); cout << endl; cout << "層次遍歷結點訪問次序: " << endl; layertravel(bt); cout << endl; return 0; }
(1)程序輸入:
先序序列:abc##de#g##f###
程序輸出:
二叉樹的高度是:5
二叉樹的總結點數是:7
先序遍歷:a b c d e g f
中序遍歷:c b e g d f a
後序遍歷:c g e f d b a
層次遍歷:a b c d e f g
(2)程序輸入:
先序序列:ABCDEFG
中序序列:CBEDAFG
程序輸出:
二叉樹的高度是:4
二叉樹的總結點數是:7
先序遍歷:A B C D E F G
中序遍歷:C B E D A F G
後序遍歷:C E D B G F A
層次遍歷:A B F C D G E
(3)程序輸入:
先序序列:ABDF####C#E#G#H##
程序輸出:
二叉樹的高度是:5
二叉樹的總結點數是:8
先序遍歷:A B D F C E G H
中序遍歷:F D B A C E G H
後序遍歷:F D B H G E C A
層次遍歷:A B C D E F G H
(4)程序輸入:
先序序列:#
程序輸出:
二叉樹的高度是:0
二叉樹的總結點數是:0
c++