子女-兄弟链表表示法,是一种二叉树表示法。它的每个结点的度d=2,每个结点由3个域组成:
|data|firstChild|nextSibling|
左孩子右兄弟。
树的遍历
利用子女-兄弟链实现遍历
树的深度优先遍历:利用递归进行先根次序遍历和后根次序遍历。
树的广度优先遍历:借助队列。在访问某一层的结点时,扫描它的所有子女(循子女的右兄弟链),把它们依次进队列。
//深度优先
# include<iostream.h>
#include"tree.h"
template<class T>
void PreOrder(ostream& out, TreeNode<T> *p){//先根次递归
if(p!=NULL){
out<<p->data;
for(p=p->firstChild;p!=NULL;p=p->nextSibling)
PreOrder(out,p);
}
}
template<class T>
void PostOrder(ostream& out, TreeNode<T> *p){
if(p!=NULL){
TreeNode<T> *q;
for(p=p->firstChild;p!=NULL;p=p->nextSibling)
PostOrder(out,p);
out<<p->data;
}
}
//广度优先
#include<iostream.h>
#include"tree.h"
#include"queue.h"
template<class T>
void LevelOrder(ostream& out, TreeNode<T> *p){
Queue<TreeNode<T>*>Q;
if(p!=NULL){
Q.EnQueue(p);//根指针进入队列
while(!Q.IsEmpty()){
Q.DeQueue(p);//队列中取一个结点
cout<<p->data;
for(p=p->firstChild;p!=NULL;p=p->nextSibling)
Q.EnQueue(p);//待访问结点的子女进队列
}
}
}
堆
一个关键码集合K={k0,k1,k2,…,kn-1},把它的所有元素按完全二叉树的顺序存放在一个一维数组中。
最小堆:任一结点的关键码均小于或等于它的左右子女的关键码,位于堆顶的结点关键码是整个集合中最小的。
最大堆:任一结点的关键码均大于或等于它的左右子女的关键码,位于堆顶的结点关键码是整个集合中最大的。
最小堆的下滑调整算法:从结点start开始到m为止,自上而下比较,如果子女的值小于父结点的值,则关键码小的上浮,继续向下层比较。
template<class T,class E>
void MinHeap<T>::siftDown(int start, int m){
int i=start, j=2*i+1;//j是i的左子女
E temp = heap[i];
while(j<=m){
if(j<m && heap[j]>heap[j+1])//找到子女的小者
j++;
if(temp<=heap[j]) break;
else{heap[i]=heap[j];i=j;j=2*j+1;}//小者上浮,i,j下降;
}
heap[i]=temp;//调整完,将temp中暂存的元素放到最终i下滑的位置
};
堆插入的上滑调整操作与插入算法(在已建成最小堆的最后插入新结点)
template<class T, class E>
void MinHeap<T>::siftUp(int start){
//从结点start开始到结点0为止,自下向上比较,如果子女的值小于父结点的值,则相互交换,这样集合调整为最小堆
int j=start, i=(j-1)/2;
E temp = heap[j];
while(j>0){
if(heap[i[<=temp) break;
else{heap[j]=heap[i];j=i;i=(i-1)/2;}//这里(i-1)/2中i不管是左子女还是右子女都能找到相同的父结点
}
heap[j]=temp;
}
template<class T, class E>
bool MinHeap<T>::Insert(const E& x){
if(currentSize==maxHeapSize)
{cerr<<"Heap Full"<<enld;return false;}//堆满
heap[currentSize]=x;
siftUp(currentSize);
currentSize++;
return true;
}
Huffman树
路径:从树中一个结点到另一个结点之间的分支构成之间的路径。
路径长度:指路径上的分支条数。树的路径长度是从根结点到每个结点的路径长度之和。
Huffman树:带权路径长度最小的二叉树应是权值大的外结点离根结点最近的扩充二叉树。
Huffman算法:
- 根据给定的n个权值,构造具有n棵扩充二叉树的森林F={T1,T2,…,Tn},其中每棵扩充二叉树只有一个带权值的根结点。
- 重复以下步骤,直到F中只剩一颗树为止:
- 在F中选取两棵根结点的权值最小的扩充二叉树,作为左、右子树构造一棵新的二叉树。新的二叉树的根结点的权值为左右子树的权值之和。
- 在F中删除这两棵二叉树
- 把新的二叉树加入F