最大堆的插入删除初始化
Huffman树的构造,输出huffman编码
搜索二叉树的插入删除输出
以下作为模板类,方法均在头文件中,否则报错
一共九个类~~~~~~
第一个,树节点BinaryTreeNode.h
template <class T>
class BinaryTree;
template <class T>
class BinaryTreeNode
{
friend class BinaryTree<T>;
friend void Visit(BinaryTreeNode<T> *);
friend void PreOrder(BinaryTreeNode<T> *);
friend void InOrder(BinaryTreeNode<T> *);
friend void PostOrder(BinaryTreeNode<T> *);
friend void LevelOrder(BinaryTreeNode<T> *);
friend void main(void);
public:
BinaryTreeNode(){ LeftChild=RightChild=0;}
virtual ~BinaryTreeNode(){}
BinaryTreeNode(const T& e)
{
data=e;
LeftChild=RightChild=0;
}
BinaryTreeNode(const T& e,BinaryTreeNode *l,BinaryTreeNode *r)
{
data=e;
LeftChild=l;
RightChild=r;
}
void Delete(){delete LeftChild;delete RightChild;delete t;}
T data;
BinaryTreeNode<T> *LeftChild,*RightChild;
};
第二个,树BinaryTree.h
#include "BinaryTreeNode.h"
#include "iostream.h"
#include "Chain.h"
#include "Huffman.h"
#include "MinHeap.h"
#include <string>
using namespace std;
template <class T>
class BinaryTree
{
public:
BinaryTree(){ root=0;}
virtual ~BinaryTree(){}
bool IsEmpty() const{}
bool Root(T& x) const;
void MakeTree(const T& element,BinaryTree<T>& left,BinaryTree<T>& right)
{
root=new BinaryTreeNode<T>(element,left.root,right.root);
left.root=right.root=0;
}
void BreakTree(T& element,BinaryTree<T>& left,BinaryTree<T>& right);
//遍历~~~
void PreOrder(void(*Visit)(BinaryTreeNode<T> *u));
void InOrder(void(*Visit)(BinaryTreeNode<T> *u));
void PostOrder(void(*Visit)(BinaryTreeNode<T> *u));
void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u))//用NOde自己做个队列~~~
{
BinaryTreeNode<T> *queue[50];//设置一个Node指针数组
int front=0;//队列头
int tail=1;//队列尾
BinaryTreeNode<T> *t;//临时变量,以防传入参访问时改变原树
t=root;
queue[tail]=t;//初始存入,在尾部
while(front!=tail)
{
front++;
cout<<queue[front]->data<<" ";//输出头,第一个元素
if(queue[front]->LeftChild!=NULL)//左不为空,加入队尾
{
tail++;
queue[tail]=queue[front]->LeftChild;
}
if(queue[front]->RightChild!=NULL)//右不为空,加入队尾
{
tail++;
queue[tail]=queue[front]->RightChild;
}//循环知道结束
}
}
//得到高度
int Height() const{return Height(root);}
//输入前中,输出后用到的三个方法
void GetPost(int a[],int s1,int e1,int b[],int s2,int e2,int cot );
int Find(int sourc[],int des ,int cout );
void InputTree(int a[],int cot);
//得到节点数的两个方法~
int Size()
{
count=0;
PreOrder(Add1,root);
return count;
}
static void Add1(BinaryTreeNode<T> *t){count++;}
static void Output(BinaryTreeNode<T> *t)
{
if(t->data<0)
return;
cout <<t->data<<" ";
}
//删除树/元素的方法
static void Free(BinaryTreeNode<T> *t){delete t;}
static void Delete1(BinaryTreeNode<T> *t)
{
if(t->data==att)
{
delete t;//那么此时指向他的指针指向了个空间,再次访问时候,得到一串地址~~需要思考下
t->LeftChild=NULL;
t->RightChild=NULL;
//t->data=0;
}
}
BinaryTree<int> HuffmanTree(int a[],int n)
{
Huffman<int> *w=new Huffman<int>[n+1];
BinaryTree<int> z,zero;
for(int i=1;i<=n;i++)
{
z.MakeTree(a[i],zero,zero);
w[i].weight=a[i];
w[i].tree=z;
}
MinHeap<Huffman<T> > H(1);
H.Initialize(w,n,n);
Huffman<int> x,y;
for(i=1;i<n;i++)
{
H.DeleteMin(x);
H.DeleteMin(y);
z.MakeTree(0,x.tree,y.tree);
x.weight+=y.weight;
x.tree=z;
H.Insert(x);
}
H.DeleteMin(x);
H.Deactivate();
delete [] w;
return x.tree;
}
//这个方法输出huffman编码
void OutputCode(BinaryTree<int> huf,Chain& A,int cx,int& ze,int& on)
{
BinaryTreeNode<int> *t;
t=huf.root;
BinaryTree left,right;
if(t->LeftChild )//找到原因:递归中连续几个if与if,else,if,else是有区别的,我晕
{
A.Insert(A.Length(),ze);
left.root=t->LeftChild;
OutputCode(left,A,cx,ze,on);
}
if(t->RightChild)
{
A.Insert(A.Length(),on);
right.root=t->RightChild;
OutputCode(right,A,cx,ze,on);
}
if(t->LeftChild==NULL && t->RightChild==NULL)
{
cout <<t->data<<"编码 : ";
A.Output();
A.Delete(A.Length(), cx);
return;
}
if(A.Length()>=1)
A.Delete(A.Length(), cx);
if(A.Length()==0)
return;
return;
}
void Delete(){PostOrder(Free,root);root=0;}
void DeleteAtt(){PostOrder(Delete1,root);}
void PreOutput(){PreOrder(Output,root);cout<<endl;}
void InOutput(){InOrder(Output,root);cout<<endl;}
void PostOutput(){PostOrder(Output,root);cout<<endl;}
void LevelOutput(){LevelOrder(Output);cout<<endl;}
BinaryTreeNode<T> *root;
private:
//static void Add1(BinaryTreeNode<T> *t){count++;}
void PreOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t)
{
if(t==NULL)
return;
if(t)
{
Visit(t);
PreOrder(Visit,t->LeftChild);
PreOrder(Visit,t->RightChild);
}
}
void InOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t)
{
if(t)
{
InOrder(Visit,t->LeftChild);
Visit(t);
InOrder(Visit,t->RightChild);
}
}
void PostOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
int Height(BinaryTreeNode<T> *t) const;
};
第三个,二叉搜索树BSTree.h
#include "BinaryTreeNode.h"
template <class E,class K>
class BSTree:public BinaryTree<E>
{
public:
BSTree(){}
virtual ~BSTree(){}
bool Search(const K& k,E& e) const
{
BinaryTreeNode<E> *p=root;
while(p)
if(k<p->data) p=p->LeftChild;
else if(k>p->data) p=p->RightChild;
else
{
e=p->data;
return true;
}
return false;
}
BSTree<E,K>& Insert(const E& e)
{
BinaryTreeNode<E> *p=root,*pp=0;
while(p)
{
pp=p;
if(e<p->data) p=p->LeftChild;
else if(e>p->data) p=p->RightChild;
else throw OutOfBounds();
}
BinaryTreeNode<E> *r=new BinaryTreeNode<E>(e);
if(root)
{
if(e<pp->data) pp->LeftChild=r;
else pp->RightChild=r;
}
else
root=r;
return *this;
}
BSTree<E,K>& Delete(const K& k,E& e)
{
BinaryTreeNode<E> *p=root,*pp=0;
while(p && p->data!=k)
{
pp=p;
if(k<p->data) p=p->LeftChild;
else p=p->RightChild;
}
if(!p) throw OutOfBounds();
e=p->data;
if(p->LeftChild && p->RightChild)
{
BinaryTreeNode<E> *s=p->LeftChild,*ps=p;
while(s->RightChild)
{
ps=s;
s=s->RightChild;
}
p->data=s->data;
p=s;
pp=ps;
}
BinaryTreeNode<E> *c;
if(p->LeftChild) c=p->LeftChild;
else c=p->RightChild;
if(p==root) root=c;
else
{
if(p==pp->LeftChild)
pp->LeftChild=c;
else
pp->RightChild=c;
}
delete p;
return *this;
}
void Ascend(){InOutput();}
};
第四个,链表Chain.h,Chain.cpp~~~用VC的在建的时候记得改名字
class ChainNode
{
public:
friend class Chain;
int data;
ChainNode *link;
};
class Chain
{
public:
Chain();
virtual ~Chain();
int Length() const;
int Search(const int&x) const;
Chain& Delete(int k,int& x) ;
Chain& Insert(int k,int& x);
Chain& Append(int& x);
Chain& DeleteLast();
void Output();
ChainNode *first;
};
#include "Chain.h"
#include "iostream.h"
//
// Construction/Destruction
//
Chain::Chain()
{
first =0;
}
Chain::~Chain()//析构
{
ChainNode *next;
while(first )
{
next=first->link;
//delete first;
first=next;
}
}
int Chain::Length() const//获得链表大小
{
ChainNode *current=first;
int len=0;
while(current)
{
len++;
current=current->link;
}
return len;
}
int Chain::Search(const int&x) const//搜索一个值
{
ChainNode *current=first;
int index=1;
while(current && current->data !=x)
{
current=current->link;
index++;
}
if(current) return index;
return 0;
}
void Chain::Output()
{
ChainNode *current=first;
while(current)
{
cout <<current->data;
current=current->link;
}
cout <<endl;
}
Chain& Chain::Delete(int k,int& x) //删除地k个元素,并保存在x中
{
if(k<1 || !first)//k小于一~~为什么??
{
cout << "ERROR: OutOfBound AAAA";
return *this;
}
ChainNode *p=first;
if(k==1)
first=first->link;
else
{
ChainNode *q=first;
for(int index=1;index<k-1 && q;index++)
q=q->link;
if(!q || !q->link)
{
cout << "ERROR: OutOfBound BBBB";
return *this;
}
p=q->link;
q->link=p->link;
}
x=p->data;
delete p;
return *this;
}
Chain& Chain::Insert(int k,int& x)//在第k个元素后插入x
{
if(k<0)
{
cout << "ERROR: OutOfBound CCCC";
return *this;
}
ChainNode *p=first;
for(int index=1;index<k && p;index++)
p=p->link;
if(k>0 && !p)
{
cout << "ERROR: OutOfBound DDDD";
return *this;
}
ChainNode *y=new ChainNode;
y->data=x;
if(k)
{
y->link=p->link;
p->link=y;
}
else
{
y->link=first;
first=y;
}
return *this;
}
第五个Huffman.h~~~提供节点信息,具体操作在 BinaryTree中
#include "BinaryTree.h"
template <class T>
class Huffman
{
friend BinaryTree<int> HuffmanTree(T [],int);
public:
virtual ~Huffman(){}
//暂时注解~~~
operator T () const {return weight;}
BinaryTree<int> tree;
T weight;
};
第六个,最大堆 MaxHeap.h
#include "iostream.h"
template <class T>
class MaxHeap
{
public:
MaxHeap(int MinHeapSize=10)
{
MaxSize=10;
heap=new T[MaxSize+1];
CurrentSize=0;
}
virtual ~MaxHeap(){delete [] heap;}
int Size() const {return CurrentSize;}
int Max()
{
if(CurrnetSize==0) throw OutOfBounds();
return heap[1];
}
MaxHeap<T>& Insert(const T& x)
{
if(CurrentSize==MaxSize);//throw NoMem();
int i=++CurrentSize;
while(i !=1 && x>heap[i/2])
{
heap[i]=heap[i/2];
i/=2;
}
heap[i]=x;
return *this;
}
MaxHeap<T>& DeleteMax(T& x)
{
if(CurrentSize==0) throw OutOfBounds();
x=heap[1];
T y=heap[CurrentSize--];
int i=1;
int ci=2;
while(ci<=CurrentSize)
{
if(ci<CurrentSize && heap[ci]<heap[ci+1])
ci++;
if(y>=heap[ci])
break;
heap[i]=heap[ci];
i=ci;
ci*=2;
}
heap[i]=y;
return *this;
}
void Initialize(T a[],int size,int ArraySize)
{
delete [] heap;
heap=a;
CurrentSize=size;
MaxSize=ArraySize;
for(int i=CurrentSize/2;i>=1;i--)
{
T y=heap[i];
int c=2*i;
while(c<=CurrentSize)
{
if(c<CurrentSize && heap[c]<heap[c+1])
c++;
if(y>=heap[c])
break;
heap[c/2]=heap[c];
c*=2;
}
heap[c/2]=y;
}
}
void Deactivate(){heap=0;}
int CurrentSize,MaxSize;
T *heap;
};
第七个,最小堆MinHeap.h
#include "OutOfBounds.h"
template <class T>
class MinHeap
{
public:
MinHeap(int MinHeapSize=10)
{
MaxSize=MinHeapSize;
heap=new T[MaxSize+1];
CurrentSize=0;
}
void Initialize(T a[],int size,int ArraySize)
{
delete [] heap;
heap=a;
CurrentSize=size;
MaxSize=ArraySize;
for(int i=CurrentSize/2;i>=1;i--)
{
T y=heap[i];
int c=2*i;
while(c<=CurrentSize)
{
if(c<CurrentSize && heap[c]>heap[c+1])
c++;
if(y<=heap[c])
break;
heap[c/2]=heap[c];
c*=2;
}
heap[c/2]=y;
}
}
MinHeap<T>& DeleteMin(T& x)
{
if(CurrentSize==0) throw OutOfBounds();
x=heap[1];
T y=heap[CurrentSize--];
int i=1;
int ci=2;
while(ci<=CurrentSize)
{
if(ci<CurrentSize && heap[ci]>heap[ci+1])
ci++;
if(y<=heap[ci])
break;
heap[i]=heap[ci];
i=ci;
ci*=2;
}
heap[i]=y;
return *this;
}
MinHeap<T>& Insert(const T& x)
{
if(CurrentSize==MaxSize);//throw NoMem();
int i=++CurrentSize;//貌似这有些问题
while(i !=1 && x<heap[i/2])
{
heap[i]=heap[i/2];
i/=2;
}
heap[i]=x;
return *this;
}
void Deactivate(){heap=0;}
virtual ~MinHeap(){delete [] heap;}
int Size() const {return CurrentSize;}
int Min()
{
if(CurrnetSize==0) throw OutOfBounds();
return heap[1];
}
int CurrentSize,MaxSize;
T *heap;
};
第八个,异常OutOfBounds()建一个就是了,可以处理,这里为空
class OutOfBounds
{
public:
OutOfBounds();
virtual ~OutOfBounds();
};
第九个,总操作Operator.h,Operator.cpp
template <class T>
class Operator
{
public:
Operator();
virtual ~Operator();
};
#include "Operator.h"
#include "BinaryTree.h"
#include "BinaryTreeNode.h"
#include "Huffman.h"
#include "MaxHeap.h"
#include "Sort.h"
#include "Chain.h"
#include "BSTree.h"
#include "iostream.h"
//
// Construction/Destruction
//
template <class T>
Operator<T>::Operator()
{
}
template <class T>
Operator<T>::~Operator()
{
}
void main(void)
{
cout <<"开始对堆,Huffman树,二叉搜索树操作"<<endl;
int n;
cout <<"要输入数组元素个数:";
cin >>n;
int *a;
a=new int[n+1];
cout <<"要输入数组元素【不允许有相同元素】 :"<<endl;
for(int i=1;i<n+1;i++)
cin >>a[i];
BSTree<int,int> bstree;//搜索二叉树成功
for(int m=1;m<n+1;m++)
bstree.Insert(a[m]);
cout <<"中序输出二叉搜索树:";
bstree.InOutput();
BinaryTree<int> bt;
bt=bt.HuffmanTree(a,n);//构造树时出问题~~~解决!
cout <<"按中序输出huffman所有元素:";
bt.InOutput();
cout <<"输出huffman编码"<<endl;
int cx=0;
Chain A;
static int ze=0,on=1;
bt.OutputCode(bt,A,cx,ze,on);
MaxHeap<int> max;//最大堆成功
max.Initialize(a,n,n);
cout <<"按层输出最大堆所有元素:";
for(int j=1;j<=n;j++)
cout <<max.heap[j]<<" ";//有些问题~~貌似初始化失败---解决了~~汗
cout <<endl;
cout<<"堆排序:";//终于成功了~~~我晕ORZ~~~~
Sort<int> sor;
sor.HeapSort(a,n);
for(int h=1;h<n+1;h++)
cout <<a[h]<<" ";
cout <<endl;
}