前序遍歷非遞歸:
//前序遍歷非遞歸
void PreOrder(BTreeNode* t)
{
? ? stack<int> st;
? ? BTreeNode* p = t;
? ? while(p != NULL || !s.empty())
? ? {
? ? ? ? if(p != NULL)
? ? ? ? {
? ? ? ? ? ? cout << p->data;
? ? ? ? ? ? s.push(p);
? ? ? ? ? ? p = p->lchild;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? p = s.pop();
? ? ? ? ? ? p = p->rchild;
? ? ? ? }
? ? }
}
//層次遍歷
void LevelOrder(BTreeNode* t)
{
? ? BTreeNode* p;
? ? queue<int> que;
? ? if(t != NULL)
? ? ? ? que.push_back(t);
? ? while(!que.empty())
? ? {
? ? ? ? p = que.front();
? ? ? ? cout << p->data;
? ? ? ? if(p ->lchild != NULL)
? ? ? ? ? ? que.push_back(t->lchild);
? ? ? ? if(p->rchild != NULL)
? ? ? ? ? ? que.push_back(t->rchild);
? ? }
}
//前序遍歷應用--輸出為廣義表:A(B(D,E),C(,F))
void Out(BTreeNode* t)
{
? ? if(t != NULL)
? ? {
? ? ? ? cout << t->data;
? ? ? ? if(t->lchild != NULL || t->rchild != NULL)
? ? ? ? {
? ? ? ? ? ? cout << '(';
? ? ? ? ? ? Out(t->lchild);
? ? ? ? ? ? cout << ',';
? ? ? ? ? ? if(t->rchild != NULL)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Out(t->rchild);
? ? ? ? ? ? }
? ? ? ? ? ? cout << ')';
? ? ? ? }
? ? }
}
//前序遍歷應用--查找中值
bool Find(BTreeNode* t,ElemType* item)
{
? ? if(t == NULL)
? ? ? ? return false;
? ? else
? ? {
? ? ? ? if(t->data == item)
? ? ? ? {
? ? ? ? ? ? item == t->data;
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? if(find(t->lchild,item))
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? if(find(t->rchild,item))
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
}
//后序遍歷應用--求二叉樹深度
int Dep(BTreeNode* t)
{
? ? if(t == NULL)
? ? ? ? return 0;
? ? else
? ? {
? ? ? ? int depl = Dep(t->lchild);
? ? ? ? int dep2 = Dep(t->rchild);
? ? ? ? return (dep1 > dep2) ? dep1+1:dep2+1;
? ? }
}
//后序遍歷應用--清空二叉樹
int Clear(BTreeNode* t)
{
? ? if(t != NULL)
? ? {
? ? ? Clear(t->lchild);
? ? ? Clear(t->rchild);
? ? ? delete t;
? ? ? t = NULL;
? ? }
}
//后序遍歷應用--求結點個數
int? NodeCount(BiTree T)
{
????if(T==NULL) return 0;
?else returnNodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
//后序遍歷應用--查找葉子結點個數
int biTreeNodeCount(BiTree t)
{? //求葉節點個數
? ? ? ? if(t != null) {
? ? ? ? ? ? int l = biTreeNodeCount(t->lchild());
? ? ? ? ? ? int r = biTreeNodeCount(t->rchild());
? ? ? ? ? ? if(l == 0 && r == 0) {
? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? return l + r;
? ? ? ? ? ? }
? ? ? ? }else {
? ? ? ? ? ? return 0;
? ? ? ? }
}
采用二叉鏈表存儲時,有n+1個空指針域。
//二叉樹中序線索化
void Inthread(BTreeNode* t)
{
? ? struct BTreeNode* pre = NULL;
? ? if(t != NULL)
? ? {
? ? ? ? Inthread(t->lchild);
? ? ? ? if(pre != NULL && pre->rtag == 1)
? ? ? ? {
? ? ? ? ? ? pre->rchild = t;
? ? ? ? }
? ? ? ? if(t->lchild == NULL)
? ? ? ? {
? ? ? ? ? ? t->ltag = 1;
? ? ? ? ? ? t->lchild = pre;
? ? ? ? }
? ? ? ? if(r->rchild == NULL)
? ? ? ? {
? ? ? ? ? ? t->rtag = 1;
? ? ? ? }
? ? ? ? pre = t;
? ? ? ? Inthread(t->rchild);
? ? }
}
//中序線索化遍歷
void InorderInthread(TreeNode* t)
{
? ? TreeNode* p = t;
? ? if(p != NULL)
? ? {
? ? ? ? while(p->ltag == 0)
? ? ? ? ? ? p = p->lchild;
? ? ? ? do
? ? ? ? {
? ? ? ? ? ? cout << p->data << ;
? ? ? ? ? ? if(p->rtag == 1)
? ? ? ? ? ? ? ? p = p->rchild;
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? p = p->rchild;
? ? ? ? ? ? ? ? while(p->ltag == 0)
? ? ? ? ? ? ? ? ? ? p = p->lchild;
? ? ? ? ? ? }
? ? ? ? } while (p != NULL);
? ? }
}
最優二叉樹---霍夫曼樹
應用----判定過程優化、哈夫曼編碼
二叉搜索樹(二叉排序樹)
1、左子樹不空,左子樹的結點都小于根結點;
2、右子樹不空,右子樹結點都大于根結點;
3、左右子樹都是二叉排序樹。
查找時間復雜度O(log2n),最壞O(n)
堆:大根堆、小根堆? 利用完全二叉樹表示。
堆的順序存儲結構
struct HeapSeq
{
? ? ElemType* heap;? ? //堆類型數組指針
int len;? ? ? ? //堆的長度
int MaxSize;? ? //堆數組的最大空間
};
樹的存儲結構:
struct GTreeNode
{
? ? ElemType data;? ? //樹結點的數據元素域
GTreeNode* t[k];? ? //k為已知的樹的度,t[i]為指向孩子的指針。
};
先根遍歷 、后根遍歷采用深度優先遍歷的思路
層次遍歷采用廣度優先遍歷的思路。
樹的應用--決策樹
樹的應用--解空間樹
利用解空間求解八皇后問題
二叉樹五種形態:
空樹
只有根節點
根節點只有左子樹
根節點只有右子樹
根節點既有左子樹又有右子樹