赞
踩
以数组的形式存储,数组下标即二叉树下标,数组内容即二叉树的内容
//基本结构(含默认构造) template <class T> struct BTnode { T data; BTnode* left, * right; BTnode(const T& item = T(), BTnode* lptr = NULL, BTnode* rptr = NULL) :data(item), left(lptr), right(rptr) {} }; //建立二叉树 template <class T> BTnode<T>* GetBtnode(const T& item, BTnode<T>* lp = NULL, BTnode<T>* rp = NULL) { BTnode<T>* p; p = new BTnode<T>(item, lp, rp); if (p == NULL) { cerr << "Memory allocation failure!" << endl; exit(1); } cout << "GetBtnode called!" << endl; return p; }
注意:
当 建立二叉树函数
//类模板中的成员时
//法一:
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; }
//先序遍历的递归
template <class T>
void Preorder(const BTnode<T>* t)
{
if (t == NULL)
return;
cout << t->data;
if (t->left)
Preorder(t->left);
if (t->right)
Preorder(t->right);
}
栈
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; }
//中序遍历的递归
template <class T>
void Inorder(const BTnode<T>* t)
{
if (!t)
return;
if (t->left)
Inorder(t->left);
cout << t->data;
if (t->right)
Inorder(t->right);
}
栈
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);
}
//后序遍历的递归
template <class T>
void Postorder(const BTnode<T>* t)
{
if (!t)
return;
if (t->left)
Postorder(t->left);
if (t->right)
Postorder(t->right);
cout << t->data;
}
栈 节点和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>
int Depth(const BTnode<T>* t)
{
if (!t)
return -1;
int l = Depth(t->left);
int r = Depth(t->right);
return (1 + (l > r ? l : r));
}
//复制二叉树链表
template<class T>
BTnode<T>* CopyTree(const BTnode<T>* t)
{
if (!t)
return(NULL);
BTnode<T>* l = CopyTree(t->left);
BTnode<T>* r = CopyTree(t->right);
return (GetBtnode(t->data, l, r));
}
//删除二叉树链表
template<class T>
void DeleteTree(const BTnode<T>* t)
{
if (!t)
return;
DeleteTree(t->left);
DeleteTree(t->right);
delete t;
t = NULL;
}
//顺序储存转换为链式的递归
template<class T>
BTnode<T>* MakeLinked(const vector<T>& L, int size, int pos)
{
if (pos >= size || L[pos] ==T())
return NULL;
BTnode<T>* left = MakeLinked(L, size, 2 * pos + 1);
BTnode<T>* right = MakeLinked(L, size, 2 * pos + 2);
BTnode<T>* t = GetBtnode(L[pos], left, right);
return t;
}
以前序和中序为例
计算相差节点数 左右递归 建首
//先序和中序 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); }
上面就是二叉树的一些知识点,如果哪里有错的地方,还望指出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。