基础数据结构(一)二叉树的实现+(先序、中序、后序、层次)遍历算法+普通树的实现+哈夫曼树的实现

 1、二叉树的顺序存储

#include <iostream>
//二叉树的顺序存储
typedef int ElemType;
#define MAXSIZE 100
typedef ElemType BiTree[MAXSIZE];//声明1种数据类型 长度为100的数组

int main()
{
	BiTree bt;//实例化出1个二叉数组
	/* 
		用空集修补当前二叉树成完全二叉树
		(满二叉树(结点数 = 2^(k) - 1)从最后1个结点开始连续删除任意个结点)
		所有的结点按满二叉树编号规则(不同层:从上到下(同层:从左到右))进行编号
	*/
	//把二叉树的N个结点存放进数组bt[0]---bt[N-1 + 修补的数量]

	return 0;
}

2、二叉树的链式存储 

#include <iostream>
//二叉树的链式存储
typedef int TElemType;
typedef struct BiNode
{
	TElemType data;//要存储的数据
	BiNode * lchild;//当前结点的左孩子结点
	BiNode * rchild;//当前结点的右孩子结点
} *BiTree;


int main()
{
	/*
		BiNode * n1 = new BiNode;
		......
		BiNode * n9 = new BiNode;
		n1->data = ...;
		n1->lchild = ...;
		n1->rchild = ...;
		......
		n9->data = ...;
		n9->lchild = nullptr;
		n9->rchild = nullptr;
	*/
	BiTree bt;//实例化出1个头指针(二叉链表)--指向首元结点
	//bt->lchild = bt->rchild = n1;
	

	return 0;
}

3、先序、中序、后序递归遍历二叉树 

#include <iostream>
//二叉树的链式存储(二叉链表)
typedef char TElemType;
typedef struct BiNode
{
	TElemType data;//要存储的数据
	BiNode * lchild;//i结点的左孩子
	BiNode * rchild;//i结点的右孩子
} *BiTree;
//先序遍历--得到二叉树的所有结点的唯一序列
/*
	判断二叉树空?不空?
				 1、访问根节点
				 2、先序遍历左子树   PreOrderTraverse(T->lchild);
				 3、先序遍历右子树   PreOrderTraverse(T->rchild);
			  返回上一层 == 直接return
*/
int PreOrderTraverse(BiTree T);
//中序遍历--得到二叉树的所有结点的唯一序列
/*
	判断二叉树空?不空?
				 1、中序遍历左子树   InOrderTraverse(T->lchild);
				 2、访问根节点
				 3、中序遍历右子树   InOrderTraverse(T->rchild);
			  返回上一层 == 直接return
*/
int InOrderTraverse(BiTree T);
//后序遍历--得到二叉树的所有结点的唯一序列
/*
	判断二叉树空?不空?
				 1、后序遍历左子树   PostOrderTraverse(T->lchild);
				 2、后序遍历右子树   PostOrderTraverse(T->rchild);
				 3、访问根节点
			  返回上一层 == 直接return
*/
int PostOrderTraverse(BiTree T);

int main()
{
	/*
		二叉树
		A
	   / \
	  B   C
	   \
	    D
	*/
	BiNode * n1 = new BiNode;
	BiNode * n2 = new BiNode;
	BiNode * n3 = new BiNode;
	BiNode * n4 = new BiNode;
	n1->data = 'A';
	n1->lchild = n2;
	n1->rchild = n3;
	n2->data = 'B';
	n2->lchild = nullptr;
	n2->rchild = n4;
	n3->data = 'C';
	n3->lchild = n3->rchild = nullptr;
	n4->data = 'D';
	n4->lchild = n4->rchild = nullptr;
	//实例化出1棵二叉树(1个头指针)
	BiTree bt = new BiNode;//栈指针不能指向堆区内存
	bt->data = ';';
	bt->lchild = n1;//指向首元结点
	bt->rchild = nullptr;
	//测试先序遍历
	std::cout << "----test----\n";
	PreOrderTraverse(bt);
	std::cout << "\n----test end----\n";

	return 0;
}
//先序遍历
int PreOrderTraverse(BiTree T)
{
	if (!T)
		return 0;//二叉树为空--返回上一层--直接return(结束当前PreOrderTraverse(?))//递归函数的出口条件
	else
	{
		if (T->data != ';')
			std::cout << T->data << '\t';//访问根结点(输出数据值)
		PreOrderTraverse(T->lchild);//先序遍历当前结点的左子树
		PreOrderTraverse(T->rchild);//先序遍历当前结点的右子树
	}
}
//中序遍历
int InOrderTraverse(BiTree T)
{
	if (!T)
		return 0;//二叉树为空--返回上一层--直接return(结束当前PreOrderTraverse(?))//递归函数的出口条件
	else
	{
		InOrderTraverse(T->lchild);//中序遍历当前结点的左子树
		if (T->data != ';')
			std::cout << T->data << '\t';//访问根结点(输出数据值)
		InOrderTraverse(T->rchild);//中序遍历当前结点的右子树
	}
}
//后序遍历
int PostOrderTraverse(BiTree T)
{
	if (!T)
		return 0;//二叉树为空--返回上一层--直接return(结束当前PreOrderTraverse(?))//递归函数的出口条件
	else
	{
		PostOrderTraverse(T->lchild);//后序遍历当前结点的左子树
		PostOrderTraverse(T->rchild);//后序遍历当前结点的右子树
		if (T->data != ';')
			std::cout << T->data << '\t';//访问根结点(输出数据值)
	}
}

4、中序遍历非递归实现

#include <iostream>
//二叉树链式存储
typedef char TElemType;
typedef struct BiNode
{
	TElemType tdata;//要存储的数据
	BiNode * lchild;//当前结点的左孩子
	BiNode * rchild;//当前结点的右孩子
} *BiTree;
//栈--存储的数据元素为指向二叉树结点的指针
#define MAXSIZE 100
typedef struct
{
	//BiTree sdata[MAXSIZE];
	BiTree * base;//栈底指针//可以同时用来开辟动态数组//不会移动的
	BiTree * top;//栈顶指针//指向当前最末元素的下一个位置
} SStack;
//栈为空
int SStackEmpty(SStack S);
//栈为满
int SStackFull(SStack S);
//入栈
int PushSStack(SStack & S, BiTree t);
//出栈
int PopSStack(SStack & S, BiTree & t);
//初始化栈
int InitSStack(SStack & S);
//中序非递归遍历(while循环 + 自定义栈)
int InOrderTraverse(BiTree T);

int main()
{
	/*
		实例化出1棵二叉树(链式存储)
			A
		   / \
		  B   C
		   \
		    D
	*/
	//堆区开辟4个结点
	BiNode * n1 = new BiNode;
	BiNode * n2 = new BiNode;
	BiNode * n3 = new BiNode;
	BiNode * n4 = new BiNode;
	n1->tdata = 'A';
	n1->lchild = n2;
	n1->rchild = n3;
	n2->tdata = 'B';
	n2->lchild = nullptr;
	n2->rchild = n4;
	n3->tdata = 'C';
	n3->lchild = n3->rchild = nullptr;
	n4->tdata = 'D';
	n4->lchild = n4->rchild = nullptr;
	//实例化出1个二叉树(头指针)
	BiTree T = new BiNode;
	T->tdata = ';';
	T->lchild = n1;//串起来
	T->rchild = nullptr;
	std::cout << "二叉树:\n    A\n   \/ \\ \n   B C\n    \\\n     D" << std::endl;
	//测试中序遍历(非递归)算法
	std::cout << "****begin test****\n结点序列为:\n";
	InOrderTraverse(T);
	std::cout << "\n****end test****\n";

	return 0;
}
//栈为空
int SStackEmpty(SStack S)
{
	if (S.top == S.base)
		return 1;
	else
		return 0;
}
//栈为满
int SStackFull(SStack S)
{
	if ((S.top - S.base) == MAXSIZE * sizeof(BiTree))
		return 1;
	else
		return 0;
}
//入栈
int PushSStack(SStack & S, BiTree t)
{
	if (!SStackFull(S))
	{
		*S.top = t;
		S.top++;
		return 1;
	}
	else
		return 0;
}
//出栈
int PopSStack(SStack & S, BiTree & t)
{
	if (!SStackEmpty(S))
	{
		t = *(S.top - 1);
		S.top--;
		return 1;
	}
	else
		return 0;
}
//初始化栈
int InitSStack(SStack & S)
{
	S.base = new BiTree[MAXSIZE];
	S.top = S.base;
	return 1;
}
/*
		A
	   / \
	  B   C
	 /\    \

	中序遍历非递归算法
	1、创建栈
	2、二叉树不空?---根结点入栈, 中序遍历左子树(利用循环2、3、)
	3、遍历完左子树---根结点出栈,中序遍历右子树(利用循环2、3、),出循环结束
*/
int InOrderTraverse(BiTree T)
{
	SStack S;
	InitSStack(S);//实例化1个栈并初始化为空栈
	BiTree p = T;//用来遍历结点
	BiTree q = nullptr;//用来记录栈存放的根结点(出栈)
	while (p || !SStackEmpty(S))//只有p为空(二叉树为空-结点遍历完成) && 栈也为空--结束循环
	{
		/*
			p不为空---遍历二叉树结点
			p为空---当前二叉树遍历结束
			Q: 中序(左-根-右) 遍历完左子树-p为空, 怎么访问根结点和遍历右子树?
			A:栈保存了当前的根结点,出栈即可
		*/
		if (p)	//p不为空,遍历当前二叉树
		{
			//1、记录根结点(根节点入栈)
			PushSStack(S, p);
			//2、遍历当前根结点的左子树
			p = p->lchild;
		}
		else   //p为空, 左子树完成遍历
		{
			//回到根节点---开始遍历右子树
			PopSStack(S, q);//q为当前左子树的根结点
			if (q->tdata != ';')
				std::cout << q->tdata << '\t';
			//开始遍历右子树
			p = q->rchild;
		}
	}
	return 1;
}

5、层次遍历 

#include <iostream>
typedef char TElemType;
//二叉树-链式存储
typedef struct BiNode
{
	TElemType tdata;
	BiNode * lchild;
	BiNode * rchild;
} *BiTree;
//单向队列--浪费内存
#define MAXSIZE 100
typedef struct
{
	BiTree data[MAXSIZE];//静态数组
	int head;//头指针(队头元素)
	int rear;//尾指针(队尾元素的下一个位置)
} Queue;
//初始化为空队列
void InitQueue(Queue &Q);
//队空?
int EmptyQueue(Queue Q);
//队满
int FullQueue(Queue Q);
//入队
int EnQueue(Queue & Q, BiTree bt);
//出队
int DelQueue(Queue & Q, BiTree & bt);
//层次遍历算法
int LevelTraverse(BiTree T);

int main()
{
	/*
		实例化出1棵二叉树(链式存储)
			A
		   / \
		  B   C
		   \
			D
	*/
	//堆区开辟4个结点
	BiNode * n1 = new BiNode;
	BiNode * n2 = new BiNode;
	BiNode * n3 = new BiNode;
	BiNode * n4 = new BiNode;
	n1->tdata = 'A';
	n1->lchild = n2;
	n1->rchild = n3;
	n2->tdata = 'B';
	n2->lchild = nullptr;
	n2->rchild = n4;
	n3->tdata = 'C';
	n3->lchild = n3->rchild = nullptr;
	n4->tdata = 'D';
	n4->lchild = n4->rchild = nullptr;
	//实例化出1个二叉树(头指针)
	BiTree T = new BiNode;
	T->tdata = ';';
	T->lchild = n1;//串起来
	T->rchild = nullptr;
	std::cout << "二叉树:\n    A\n   \/ \\ \n   B C\n    \\\n     D" << std::endl;
	//测试层次遍历算法
	std::cout << "****begin test****\n结点序列为:\n";
	LevelTraverse(T);
	std::cout << "\n****end test****\n";


	return 0;
}
//初始化为空队列
void InitQueue(Queue &Q)
{
	Q.head = Q.rear = 0;
}
//队空?
int EmptyQueue(Queue Q)
{
	if (Q.head == Q.rear)
		return 1;
	else
		return 0;
}
//队满
int FullQueue(Queue Q)
{
	if (Q.rear == MAXSIZE)
		return 1;
	else
		return 0;
}
//入队
int EnQueue(Queue & Q, BiTree bt)
{
	if (!FullQueue(Q))
	{
		Q.data[Q.rear++] = bt;
		return 1;
	}
	else
		return 0;
}
//出队
int DelQueue(Queue & Q, BiTree & bt)
{
	if (!EmptyQueue(Q))
	{
		bt = Q.data[Q.head++];
		return 1;
	}
	else
		return 0;
}
//层次遍历算法
int LevelTraverse(BiTree T)
{
	/*
			A
		   / \
		  B   C
		   \
			D
		1、初始化1个队列
		2、根节点入队
		3、循环 (队列非空?) 队头元素出队 + 队头元素的左右孩子结点入队
	*/
	BiTree p = nullptr;
	Queue Q;
	InitQueue(Q);
	EnQueue(Q, T);
	while (!EmptyQueue(Q))//队列为空(所有结点均遍历)--结束循环
	{
		//队头元素出队(访问根节点)
		DelQueue(Q, p);
		if (p->tdata != ';')
			std::cout << p->tdata << '\t';
		if (p->lchild)
			EnQueue(Q, p->lchild);
		if (p->rchild)
			EnQueue(Q, p->rchild);
	}
	return 1;
}

6、 先序+中序的序列生成二叉树

#include <iostream>
//二叉树链式存储
typedef char TElemType;
typedef struct BiNode
{
	TElemType data;
	BiNode * lchild;
	BiNode * rchild;
} *BiTree;
//由已知序列生成二叉树
int CreatBiTree(BiTree & T);
//先序遍历
int PreOrderTraverse(BiTree T);

int main()
{
	//测试生成二叉树
	std::cout << "修改的先序遍历序列:ABC##DE##G##F###\n";
	BiTree T = nullptr;//实例化1个空二叉树
	CreatBiTree(T);
	//遍历该生成的二叉树
	std::cout << "测试先序遍历序列:\n";
	PreOrderTraverse(T);

	return 0;
}
//由已知序列生成二叉树
/*
	人为规定:i结点均有2个孩子结点(空结点除外)
	#代替补充的空结点
*/
int CreatBiTree(BiTree & T)
{
	TElemType e;
	std::cout << "Enter a word:\t";
	std::cin >> e;
	if (e != '#')
	{
		//在堆区开辟1个根节点
		T = new BiNode;
		T->data = e;
		//生成该根结点的左子树
		CreatBiTree(T->lchild);
		//生成该根结点的右子树
		CreatBiTree(T->rchild);
	}
	else    //递归函数出口条件
	{
		/*
			输入的字符为#  等价  树为空
			  A
			 / \
			空  B
			   / \
			  C	 空
			 / \
			空 空
		*/
		T = nullptr;//树为空
		return 1;
	}
}
//先序遍历--得到二叉树的所有结点的唯一序列
/*
	判断二叉树空?不空?
				 1、访问根节点
				 2、先序遍历左子树   PreOrderTraverse(T->lchild);
				 3、先序遍历右子树   PreOrderTraverse(T->rchild);
			  返回上一层 == 直接return
*/
int PreOrderTraverse(BiTree T)
{
	if (!T)
		return 0;//二叉树为空--返回上一层--直接return(结束当前PreOrderTraverse(?))//递归函数的出口条件
	else
	{
		if (T->data != ';')
			std::cout << T->data << '\t';//访问根结点(输出数据值)
		PreOrderTraverse(T->lchild);//先序遍历当前结点的左子树
		PreOrderTraverse(T->rchild);//先序遍历当前结点的右子树
	}
}

7、二叉树遍历算法的应用-复制二叉树

#include <iostream>
//二叉树
typedef char TElemType;
typedef struct BiNode
{
	TElemType data;
	BiNode * lchild;
	BiNode * rchild;
} *BiTree;
//复制二叉树
int CopyBiTree(BiTree T, BiTree & Tnew);
//先序遍历--得到二叉树的所有结点的唯一序列
int PreOrderTraverse(BiTree T);

int main()
{
	/*
		二叉树
		A
	   / \
	  B   C
	   \
		D
	*/
	BiNode * n1 = new BiNode;
	BiNode * n2 = new BiNode;
	BiNode * n3 = new BiNode;
	BiNode * n4 = new BiNode;
	n1->data = 'A';
	n1->lchild = n2;
	n1->rchild = n3;
	n2->data = 'B';
	n2->lchild = nullptr;
	n2->rchild = n4;
	n3->data = 'C';
	n3->lchild = n3->rchild = nullptr;
	n4->data = 'D';
	n4->lchild = n4->rchild = nullptr;
	//实例化出1棵二叉树(1个头指针)
	BiTree bt = new BiNode;//栈指针不能指向堆区内存
	bt->data = ';';
	bt->lchild = n1;//指向首元结点
	bt->rchild = nullptr;
	//测试复制二叉树算法
	BiTree Tnew = nullptr;
	std::cout << "----test----\n";
	CopyBiTree(bt, Tnew);
	PreOrderTraverse(Tnew);
	std::cout << "\n----test end----\n";

	return 0;
}
//复制二叉树
int CopyBiTree(BiTree T, BiTree & Tnew)
{
	/*
		判断二叉树空---直接return
				  不空---1、在堆区新建根节点(值复制)
						 2、复制左子树
						 3、复制右子树	
	*/
	if (T)
	{
		Tnew = new BiNode;
		Tnew->data = T->data;//新建根结点
		CopyBiTree(T->lchild, Tnew->lchild);//复制左子树
		CopyBiTree(T->rchild, Tnew->rchild);//复制右子树
	}
	else
	{
		Tnew = T;//复制1棵空树
		return 1;
	}
}
//先序遍历
/*
	判断二叉树空?不空?
				 1、访问根节点
				 2、先序遍历左子树   PreOrderTraverse(T->lchild);
				 3、先序遍历右子树   PreOrderTraverse(T->rchild);
			  返回上一层 == 直接return
*/
int PreOrderTraverse(BiTree T)
{
	if (!T)
		return 0;//二叉树为空--返回上一层--直接return(结束当前PreOrderTraverse(?))//递归函数的出口条件
	else
	{
		if (T->data != ';')
			std::cout << T->data << '\t';//访问根结点(输出数据值)
		PreOrderTraverse(T->lchild);//先序遍历当前结点的左子树
		PreOrderTraverse(T->rchild);//先序遍历当前结点的右子树
	}
}

8、遍历算法的应用-计算二叉树的深度、结点数、叶子数 

#include <iostream>
//二叉树
typedef char TElemType;
typedef struct BiNode
{
	TElemType data;
	BiNode * lchild;
	BiNode * rchild;
} *BiTree;
//计算二叉树的深度
int DepthBiTree(BiTree T);
//计算二叉树结点总数
int NumBiTree(BiTree T);
//计算叶子节点数
int LeafBiTree(BiTree T);

int main()
{
	/*
		二叉树
		A
	   / \
	  B   C
	   \
		D
	*/
	BiNode * n1 = new BiNode;
	BiNode * n2 = new BiNode;
	BiNode * n3 = new BiNode;
	BiNode * n4 = new BiNode;
	n1->data = 'A';
	n1->lchild = n2;
	n1->rchild = n3;
	n2->data = 'B';
	n2->lchild = nullptr;
	n2->rchild = n4;
	n3->data = 'C';
	n3->lchild = n3->rchild = nullptr;
	n4->data = 'D';
	n4->lchild = n4->rchild = nullptr;
	//实例化出1棵二叉树(1个头指针)
	BiTree bt = new BiNode;//栈指针不能指向堆区内存
	bt->data = ';';
	bt->lchild = n1;//指向首元结点
	bt->rchild = nullptr;
	//测试计算二叉树的深度算法
	std::cout << "----test----\n";
	std::cout << DepthBiTree(bt->lchild);
	std::cout << "\n----test end----\n";
	//测试计算二叉树的结点数算法
	std::cout << "----test----\n";
	std::cout << NumBiTree(bt->lchild);
	std::cout << "\n----test end----\n";
	//测试计算二叉树的叶子结点数算法
	std::cout << "----test----\n";
	std::cout << LeafBiTree(bt->lchild);
	std::cout << "\n----test end----\n";

	return 0;
}
//计算二叉树的深度
int DepthBiTree(BiTree T)
{
	/*
		判断二叉树空?不空?
			return 0
					 计算左子树深度
					 计算右子树深度
					 取两者最大值 + 1并返回
	*/
	if (T)
	{
		int m = DepthBiTree(T->lchild); //计算左子树深度
		int n = DepthBiTree(T->rchild);//计算右子树深度
		return ((m < n) ? n + 1 : m + 1);//返给上一层递归调用
	}
	else
		return 0;
}
//计算二叉树结点总数
int NumBiTree(BiTree T)
{
	/*
		判断二叉树空?不空?
			return 0
					 计算左子树结点数
					 计算右子树结点数
					 取两者和 + 1并返回
	*/
	if (T)
	{
		int m = NumBiTree(T->lchild); //计算左子树结点数
		int n = NumBiTree(T->rchild); //计算右子树结点数
		return m + n + 1; //取两者和 + 1并返回
	}
	else
		return 0;
}
//计算叶子节点数
int LeafBiTree(BiTree T)
{
	/*
		判断二叉树空?不空?
			return 0
					 计算左子树叶子结点数
					 计算右子树叶子结点数
					 取两者和并返回
	*/
	if (!T)
		return 0;
	else
	{
		int m = LeafBiTree(T->lchild);
		int n = LeafBiTree(T->rchild);
		if (m + n > 0)
			return m + n;
		else
			return 1;//叶子节点(左为空,右为空)
	}
}

9、普通树的存储结构

#include <iostream>
typedef int TElemType;
/*
	树的存储结构
				顺序存储
				链式存储
			 R
		   / | \
		  A  B  C
		 / \    | 
		D   E   F
		      / | \
			 G  H  K
*/

/*
	树的顺序存储
				双亲表示法
				孩子链表表示法
	树的链式存储
				孩子兄弟表示法
*/

/*
	双亲表示法(顺序存储)
	i结点
		要保存的数据
		双亲结点的位置
*/
typedef struct DoubleParentNode
{
	TElemType data;
	int parent;
} DoubleParentNode;
#define MAXSIZE 100
typedef struct DoubleParentTree
{
	DoubleParentNode array[MAXSIZE];
	int len;//当前有多少个元素
}DoubleParentTree;

/*
	孩子链表法(顺序存储)
	i结点
		要保存的数据
		i结点所有孩子结点位置构成的链表
*/
//链表
typedef struct LinkNode
{
	int index;//i结点所在的几号位置
	LinkNode * next;//下一个链结点的位置
} *LinkList;
//i结点
typedef struct ChildLinkNode
{
	TElemType data;
	LinkList L;
} ChildLinkNode;
//树--孩子链表法
#define MAXSIZE1 100
typedef struct ChildLinkTree
{
	ChildLinkNode array[MAXSIZE1];
	int len;//当前几个元素
};

/*
	孩子兄弟表示法(链式存储)
	i结点
		要保存的数据
		第一个孩子结点的位置
		下一个兄弟结点的位置
*/
typedef struct ChildBrotherNode
{
	TElemType data;
	ChildBrotherNode * firstchild;
	ChildBrotherNode * nextbrother;
} ChildBrotherTree;

int main()
{

	return 0;
}

10、哈夫曼树 

#include <iostream>
/*
	已知n个叶子节点的权, 构造这n个结点的哈夫曼树
	1、n个结点构成n棵二叉树(只有根结点) T1 ... Tn 森林F = {T1, ..., Tn};
	2、从森林F中取出2棵权最小树作为左右子树, 构造新树.
	3、从森林F中删除这2棵树, 添加新树.
	重复2、3、(n - 1次产生n - 1棵新树)直到森林中剩下1棵树---所求的n个结点的哈夫曼树.
*/
//为了从森林中取出2棵权最小的树---森林采用顺序存储(方便取值) 数组(元素均为1棵二叉树)
//二叉树
typedef struct BiNode
{
	int weight;//规定: 树的权 = 所有叶子结点的权
	/*
		位置指针 双亲结点 左右孩子结点的位置
		BiNode * parent;
		BiNode * lchild;
		BiNode * rchild;
	*/
	int parent;
	int lchild;
	int rchild;
} *BiTree;
//对n个结点构造哈夫曼树
void CreatHuffmanTree(BiTree &T, int n);
//数组的n个数值中找最小的两个
void Select(BiTree T, int len, int & s1, int & s2);

int main()
{


	return 0;
}

//数组的len个数值中找最小的两个
void Select(BiTree T, int len, int & s1, int & s2)
{
	s1 = T[1].weight;
	for (int i = 1; i <= len; i++)
	{
		if (T[i].parent != 0 || T[i].weight <= 0)
			continue;
		if (T[i].weight <= s1);
			s1 = i;
	}
	for (int j = 1; j <= len; j++)
	{
		if (T[j].parent != 0 || T[j].weight <= 0 || j == s1)
			continue;
		if (T[j].weight <= s1);
			s2 = j;
	}
}

//对n个结点构造哈夫曼树
void CreatHuffmanTree(BiTree &T, int n)
{
	//1、构造n棵二叉树(只有根结点), n棵二叉树组成森林
	T = new BiNode[2 * n];//0号下标不用, n棵二叉树 + n - 1棵新树
	for (int i = 1; i <= n; i++)
	{
		std::cout << "Enter the " << i << " weight: ";
		std::cin >> T[i].weight;
		T[i].parent = T[i].lchild = T[i].rchild = 0;
	}
	//n - 1轮构造新树
	int s1, s2;
	for (int j = 1; j <= n - 1; j++)
	{
		//2、从森林中取2个权最小的树
		Select(T, n + j - 1, s1, s2);
		//作为左右子树构造新树
		T[n + j].weight = T[s1].weight + T[s2].weight;
		T[n + j].parent = 0;
		T[n + j].lchild = s1;
		T[n + j].rchild = s2;
		T[s1].parent = T[s2].parent = n + j;
	}
	*T = T[2 * n - 1];
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汪呈祥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值