以数组的形式存储,数组下标即二叉树下标,数组内容即二叉树的内容
注意: 当 建立二叉树函数
是类模板中的成员时: 左右子树可以直接指向NULL是函数模板时: 不可以直接指向NULL,必须建一个声明了T的种类的节点nullp,节点内容为NULL //类模板中的成员时 //法一: BTnode<char>* nullp = NULL; BTnode<char>* c = GetBtnode('C', f, nullp); //合法 //法二: BTnode<char>* b = GetBtnode('B', NULL, NULL); //合法 //函数模板时 //法一: BTnode<char>* nullp = NULL; BTnode<char>* c = GetBtnode('C', f, nullp); //合法 //法二: BTnode<char>* b = GetBtnode('B', NULL, NULL); //非法队列 先入队 删除和访问作为循环
//层次遍历法一 template <class T> void Level(const BTnode<T>* t) { if (t == NULL) return; queue <const BTnode<T>*> Q; Q.push(t); while (!Q.empty()) { t = Q.front(); Q.pop(); cout << t->data; if (t->left) Q.push(t->left); if (t->right) Q.push(t->right); } cout<<endl;队列 先访问和入队 出队作为循环
//层次遍历法二 template <class T> void Level(const BTnode<T>* t) { if (t == NULL) return; queue <const BTnode<T>*> Q; cout << t->data; Q.push(t); while (!Q.empty()) { t = Q.front(); Q.pop(); if (t->left) { cout << t->left->data; Q.push(t->left); } if (t->right) { cout << t->right->data; Q.push(t->right); } } cout << endl; }对比层次遍历法二 队列 先访建和入队 出队和+1/2作为循环
//顺序储存转链式储存非递归 template <class T> BTnode<T>* MakeLinked(const vector<T>& L) { if (L.size() == 0) return NULL; queue<BTnode<T>*> Q; BTnode<T>* parent, * child; int n = L.size(),i = 0; BTnode<T>* t = GetBtnode(L[0]); Q.push(t); while (!Q.empty()) { parent = Q.front(); Q.pop(); if (2 * i + 1 < n && L[2 * i + 1] != T()) { child = GetBtnode(L[2 * i + 1]); parent->left = child; Q.push(child); } if (2 * i + 2 < n && L[2 * i + 2] != T()) { child = GetBtnode(L[2 * i + 2]); parent->right = child; Q.push(child); } i++; while (i < n && L[i] == T()) i++; } cout << "MakeLinked(1) called!" << endl; return (t); }对比层次遍历法一 队列 节点和位置同步 先入队 出队访问和判断作为循环
//垂直输出 struct Loction { int xindent, ylevel; }; void Gotoxy(int x, int y) { static int level = 0, indent = 0; if (y == 0) { indent = 0; level = 0; } if (level != y) { cout << endl; indent = 0; level++; } cout.width(x - indent); indent = x; } template <class T> void PrintTree(const BTnode<T>* t, int screenwidth) { if (t == NULL) return; int level = 0, offset = screenwidth / 2; Loction fLoc, cLoc; queue<const BTnode<T>*> Q; queue<Loction> LQ; fLoc.xindent = offset; fLoc.ylevel = level; Q.push(t); LQ.push(fLoc); while (!Q.empty()) { t = Q.front(); Q.pop(); fLoc = LQ.front(); LQ.pop(); Gotoxy(fLoc.xindent, fLoc.ylevel); cout << t->data; if (fLoc.ylevel != level) { level++; offset = offset / 2; } if (t->left) { Q.push(t->left); cLoc.ylevel = fLoc.ylevel + 1; cLoc.xindent = fLoc.xindent - offset / 2; LQ.push(cLoc); } if (t->right) { Q.push(t->right); cLoc.ylevel = fLoc.ylevel + 1; cLoc.xindent = fLoc.xindent + offset / 2; LQ.push(cLoc); } } cout << endl; }栈 while (t || !S.empty()) { 若t: 访问 右入栈 指左 ; 否则: 出栈 (且取出栈) }
//前序遍历的非递归 template <class T> void SimPreorder(const BTnode<T>* t) { if (!t) return; stack<const BTnode<T>*> S; while (t || !S.empty()) { if (t) { cout << t->data; if (t->right) S.push(t->right); t = t->left; } else { t = S.top(); S.pop(); } } }左右移 互换 取下标
//快速排序 template <class T> int Particition(T* pa, int low, int high) { int i = low, j = high; T temp = pa[i]; while (i != j) { while (i<j && pa[j]>temp) j--; if (i < j) pa[i++] = pa[j]; while (i < j && pa[i] < temp) i++; if (i < j) pa[j--] = pa[i]; } pa[i] = temp; return i; } template<class T> void QuickSoret(T* pa, int low, int high) { if (low > high) return; int m = Particition(pa, low, high); QuickSoret(pa, low, m - 1); QuickSoret(pa, m + 1, high); } //附加验证 template<class T> void PrintQuickSoretResout(T* pa, int low, int high) { QuickSoret(pa, low, high); for (int k = low; k <= high; k++) cout << pa[k] << " "; cout << endl; }栈 while (t || !S.empty()) { 若t: 入栈 指左 否者: 出栈 访问 指右 }
//中序遍历的非递归 template <class T> void SimInorder(const BTnode<T>* t) { if (!t) return; stack<const BTnode<T>*> S; while (t || !S.empty()) { if (t) { S.push(t); t = t->left; } else { t = S.top(); S.pop(); cout << t->data; t = t->right; } } }对比中序遍历的递归
//汉诺塔递归算法 void Hanoi(int n, char A, char B, char C) { if (n <= 0) return; if (n > 1) Hanoi(n - 1, A, C, B); cout << '(' << n << ")," << A << ',' << C << endl; if (n > 1) Hanoi(n - 1, B, A, C); }栈 节点和tag同步 while (t || !S.empty()) { 若t: 入栈 指左 否则: { 出栈 若tag为1: 入栈 改1为2 指右 否则: 访问 } }
//后序遍历的非递归 template <class T> void SimPostorder(const BTnode<T>* t) { if (!t) return; int tag; const BTnode<T>* temp; stack<const BTnode<T>*> S; stack<int> tagS; while (t || !S.empty()) { if (t) { S.push(t); tagS.push(1); t = t->left; } else { temp = S.top(); tag = tagS.top(); S.pop(); tagS.pop(); if (tag == 1) { S.push(temp); tagS.push(2); t = temp->right; } else cout << temp->data; } } }以前序和中序为例 计算相差节点数 左右递归 建首
//先序和中序 template<class T> BTnode<T>* MakeLinked(const T* pL, const T* iL, int size) { if (size <= 0) return NULL; BTnode<T>* t, * left, * right; const T* rL; int k; for (rL = iL; rL < iL + size; rL++) if (*rL == *pL) break; k = rL - iL; left = MakeLinked(pL + 1,iL, k); right = MakeLinked(pL + k + 1,iL + k + 1 , size - k - 1); t = GetBtnode(*pL, left, right); return(t); }上面就是二叉树的一些知识点,如果哪里有错的地方,还望指出。
