本文章主要包括以下内容:
1、 创建最大堆类。最大堆的存储结构使用链表。
2、 提供操作:堆的插入、堆的删除。堆的初始化。Huffman树的构造。二叉搜索树的构造。
3、 接收键盘录入的一系列整数,输出其对应的最大堆、Huffman编码以及二叉搜索树。
4、 堆排序。
下面是c++代码实现:
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stack>
using namespace std;
#define MAXSIZE 20
#define MAXDEPTH 10
class BinaryTreeNode//二叉树节点类
{
public:
BinaryTreeNode() {leftChild = rightChild = 0;}
BinaryTreeNode(int d) {data = d; leftChild = rightChild = 0;}
BinaryTreeNode(int d, BinaryTreeNode* left, BinaryTreeNode* right) {data = d; leftChild = left; rightChild = right;}
int data;
BinaryTreeNode* leftChild;
BinaryTreeNode* rightChild;
};
class MaxHeap//最大堆类
{
private:
int currentSize, maxSize;
int* heap;
public:
MaxHeap(int size = 10)//类初始化
{
maxSize = size;
heap = new int[maxSize + 1];
currentSize = 0;
}
void init(int array[], int arrayCurrentSize, int arrayMaxSize)//接收一个数组产生一个最大堆
{
delete [] heap;
heap = array;
currentSize = arrayCurrentSize;
maxSize = arrayMaxSize;
// 产生一个最大堆
for(int i = currentSize / 2; i >= 1; i--)
{
int y = heap[i];// 子树的根
// 寻找放置 y的位置
int c = 2*i;// c的父节点是y的目标位置
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 insert(int x)//插入一个元素
{
if(currentSize == maxSize) {cout << "out of bounds"; return;}
int i = ++currentSize;
while(i != 1 && x > heap[i / 2])
{
heap[i] = heap[i / 2];
i /= 2;
}
heap[i] = x;
}
int deleteMax()//删除最大元素
{
if(currentSize == 0) {cout << "there is no mem"; return -1;}
int x = heap[1];
// 重构堆
int y = heap[currentSize--];// 最后一个元素
// 从根开始,为 y 寻找合适的位置
int i = 1;
int ci = 2;
while(ci <= currentSize)
{
if(ci < currentSize && heap[ci] < heap[ci + 1]) ci++;
if(y >= heap[ci]) break;//这是while的跳出条件,即为最后的节点找到适当的位置
heap[i] = heap[ci];//把孩子放入上一层
i = ci;//下移一层
ci *= 2;
}
heap[i] = y;
return x;
}
};
//下面是堆排序
void heapSort(int a[], int n)
{
int b[n + 1];
MaxHeap maxHeap;
maxHeap.init(a, n, n);
for(int i = 1; i <= n; i++)
{
cout << maxHeap.deleteMax() << endl;
}
for(int i = 1; i <= n; i++)
{
a[i] = b[i];
}
}
class BinarySearchTree//搜索树类
{
public:
BinaryTreeNode* root;
BinarySearchTree() {root = 0;}
void insert(int e)//插入一个元素
{
BinaryTreeNode* p = root;
BinaryTreeNode* pp = 0;// p的父节点指针
while(p)
{//检查 p - > d a t a
pp = p;
if(e < p->data) p = p->leftChild;// 将p移向孩子节点
else if(e > p->data) p = p->rightChild;
else {cout << "bad input"; return;}//又重复的
}
// 为e 建立一个节点,并将该节点连接至 to pp
BinaryTreeNode* r = new BinaryTreeNode(e);
if(root)
{
if(e < pp->data) pp->leftChild = r;
else pp->rightChild = r;
}
else
root = r;
}
void preOrder(BinaryTreeNode* t)//前序遍历
{
if(t != NULL)
{
preOrder(t->leftChild);
cout << t->data << endl;
preOrder(t->rightChild);
}
}
};
class HuffmanTree
{
public:
//数组a储存的是各个树的权重
HuffmanTree(int a[], int n)
{
b = new BinaryTreeNode*[100];
for(int i = 0; i < n; i++)
b[i] = new BinaryTreeNode(a[i + 1]);
for(int i = 1; i < n; i++)//进行 n-1 次循环建立哈夫曼树
{
//k1表示森林中具有最小权值的树根结点的下标,k2为次最小的下标
int k1 = -1, k2;
for(int j = 0; j < n; j++)//让k1初始指向森林中第一棵树,k2指向第二棵
{
if(b[j] != NULL && k1 == -1)
{
k1 = j;
continue;
}
if(b[j] != NULL)
{
k2 = j;
break;
}
}
for(int j = k2; j < n; j++)//从当前森林中求出最小权值树和次最小
{
if(b[j] != NULL)
{
if (b[j]->data < b[k1]->data)
{
k2 = k1;
k1 = j;
}
else if (b[j]->data < b[k2]->data)
k2 = j;
}
}
//下面是最小和次最小的合并
BinaryTreeNode *q = new BinaryTreeNode();
q->data = b[k1]->data + b[k2]->data;
q->leftChild = b[k1];
q->rightChild = b[k2];
b[k1] = q;
b[k2] = NULL;
}
}
void preOrder(BinaryTreeNode* b)//这是遍历一个树的函数
{
if (b != NULL)
{
cout << b->data << endl;
preOrder(b->leftChild);
preOrder(b->rightChild);
}
}
void printCode(BinaryTreeNode* b, int len)//这是打印霍夫曼编码的函数
{
static int code[MAXDEPTH];
if(b != NULL)
{
if(b->leftChild == NULL && b->rightChild == NULL)
{
cout << "the huffman code of " << b->data << " is ";
for(int i = 0; i < len; i++)
{
cout << code[i];
}
cout << endl;
}
code[len] = 0;
printCode(b->leftChild, len + 1);
code[len] = 1;
printCode(b->rightChild, len + 1);
}
}
BinaryTreeNode** b;
};
int main()
{
int a[MAXSIZE];
int n;
cout << "输入数组长度:" << endl;
cin >> n; //输入样例 5
cout << "输入数据:" << endl;
for(int i = 1; i <= n; i++) //输入样例 1 32 21 35 41
cin >> a[i];
cout << "bst:" << endl;
BinarySearchTree bstree;
for(int i =1; i <= 5; i++)
bstree.insert(a[i]);
cout << "preOrder:" << endl;
bstree.preOrder(bstree.root);
cout << "huffman:" << endl;
HuffmanTree htree(a, 5);
htree.preOrder(*htree.b);
// htree.printCode(htree.b[0], 0);
cout << "heap sort:" << endl;
heapSort(a, 5);
system("pause");
return 0;
}