算法5.1-5.6、5.7-5.9线索二叉树、5.10-5.11构造哈夫曼树求哈夫曼编码、5.12-5.13表达式求值

 """

一个不知名大学生,江湖人称菜狗
original author: jacky Li
Email : 3435673055@qq.com
Last edited: 2022.11.17

"""

2980e45a0ac243d4addb881dafa4c151.jpeg

目录

算法5.1-5.6

第1关:5.1,5.3中序遍历的递归算法

任务描述

相关知识

编程要求

测试说明

参考代码

第2关:5.2中序遍历的非递归算法

任务描述

相关知识

编程要求

测试说明

参考代码

第3关:5.4复制二叉树

任务描述

相关知识

编程要求

测试说明

参考代码

第4关:5.5计算二叉树的深度

任务描述

相关知识

编程要求

测试说明

参考代码

第5关:5.6统计二叉树中节点的个数

任务描述

相关知识

编程要求

测试说明

参考代码

算法5.7-5.9线索二叉树 

第1关:5.7-5.9线索化遍历

任务描述

相关知识

编程要求

测试说明

参考代码

算法5.10-5.11构造哈夫曼树求哈夫曼编码

第1关:例子5.3使用哈夫曼编码

任务描述

编程要求

测试说明

参考代码

算法5.12-5.13表达式求值

第1关:表达式树的求值

任务描述

编程要求

测试说明

参考代码


 

算法5.1-5.6

第1关:5.1,5.3中序遍历的递归算法

任务描述

本关任务:编写一个中序遍历的递归算法,包含算法5.1遍历算法和5.3先序遍历建立二叉树。

相关知识

为了完成本关任务,你需要掌握:1.如何中序遍历二叉树 2.如何先序遍历建立二叉树。

编程要求

根据提示,在右侧编辑器补充代码,并输出中序遍历的二叉树。

测试说明

平台会对你编写的代码进行测试:

测试输入:ABC##DE#G##F###;

预期输出:CBEGDFA


开始你的任务吧,祝你成功!

参考代码

//算法5.1 中序遍历的递归算法
#include<iostream>
using namespace std;

typedef struct BiNode{				//二叉链表定义
	char data;
	struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;

//用算法5.3 先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T){	
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
    char ch;
    cin>>ch;
    if(ch=='#') T=NULL;
    else{
        T=new BiTNode;
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}									//CreateBiTree

void InOrderTraverse(BiTree T)
{  
	//中序遍历二叉树T的递归算法
    if(T)
	{
        InOrderTraverse(T -> lchild);
        cout<< T -> data;
        InOrderTraverse(T -> rchild);
    }
}

int main(){
	BiTree tree;
	
	CreateBiTree(tree);

	InOrderTraverse(tree);
	cout<<endl;
}

第2关:5.2中序遍历的非递归算法

任务描述

本关任务:编写一个中序遍历的非递归算法,包含算法5.2非递归遍历算法和5.3先序遍历建立二叉树。

相关知识

为了完成本关任务,你需要掌握:1.如何中序非递归遍历二叉树 2.如何先序遍历建立二叉树。

编程要求

根据提示,在右侧编辑器补充代码,并输出中序遍历的二叉树。

测试说明

平台会对你编写的代码进行测试:

测试输入:ABC##DE#G##F###;

预期输出:CBEGDFA


开始你的任务吧,祝你成功!

参考代码

//算法5.2 中序遍历的非递归算法
#include<iostream>
using namespace std;

//二叉树的二叉链表存储表示
typedef struct BiNode
{				
	char data;						//结点数据域
	struct BiNode *lchild,*rchild;	//左右孩子指针
}BiTNode,*BiTree;

//链栈的定义
typedef struct StackNode
{
	BiTNode data;
	struct StackNode *next;
}StackNode,*LinkStack;

//用算法5.3 先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T)
{	
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			//递归结束,建空树
	else{							
		T=new BiTNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								//else
}									//CreateBiTree

void InitStack(LinkStack &S)
{
	//构造一个空栈S,栈顶指针置空
	S=NULL;
}

bool StackEmpty(LinkStack S)
{
	if(!S)
		return true;
	return false;
}

void Push(LinkStack &S,BiTree e)
{
	//在栈顶插入元素*e
	StackNode *p=new StackNode;
	p->data=*e;
	p->next=S;
	S=p;
}

void Pop(LinkStack &S,BiTree e)
{
	if(S!=NULL)//原书上写的是if(S==NULL)return ERROR;
	{	
		*e=S->data;
		StackNode *p=S;
		S=S->next;
		delete p;
	}
} 
  
void InOrderTraverse1(BiTree T)
{ 
  // 中序遍历二叉树T的非递归算法
	LinkStack S;
	InitStack(S);
	BiTree p, q;
	p = T, 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;
	    }
	}
}									// InOrderTraverse

int main()
{
	BiTree tree;

	CreateBiTree(tree);

	InOrderTraverse1(tree);
	cout<<endl;
}


第3关:5.4复制二叉树

任务描述

本关任务:编写一个中序遍历的递归算法,包含算法5.4复制二叉树。

相关知识

为了完成本关任务,你需要掌握:1.如何中序遍历二叉树 2.如何先序遍历建立二叉树 3.如何复制二叉树。

编程要求

根据提示,在右侧编辑器补充代码,并输出复制二叉树的中序遍历结果。

测试说明

平台会对你编写的代码进行测试:

测试输入:ABC##DE#G##F###;

预期输出:CBEGDFA


开始你的任务吧,祝你成功!

参考代码

//算法5.4 复制二叉树
#include<iostream>
using namespace std;

//二叉树的二叉链表存储表示
typedef struct BiNode
{				
	char data;						//结点数据域
	struct BiNode *lchild,*rchild;	//左右孩子指针
}BiTNode,*BiTree;

//用算法5.3建立二叉链表
void CreateBiTree(BiTree &T)
{	
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			//递归结束,建空树
	else{							
		T=new BiTNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								//else
}									//CreateBiTree

void Copy(BiTree T, BiTree &NewT)
{ 
	/***********************Begin******************/
    if(T == NULL)
	{
        NewT = NULL;
        return;
    }
    NewT = new BiTNode;
    NewT -> data = T -> data;
    Copy(T -> lchild, NewT -> lchild);
    Copy(T -> rchild, NewT -> rchild);
	/**********************End*******************/
}												//CopyBiTree

//用算法5.1 中序遍历的递归算法							
void InOrderTraverse(BiTree T)
{  
	//中序遍历二叉树T的递归算法
	if(T){
		InOrderTraverse(T->lchild);
		cout << T->data;
		InOrderTraverse(T->rchild);
	}
}
int main()
{
	BiTree tree,new_tree;
	
	CreateBiTree(tree);
	Copy(tree,new_tree);

	InOrderTraverse(new_tree);
	cout<<endl;
}

第4关:5.5计算二叉树的深度

任务描述

本关任务:编写一个计算二叉树深度的算法,如5.5所示。

相关知识

为了完成本关任务,你需要掌握:1.如何中序遍历二叉树 2.如何先序遍历建立二叉树 3.如何计算二叉树的深度。

编程要求

根据提示,在右侧编辑器补充代码,并输出二叉树的深度。

测试说明

平台会对你编写的代码进行测试:

测试输入:ABC##DE#G##F###

预期输出:5


开始你的任务吧,祝你成功!

参考代码

//算法5.5 计算二叉树的深度
#include<iostream>
using namespace std;

//二叉树的二叉链表存储表示
typedef struct BiNode
{				
	char data;						//结点数据域
	struct BiNode *lchild,*rchild;	//左右孩子指针
}BiTNode,*BiTree;

//用算法5.3建立二叉链表
void CreateBiTree(BiTree &T)
{	
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			//递归结束,建空树
	else{							
		T=new BiTNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								//else
}									//CreateBiTree

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);
    }
}

int main()
{
	BiTree tree;
	CreateBiTree(tree);
	cout << Depth(tree) << endl;
}

第5关:5.6统计二叉树中节点的个数

任务描述

本关任务:编写一个计算二叉树中节点个数的算法,如5.5所示。

相关知识

为了完成本关任务,你需要掌握:1.如何中序遍历二叉树 2.如何先序遍历建立二叉树 3.如何统计二叉树中的节点。

编程要求

根据提示,在右侧编辑器补充代码,并输出二叉树的节点个数。

测试说明

平台会对你编写的代码进行测试:

测试输入:ABC##DE#G##F###

预期输出:7


开始你的任务吧,祝你成功!

参考代码

//算法5.6 统计二叉树中结点的个数
#include<iostream>
using namespace std;

//二叉树的二叉链表存储表示
typedef struct BiNode
{				
	char data;						//结点数据域
	struct BiNode *lchild,*rchild;	//左右孩子指针
}BiTNode,*BiTree;

//用算法5.3建立二叉链表
void CreateBiTree(BiTree &T)
{	
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			//递归结束,建空树
	else{							
		T=new BiTNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								//else
}									//CreateBiTree

int NodeCount(BiTree T)
{
    if(T == NULL) return 0;
    else return NodeCount(T -> lchild) + NodeCount(T -> rchild) + 1;
} 

int main()
{
	BiTree tree;
	CreateBiTree(tree);
	cout << NodeCount(tree) << endl;
}

算法5.7-5.9线索二叉树 

第1关:5.7-5.9线索化遍历

任务描述

本关任务:编写一个遍历线索二叉树的程序,包含算法5.7、算法5.8和算法5.9。

相关知识

为了完成本关任务,你需要掌握:1.如何以节点p为根的子树线索化 2.带头结点的二叉树中序线索化 3.遍历线索二叉树。

编程要求

根据提示,在右侧编辑器补充代码,并输出线索二叉树中的节点。

测试说明

平台会对你编写的代码进行测试:

测试输入:ABC##DE#G##F###

预期输出:CBEGDFA


开始你的任务吧,祝你成功!

参考代码

//算法5.9 遍历中序线索二叉树
#include<iostream>
using namespace std;

//二叉树的二叉线索类型存储表示
typedef struct BiThrNode
{				
	char data;							//结点数据域
	struct BiThrNode *lchild,*rchild;	//左右孩子指针
	int LTag,RTag;
}BiThrNode,*BiThrTree;

//全局变量pre
BiThrNode *pre=new BiThrNode;

//用算法5.3建立二叉链表
void CreateBiTree(BiThrTree &T)
{	
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			//递归结束,建空树
	else
	{							
		T=new BiThrNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								//else
}									//CreateBiTree

//用算法5.7以结点P为根的子树中序线索化
void InThreading(BiThrTree p)
{
	//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
	if(p)
	{
		InThreading(p -> lchild);             			//左子树递归线索化
		if(!p -> lchild)				//p的左孩子为空
		{    				
			p -> LTag = 1;   			//给p加上左线索
			p -> lchild = pre; 			//p的左孩子指针指向pre(前驱)
		}
		else p -> LTag = 0;
		if(!pre -> rchild)			    //pre的右孩子为空
		{							
			pre -> RTag = 1;    		//给pre加上右线索
			pre -> rchild = p;      	//pre的右孩子指针指向p(后继)
		}
		else pre -> RTag = 0;
		pre = p;        				//保持pre指向p的前驱
		InThreading(p -> rchild);		//右子树递归线索化
	}
}//InThreading

//用算法5.8带头结点的中序线索化
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)
{
	//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
	Thrt = new BiThrNode;           	//建头结点
	Thrt -> LTag = 0;  		   		 	//头结点有左孩子,若树非空,则其左孩子为树根
	Thrt -> RTag = 1;					//头结点的右孩子指针为右线索
	Thrt -> rchild = Thrt;            	//初始化时右指针指向自己
	if(!T)  Thrt -> lchild = Thrt;      //若树为空,则左指针也指向自己
	else
	{
		Thrt -> lchild = T;  pre = Thrt;//头结点的左孩子指向根,pre初值指向头结点
		InThreading(T);             	//调用算法,对以T为根的二叉树进行中序线索化
		pre -> rchild = Thrt;          	//算法,结束后,pre为最右结点,pre的右线索指向头结点
		pre -> RTag = 1;
		Thrt -> rchild = pre;        	//头结点的右线索指向pre
	}
} 										//InOrderThreading

void InOrderTraverse_Thr(BiThrTree T)
{ 
    //T指向头结点,头结点的左链lchild指向根结点,可参见线索化算法5.8。
	//中序遍历二叉线索树T的非递归算法,对每个数据元素直接输出
	BiThrTree p;
	p = T -> lchild;              		//p指向根结点
	while(p != T)
	{			  						//空树或遍历结束时,p==T
		while(p -> LTag == 0)	  		//沿左孩子向下
			p = p -> lchild;	 		//访问其左子树为空的结点
		cout << p -> data;
		while(p -> RTag == 1 && p -> rchild != T)
		{
			p = p -> rchild;			//沿右线索访问后继结点
			cout << p -> data;
		}
		p = p -> rchild;
	}
}										//InOrderTraverse_Thr

int main()
{
	pre->RTag=1;
	pre->rchild=NULL;
	BiThrTree tree,Thrt;
	
	CreateBiTree(tree);
	InOrderThreading(Thrt,tree);
	InOrderTraverse_Thr(Thrt);
    
	cout<<endl;
	return 0;
}

算法5.10-5.11构造哈夫曼树求哈夫曼编码

第1关:例子5.3使用哈夫曼编码

任务描述

本关任务:编写一个哈夫曼编码程序。

编程要求

根据提示,在右侧编辑器补充代码。

测试说明

平台会对你编写的代码进行测试:输入的第一行为叶子节点个数n,第二行分别是n个节点所对应的权值。输出为上述权值对应节点的哈夫曼编码。

测试输入: 8
5 29 7 8 14 23 3 11

 

预期输出:

0001

10

1110

1111

110

01

0000

001


开始你的任务吧,祝你成功!

参考代码

//算法5.11 根据赫夫曼树求赫夫曼编码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
	int weight;
	int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;

void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
    int i, min1 = 0x3f3f, min2 = 0x3f3f;//规定一个特别大的数 
    
    for(i = 1; i <= len; i ++)
    	if(HT[i].parent == 0 && min1 > HT[i].weight)
    		min1 = HT[i].weight, s1 = i;
    		
    for(i = 1; i <= len; i ++) //注意这个I!=*s1标记min 
    	if(i != s1 && HT[i].parent == 0)
    		if(HT[i].weight < min2)
        		min2 = HT[i].weight, s2 = i;
}

//用算法5.10构造赫夫曼树
void CreatHuffmanTree(HuffmanTree &HT,int n)
{
	//构造赫夫曼树HT
    if(n <= 1) return;
    int m = 2 * n - 1;
    HT = new HTNode[m + 1];
    for(int i = 1; i <= m; i ++)
        HT[i].parent = 0, HT[i].lchild = 0, HT[i].rchild = 0;
        
    for(int i = 1; i <= n; i ++) cin >> HT[i].weight;
    
    for(int i=n+1;i<=m;i++)
	{
        int s1, s2;
        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;
    }
}	// CreatHuffmanTree

void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
	//从叶子到根逆向求每个字符的赫夫曼编码,存储在编码表HC中
    char *cd;
    HC = new char*[n + 1];
    cd = new char[n];
    cd[n - 1] = '\0';
    for(int i = 1; i <= n; i ++)
	{
        int start = n - 1;
        int c = i, f = HT[i].parent;
        while(f != 0)
		{
            -- start;
            if(HT[f].lchild == c) cd[start] = '0';
            else cd[start] = '1';
            c = f, f = HT[f].parent;
        }
        HC[i] = new char[n - start];
        strcpy(HC[i], &cd[start]);
    }
    delete cd;
}													// CreatHuffanCode
void show(HuffmanTree HT,HuffmanCode HC)
{
	for(int i=1;i<=sizeof(HC);i++)
		cout << HC[i]<< endl;
}
int main()
{
	HuffmanTree HT;
	HuffmanCode HC;
	int n;

	cin>>n;											//输入赫夫曼树的叶子结点个数
	CreatHuffmanTree(HT,n);
	CreatHuffmanCode(HT,HC,n);
	show(HT,HC);

    return 0;
}

算法5.12-5.13表达式求值

第1关:表达式树的求值

任务描述

本关任务:编写一个表达式树求值的程序。

编程要求

根据提示,在右侧编辑器补充代码。

测试说明

平台会对你编写的代码进行测试:输入为一个表达式以#号结束,中间的计算过程需要是个位数。

测试输入: 3+(2+3)/5-2*2

预期输出: 0


开始你的任务吧,祝你成功!

参考代码

//利用二叉树求解表达式的值 
#include<iostream>
#include<string>
#define ERROR -1
#define MAXSIZE 100
using namespace std;

typedef struct BiTNode{                             //二叉树的二叉链表存储表示
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

typedef struct{                  // 字符栈定义
	char *base;
	char *top;
	int stacksize;
}SqStack;

typedef struct{                   //树栈定义
	BiTree *base;
	BiTree *top;
	int stacksize;
}BiTreeStack;


void  InitStack(SqStack &S){             //字符栈初始化
	S.base=new char[MAXSIZE];
	if(!S.base) exit(-1);
	S.top=S.base;
	S.stacksize=MAXSIZE;
}


void  InitBiTreeStack(BiTreeStack &S){             //树栈初始化
	S.base=new BiTree[MAXSIZE];
	if(!S.base) exit(-1);
	S.top=S.base;
	S.stacksize=MAXSIZE;
}


void Push(SqStack &S,char e)             //字符栈入栈
{
	if(S.top-S.base==S.stacksize) return ;
	*S.top=e;
	S.top++;

}
void PushBiTree(BiTreeStack &S,BiTree e)             //树栈入栈
{
	if(S.top-S.base==S.stacksize) return ;
	*S.top=e;
	S.top++;

}
void Pop(SqStack &S,char &e)           //字符栈出栈
{
	if(S.top==S.base) return;
	e=*--S.top;
	 
}

void PopBiTree(BiTreeStack &S,BiTree &e)           //树栈出栈
{
	if(S.top==S.base) return;
	e=*--S.top;
	 
}


char GetTop(SqStack &S)                //字符栈得到栈顶函数
{		
	if(S.top==S.base)	exit(1);
	return *(S.top-1);
}

char Precede(char t1,char t2) 
 { /* 根据教科书表3.1,判断两符号的优先关系 */
   char f;
    switch(t2)
   {
     case '+':if(t1=='('||t1=='#')
                f='<';
              else
                f='>';
              break;
     case '-':if(t1=='('||t1=='#')
                f='<';
              else
                f='>';
              break;
     case '*':if(t1=='*'||t1=='/'||t1==')')
                f='>';
              else
                f='<';
              break;
	case '/':if(t1=='*'||t1=='/'||t1==')')
                f='>';
              else
                f='<';
              break;
	case '(':if(t1!=')')
                f='<';
              break;
	case')':if(t1=='(')
				f='=';
				else
					f='>';
				break;
	case'#':if(t1=='#')
				f='=';
		else
			f='>';
   }

   return f;
 }
int In(char c) 
 { /* 判断c是否为运算符 */
   switch(c)
   {
   	case '+':
   	case'-':
   	case'*':
	case '/':
   	case'#':
   	case '(':
   	case')':return 1;break;
   	default:return 0;
   }
 }
int GetValue(char theta,int a,int b)     //进行运算的函数
 {
	int c;
	switch(theta)
	{
	case '+':c=a+b;break;
	case'-':c=a-b;break;
	case'*':c=a*b;break;
	case'/':c=a/b;break;
	default:
		break;
	}
	return c;
 }

void CreateExpTree(BiTree &T,BiTree a,BiTree b,char ch){           //简单二叉树的创建
	T=new BiTNode;
	T->data=ch;
	T->lchild=a;
	T->rchild=b;
}


 void InitExpTree(BiTree &T)      //算法5.12 表达式树的创建
 {	
	SqStack OPTR;
	BiTreeStack EXPT;
	char ch, theta, x;
	BiTree a, b;
	InitStack(OPTR); Push(OPTR,'#');
	InitBiTreeStack(EXPT); 
	cin >> ch;
	while(ch != '#' || GetTop(OPTR) != '#')
	{
		if(!In(ch))
		{
			CreateExpTree(T, NULL, NULL, ch);
			PushBiTree(EXPT, T);
			cin >> ch;
		}//*q
		else
		{
   			switch(Precede(GetTop(OPTR), ch))
			{
				case'<':
    				Push(OPTR, ch);
					cin >> ch;
					break;
				case'>':
					Pop(OPTR, theta);
					PopBiTree(EXPT, b); PopBiTree(EXPT, a);
					CreateExpTree(T,a,b,theta);
    				PushBiTree(EXPT, T);
					break;
				case'=':
					Pop(OPTR,x);cin>>ch;
					break;
			}
		}
	}
}

 int EvaluateExTree(BiTree T){ //算法5.13 表达式树的求值

    int lvalue=0,rvalue=0;
    if(T->lchild==NULL&&T->rchild==NULL) return T->data-'0';
    else
	{
        lvalue=EvaluateExTree(T->lchild);
        rvalue=EvaluateExTree(T->rchild);
        return GetValue(T->data,lvalue,rvalue);
    }
 }

 int main() 
 {
   BiTree T;
   InitExpTree(T);          //创建表达式树
   cout<<EvaluateExTree(T)<<endl;             //输出值
   return 0;
 }
	

 

 

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
//算法5.11 根据赫夫曼树赫夫曼编码 #include using namespace std; typedef struct { int weight; int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char **HuffmanCode; void Select(HuffmanTree HT,int len,int &s1,int &s2) { int i,min1=0x3f3f3f3f,min2=0x3f3f3f3f;//先赋予最大值 for(i=1;i<=len;i++) { if(HT[i].weight<min1&&HT[i].parent==0) { min1=HT[i].weight; s1=i; } } int temp=HT[s1].weight;//将原值存放起来,然后先赋予最大值,防止s1被重复选择 HT[s1].weight=0x3f3f3f3f; for(i=1;i<=len;i++) { if(HT[i].weight<min2&&HT[i].parent==0) { min2=HT[i].weight; s2=i; } } HT[s1].weight=temp;//恢复原来的值 } //用算法5.10构造赫夫曼树 void CreatHuffmanTree(HuffmanTree &HT,int n) { //构造赫夫曼树HT int m,s1,s2,i; if(n<=1) return; m=2*n-1; HT=new HTNode[m+1]; //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点 for(i=1;i<=m;++i) //将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0 { HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } cout<<"请输入叶子结点的权值:\n"; for(i=1;i>HT[i].weight; /*――――――――――初始化工作结束,下面开始创建赫夫曼树――――――――――*/ for(i=n+1;i<=m;++i) { //通过n-1次的选择、删除、合并来创建赫夫曼树 Select(HT,i-1,s1,s2); //在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点, // 并返回它们在HT中的序号s1和s2 HT[s1].parent=i; HT[s2].parent=i; //得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i HT[i].lchild=s1; HT[i].rchild=s2 ; //s1,s2分别作为i的左右孩子 HT[i].weight=HT[s1].weight+HT[s2].weight; //i 的权值为左右孩子权值之和 } //for } // CreatHuffmanTree void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n) { //从叶子到根逆向每个字符的赫夫曼编码,存储在编码表HC中 int i,start,c,f; HC=new char*[n+1]; //分配n个字符编码的头指针矢量 char *cd=new char[n]; //分配临时存放编码的动态数组空间 cd[n-1]='\0'; //编码结束符 for(i=1;i<=n;++i) { //逐个字符赫夫曼编码 start=n-1; //start开始时指向最后,即编码结束符位置 c=i; f=HT[i].parent; //f指向结点c的双亲结点 while(f!=0) { //从叶子结点开始向上回溯,直到根结点 --start; //回

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羁旅少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值