1、二叉树的基本操作
内容:
1)采用二叉链表结构建立二叉树
2)编程实现二叉树的先序、中序、后序和层序遍历
3)编程实现非递归中序遍历
4)编程实现:求二叉树的高度和叶子结点个数
实现思路
① 设置存储空间的初始分量
② 定义结构体类型的二叉树数据类型,并引入堆栈
③ 实现先序建立二叉树、前序遍历二叉树、中序遍历二叉树、后序遍历二叉树、层序遍历二叉树、先序非递归遍历二叉树、求二叉树深度、求叶子结点个数等函数
④ 先序建立二叉树、前序遍历二叉树、中序遍历二叉树、后序遍历二叉树、求二叉树深度、求叶子结点个数使用递归实现
⑤ 层序遍历二叉树使用数组或者队列实现
⑥ 先序非递归遍历二叉树使用堆栈和循环实现
⑦ 在主函数里面调用各个方法进行检验
二叉树基本操作程序代码:
#include <iostream>
using namespace std;
#define MAXSIZE 100 //顺序栈存储空间的初始配量
#define OK 1
#define ERROR 0
typedef char TElemType;
typedef struct BiTNode //二叉树
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef BiTree ElemType;
typedef struct StackNode //链栈的存储结构
{
ElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
void InitStack(LinkStack &S) //链栈的初始化
{
S=NULL;
}
void Push(LinkStack &S,ElemType e)
{
StackNode *p=new StackNode;
p->data=e;
p->next=S;
S=p;
}
void Pop(LinkStack &S,ElemType &e)
{
if(S==NULL)
return;
e=S->data;
StackNode *p=S;
S=S->next;
delete p;
}
bool StackEmpty(LinkStack S)
{
if(S==NULL)
return true;
return false;
}
void CreateBiTree(BiTree &T) //先序建立二叉树
{
char ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T) //前序遍历
{
if(T)
{
cout<<T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T) //中序遍历
{
if(T)
{
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T) //后续遍历
{
if(T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data;
}
}
void LevelOrderTraverse(BiTree T) //层次遍历
{
BiTree temp[100];
int in=0;
int out=0;
temp[in++]=T;
while(in>out)
{
if(temp[out])
{
cout<<temp[out]->data;
temp[in++]=temp[out]->lchild;
temp[in++]=temp[out]->rchild;
}
out++;
}
}
int Depth(BiTree T) //二叉树深度
{
if(T==NULL)
return 0;
else
{
int m=Depth(T->lchild);
int n=Depth(T->rchild);
if(m>n)
return m+1;
else
return n+1;
}
}
void InOrderTraverse_1(BiTree T) //中序非递归遍历
{
LinkStack S;
InitStack(S);
BiTree p=T;
BiTree q=new BiTNode;
while(p || !StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->lchild;
}
else
{
Pop(S,q);
cout<<q->data;
p=q->rchild;
}
}
}
int leave_number(BiTree T) //叶子结点的个数
{
if(T==NULL)
return 0;
if(T->lchild==NULL && T->rchild==NULL)
return 1;
return leave_number(T->lchild)+leave_number(T->rchild);
}
int main()
{
BiTree T;
//InitBiTNode(&T);
cout<<"请输入二叉树:"<<endl;
CreateBiTree(T);
cout<<"先序遍历:";
PreOrderTraverse(T); cout<<endl;
cout<<"后序遍历:";
PostOrderTraverse(T); cout<<endl;
cout<<"中序遍历:";
InOrderTraverse(T); cout<<endl;
cout<<"层序遍历:";
LevelOrderTraverse(T); cout<<endl;
cout<<"深度为:"<<Depth(T)<<endl;
cout<<"中序非递归遍历:";
InOrderTraverse_1(T); cout<<endl;
cout<<"叶子结点个数:";
cout<<leave_number(T);
return 0;
}
2、哈夫曼编码
内容:
1) 给定报文中26个字母a-z及空格的出现频率{64, 13, 22, 32, 103, 21, 15, 47, 57, 1, 5, 32, 20, 57, 63, 15, 1, 48, 51, 80, 23, 8, 18, 1, 16, 1,168},构建哈夫曼树并为这27个字符编制哈夫曼编码,并输出
2)模拟发送端,从键盘输入字符串,以%为结束标记,在屏幕上输出输入串的编码
3)模拟接收端,从键盘上输入0-1哈夫曼编码串,翻译出对应的原文。
实现思路:
① 定义结构体类型的哈夫曼树数据类型
② 实现哈夫曼树的初始化,父结点、子结点都赋值为0
③ 实现Select函数搜索哈夫曼树里面最小的两个结点并返回
④ 实现创建二叉树,不断搜索最小的两个结点加入树中
⑤ 实现创建哈夫曼编码函数,左子树为0,右子树为1,从叶子结点向上寻找直到根节点
⑥ 实现转码函数和翻译函数(从根向下0向左1向右)
⑦ 主函数进行函数调用,实现程序
哈夫曼编码程序代码:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
typedef map<int,string> HuffmanCode;
int a[27];
//哈夫曼树的存储结构
typedef struct
{
int weight;
char c;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
void Select(HuffmanTree HT,int n,int &s1,int &s2)
{
for(int i=1;i<=n;i++)
{
if(HT[i].parent == 0)
{
if(s1 == 0)
s1=i;
else
{
s2=i;
break;
}
}
}
if(HT[s1].weight > HT[s2].weight)
{
int t=s1;
s1=s2;
s2=t;
}
for(int i=1;i<=n;i++)
{
if(HT[i].parent == 0)
{
if(HT[i].weight < HT[s1].weight)
{
s2=s1;
s1=i;
}
else if(HT[i].weight < HT[s2].weight && i!=s1)
{
s2=i;
}
}
}
}
//初始化哈夫曼树
void initHuffmanTree(HuffmanTree &HT)
{
int n=27;
int m = 2 * n - 1;
HT = new HTNode[m+1];
for(int i = 0; i <= m; i++) //将m个元素的双亲、左孩子、右孩子的小标都初始化为0
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(int i=1;i<=n;i++) //输入前n个单元中叶子结点的权值
{
HT[i].weight=a[i-1];
HT[i].c='a'+i-1;
}
HT[27].c=' ';
}
//创建哈夫曼树
void CreatHuffmanTree(HuffmanTree &HT)
{
int n=27;
int m = 2 * n - 1;
for(int i=n+1;i<=m;i++)
{
int s1=0;
int s2=0;
Select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC)
{
int n=27;
for(int i=1;i<=n;i++)
{
string str="";
int c=i;
int f=HT[i].parent;
while(f!=0)
{
if(HT[f].lchild==c)
str += "0";
else
str += "1";
c=f;
f=HT[f].parent;
}
reverse(str.begin(),str.end());
HC[i] = str;
}
}
//字符串转码
string zhuanma(HuffmanCode HC,string str)
{
string s="";
for(int i=0;i<str.length();i++)
{
if(str[i]>='A'&&str[i]<='Z')
str[i]=str[i]+32;
if(str[i]==' ')
{
s+=HC[27];
}
else
{
s+=HC[str[i]-'a'+1];
}
}
return s;
}
//译码
void translation(HuffmanTree HT,string str)
{
HTNode ht=HT[53];
cout<<"翻译结果为:"<<endl;
for(int i=0;i<str.length();i++)
{
if(str[i]=='0')
ht=HT[ht.lchild];
else
ht=HT[ht.rchild];
if(ht.lchild==0&&ht.rchild==0)
{
cout<<ht.c;
ht=HT[53];
}
}
}
int main()
{
string str="abcdefghijklmnopqrstuvwxyz ";
int flag=1;
HuffmanTree HT;
HuffmanCode HC;
int n=27;
while(flag)
{
cout<<"****************************************************************************************"<<endl;
cout<<"******************* 1.输入HuffmanTree的参数。 *******************"<<endl;
cout<<"******************* 2.初始化HuffmanTree的参数。(含有26字母及空格) *******************"<<endl;
cout<<"******************* 3.创建HuffmanTree和编码表。 *******************"<<endl;
cout<<"******************* 4.输出编码表。 *******************"<<endl;
cout<<"******************* 5.输入编码,并翻译为字符。 *******************"<<endl;
cout<<"******************* 6.输入字符,并实现转码。 *******************"<<endl;
cout<<"******************* 7.退出。 *******************"<<endl;
cout<<"****************************************************************************************"<<endl;
int ip;
cout<<"请输入指令:";
cin>>ip;
switch(ip)
{
case 1:
{
cout<<"请按顺序输入HuffmanTree的27个参数:"<<endl;
for(int i=0;i<27;i++)
cin>>a[i];
break;
}
case 2:
{
initHuffmanTree(HT);
cout<<"参数初始化成功"<<endl;
cout<<"结点i\tweight\tparent\tlchild\trchild\n";
for(int i=1;i<2*n;i++)
cout<<i<<"\t"<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<endl;
system("pause");
break;
}
case 3:
{
CreatHuffmanTree(HT);
CreateHuffmanCode(HT,HC);
cout<<"创建成功"<<endl;
for(int i=1;i<2*n;i++)
cout<<i<<"\t"<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<endl;
system("pause");
break;
}
case 4:
{
cout<<"字符编号\t哈夫曼编码"<<endl;
for(map<int,string>::iterator iter=HC.begin();iter!=HC.end();iter++)
{
cout<<"'"<<str[iter->first-1]<<"'"<<"\t\t"<<iter->second<<endl;
}
system("pause");
break;
}
case 5:
{
string s;
cout<<"请输入需要翻译的编码:"<<endl;
cin>>s;
translation(HT,s);
cout<<endl;
system("pause");
break;
}
case 6:
{
string s;
cout<<"请输入需要转码的字符串:"<<endl;
cin.ignore();
getline(cin,s);
cout<<"字符串对应的编码为:\n"<<zhuanma(HC,s)<<endl;
system("pause");
break;
}
case 7:
{
flag=0;
break;
}
default :
{
cout<<"指令错误!请重新输入!"<<endl;
system("pause");
break;
}
}
system("cls");
}
return 0;
}
/*
hello world
h 0001
e 010
l 10111
l 10111
o 1001
111
w 110001
o 1001
r 0010
l 10111
d 10110
000101010111101111001111110001100100101011110110
*/