实验六 堆和搜索树
一、 实验目的
掌握堆和搜索树的基本概念,插入、删除方法。
二、 实验内容
1、输入一系列不为零的正整数(最多不超过 20 个),遇到 0 代表输入结 束(不包含 0)。
2、根据上面输入的数据序列,用初始化方法创建最大堆(不要用节点依 次插入的办法创建最大堆),然后输出最大堆的层次序列。
3、输出用堆排序后的排序结果。
4、根据上面输入的数据,创建二叉搜索树(关键字不允许重复,如遇重 复,则不重复插入该关键字),输出二叉搜索树的前序序列、中序序 列(分行输出)。
代码如下:
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<queue>
using namespace std;
int a[25],b[25],n;
int &size=n;
int count=1;
//定义最大堆类
class maxheap{
public:
int heap[25];//需要初始化数组空间大小,否则容易出错
int heapsize;
void init();
int top(){return heap[1];}//返回最大元素的值
void pop();
};
void maxheap::init(){//根据输入的数组元素初始化最大堆
for(int i=1;i<=n;i++) heap[i]=a[i];
heapsize=n;
for(int root=heapsize/2;root>=1;root--){
int rootElement=heap[root];
int child=2*root;
while(child<=heapsize){
if(child<heapsize&&heap[child]<heap[child+1])child++;
if(rootElement>=heap[child])break;
heap[child/2]=heap[child];
child*=2;
}
heap[child/2]=rootElement;
}
}
//删除最大的元素,重新排列最大堆
void maxheap::pop(){
int lastElement=heap[heapsize--];
int cur=1,child=2;//从根开始
while(child<=heapsize){
if(child<heapsize&&heap[child]<heap[child+1])child++;
if(lastElement>=heap[child])break;
heap[cur]=heap[child];
cur=child;
child*=2;
}
heap[cur]=lastElement;
}
//输出最大堆的层次序列
void print(int a[],int n){ for(int i=1;i<n;i++)
cout<<a[i]<<",";
cout<<a[n]<<endl;
}
//堆排序
void heapsort(const int a[],int b[],int n){ maxheap mh;
mh.init();
for(int i=n;i>=1;i--){
b[i]=mh.top();
mh.pop();
}
maxheap mmh;
mh=mmh;
}
//定义二叉搜索树类
class BStreeNode{public:
int element;
BStreeNode *leftchild,*rightchild;
BStreeNode(){leftchild=rightchild=NULL;}
BStreeNode(int& theE,BStreeNode* theleft=NULL,BStreeNode*theright=NULL){
element=theE;
leftchild=theleft;
rightchild=theright;
}
};
//按节点依次插入的方法创建二叉搜索树
void insert(BStreeNode *root,int num){
BStreeNode *p=root;
BStreeNode *prep;
while(p!=NULL){
if(p->element==num){
size--;return;
}
prep=p;
if(num>p->element){p=p->rightchild;}
else if(num<p->element){p=p->leftchild;}
}
BStreeNode *np=new BStreeNode(num);
if(root!=NULL){
if(num<prep->element){prep->leftchild=np;}
else if(num>prep->element){prep->rightchild=np;}
}
else root=np;
return;
}
void pre(BStreeNode* t){//前序序列输出
if(t!=NULL){
if(count!=size) cout<<t->element<<",";
else cout<<t->element<<endl;
count++;
pre(t->leftchild);
pre(t->rightchild);
}
}
void in(BStreeNode* t){//中序序列输出
if(t!=NULL){
in(t->leftchild);
if(count!=size) cout<<t->element<<",";
else cout<<t->element<<endl;
count++;
in(t->rightchild);
}
}
int main(){
cout<<"Input"<<endl;
for(n=1;cin>>a[n]&&a[n]!=0;n++);
n--;
cout<<"Output"<<endl;
maxheap mh;
mh.init();
print(mh.heap,mh.heapsize);
heapsort(a,b,n);
print(b,n);
BStreeNode *bst=new BStreeNode(a[1]);
for(int i=2;i<=n;i++) {
insert(bst,a[i]);
}
pre(bst);count=1;in(bst);
cout<<"End"<<endl;
return 0;
}
结论分析与体会:
复习了最大堆和二叉搜索树相关的知识点,并通过实验得出类内成员数组需要初始化数组的空间大小,否则容易出错的结论,解决了逻辑正确但输出错误的问题。