数据结构和算法——二叉搜索树/哈夫曼二叉树的算法实现

本文详细介绍了二叉搜索树和哈夫曼二叉树的算法实现过程,包括如何构建、插入、查找和删除操作。通过对这两种数据结构的深入理解,有助于提升算法设计和优化能力。
摘要由CSDN通过智能技术生成

二叉搜索树的算法实现

#include<iostream>
#include <assert.h> //断言

using namespace std;

#define MaxSize 128 //预先分配栈空间
#define isLess(a,b) (a<b)
#define isEqual(a,b) (a==b)

typedef int DataType;

typedef struct TreeNode {
	DataType element;	//元素类型
	TreeNode* lchild;	//左子节点
	TreeNode* rchild;	//右子节点
}SeekTree;

//二叉搜索树的插入
bool SeekTreeInsert(SeekTree** root, TreeNode* node) {
	TreeNode* tmp = NULL;    //保存根节点
	TreeNode* parent = NULL; //保存根节点

	if (!node) return false; //判断是否存在新节点
	else {
		node->lchild = NULL;
		node->rchild = NULL;
	}
	if (*root) tmp = *root;	//判断是否存在根节点
	else {					//存在根节点不执行
		*root = node;
		return true;
	}

	while (tmp != NULL) {
		parent = tmp;	//找到要插入的位置的父节点
		if (isLess(node->element, tmp->element)) { 
			tmp = tmp->lchild;	
		}else {
			tmp = tmp->rchild;
		}
	}

	if (isLess(node->element, parent->element)) {//判断要插入的位置是左子节点还是右子节点
		parent->lchild = node;
	}else {
		parent->rchild = node;
	}
	return true;
}

//查找左子树上的最大元素替换要删除的节点
int findMax(SeekTree* tree){
	assert(tree != NULL); //触发断言
	if (tree->rchild == NULL)return tree->element;
	return findMax(tree->rchild);
}

//删除元素
SeekTree* SeekTreeDelete(SeekTree* tree, int data,TreeNode *& node) {
	if (tree == NULL) return NULL;
	if (isLess(data,tree->element)) { //判断要删除的元素是否小于根节点的元素
		tree->lchild = SeekTreeDelete(tree->lchild, data, node);
		return tree;
	}
	if (isLess(tree->element, data)) { //判断要删除的元素是否大于根节点的元素
		tree->rchild = SeekTreeDelete(tree->rchild, data, node);
		return tree;
	}
	node = tree;
	if (tree->lchild == NULL && tree->rchild == NULL)return NULL;
	if (tree->lchild == NULL && tree->rchild != NULL)return tree->rchild;
	if (tree->lchild != NULL && tree->rchild == NULL)return tree->lchild;
	int val = findMax(tree->lchild);
	tree->element = val;
	tree->lchild = SeekTreeDelete(tree->lchild, val, node);
	return tree;
}

//搜索节点
SeekTree* SeekTreeQuery(SeekTree* tree, int element) {
	while(tree!=NULL&& !isEqual(tree->element,element)){ //判断要查找的数值是否与当前值相等
		if (isLess(element, tree->element)) {
			tree = tree->lchild;
		}else {
			tree = tree->rchild;
		}
	}
	return tree;
}

//前序遍历
void SeekTreePreorder(SeekTree* tree) {
	if (tree == NULL) return;
	cout << tree->element << "\t";
	SeekTreePreorder(tree->lchild);
	SeekTreePreorder(tree->rchild);
}
int main(void) {
	
	//1.初始化插入
	int test[] = { 19,7,25,5,11,15,21,61 };
	SeekTree* tree = NULL;
	TreeNode* node = new TreeNode;
	node->element = test[0];
	SeekTreeInsert(&tree, node);

	for (int i = 1; i < sizeof(test) / sizeof(int); i++) {
		node = new TreeNode;
		node->element = test[i];
		SeekTreeInsert(&tree, node);
	}

	//2.前序遍历
	SeekTreePreorder(tree);

	//3.删除节点
	TreeNode* deletenode = NULL;
	SeekTreeDelete(tree, 19, deletenode);
	delete deletenode;

	//4.查找节点
	if (SeekTreeQuery(tree, 19) == NULL)
		cout << "不存在";
	else
		cout << "存在";
	

	return 0;
}

哈夫曼二叉树算法实现

#include<iostream>

using namespace std;

#define MaxSize 1024 //队列最大容量

typedef struct TreeNode {
	char value;		//哈夫曼值
	int weight;		//权重
	TreeNode* parent;	//父节点
	TreeNode* lchild;	//左子节点
	TreeNode* rchild;	//右子节点
}HuffTree;

typedef struct QueueNode {
	int priority;		//优先级
	HuffTree* data;		//哈夫曼数据域
	QueueNode* next;	//尾指针
}QueueNode;

typedef struct Queue {
	int length;		//队列长度
	QueueNode* front;	//队头指针
	QueueNode* rear;	//队尾指针
}PriorityQueue;

//初始化优先队列
bool initPriorityQueue(PriorityQueue* queue){
	if (!queue)return false;
	queue->length = 0;
	queue->front = queue->rear = NULL;
	return true;
}

//判断队列为空
bool PriorityQueueIsEmpty(PriorityQueue* queue) {
	if (!queue)return false;
	if (queue->front == NULL)return true;
	return false;
}

//判断队列是否为满
bool PriorityQueueIsFull(PriorityQueue* queue) {
	if (!queue)return false;
	if (queue->length == MaxSize)return true;
	return false;
}

//哈夫曼数据插入到优先队列中
bool PriorityQueuePush_back(PriorityQueue* queue, HuffTree* data, int priority) {
	if (!queue)return false;
	if (PriorityQueueIsFull(queue))return false;
	QueueNode* node = new QueueNode;
	node->data = data;
	node->priority = priority;
	node->next = NULL;
	if (PriorityQueueIsEmpty(queue)) {
		queue->front = queue->rear = node;
	}else {
		node->next = queue->front;
		queue->front = node;
	}
	queue->length++;
	return true;
}

//优先级高的元素出列
bool PriorityQueuePop_front(PriorityQueue* queue, HuffTree*& data){
	QueueNode** prev = NULL;    //保存优先级最高的节点
	QueueNode* prevNode = NULL; //保存当前最高优先级的上一个节点位置
	QueueNode* lastNode = NULL;
	QueueNode* tmp = NULL;      //保存优先级最高的节点

	if (!queue || PriorityQueueIsEmpty(queue) )return false;
	prev = &(queue->front); //获取队头指针所在的位置
	lastNode = queue->front;
	tmp = lastNode->next;	//头指针指向的下一个元素
	while (tmp) {
		if (tmp->priority < (*prev)->priority) {//判断优先级
			prev = &(lastNode->next); //将优先级最高的节点赋值给prev
			prevNode = lastNode;
		}
		lastNode = tmp;
		tmp = tmp->next;
	}
	data = (*prev)->data;
	tmp = *prev;
	*prev = (*prev)->next;
	delete tmp;

	queue->length--;
	if (queue->length == 0)
		queue->rear = NULL;

	if (prevNode && prevNode->next == NULL)
		queue->rear = prevNode;
	return true;
}

//获取队首元素
bool PriorityQueueGet_Head(PriorityQueue* queue, HuffTree** data) {
	if (!queue || PriorityQueueIsEmpty(queue));
	data = &(queue->front->data);
	return true;
}

//清空队列
void PriorityQueueClear(PriorityQueue* queue) {
	if (!queue)return;
	while (queue->front) {
		QueueNode* tmp = queue->front->next;
		delete queue->front;
		queue->front = tmp;
	}
	queue->front = queue->rear = NULL;
	queue->length = 0;
}

//获取队列中元素的个数
int PriorityQueueLength(PriorityQueue* queue) {
	if (!queue)return 0;
	return queue->length;
}

//优先队列的遍历
void PriorityQueuePrint(PriorityQueue* queue) {
	if (!queue)return;
	if (queue->front == NULL)return;
	QueueNode* tmp = queue->front;	//将临时指针指向头指针所在的节点
	while (tmp) {
		cout << tmp->data->value << "  [优先级:" << tmp->priority << "]" << "\t";
		tmp = tmp->next;
	}
	cout << endl;
}

//初始化哈夫曼树
bool initHuffmanTree(HuffTree*& tree, int n) {
	PriorityQueue* queue = new PriorityQueue; //创建优先级队列
	initPriorityQueue(queue);	//初始化优先级队列
	for (int i = 0; i < n; i++) {
		TreeNode* node = new TreeNode; //创建哈夫曼树节点
		cout << "请输出第" << i + 1 << "个字符和出现的频率:" << endl;
		cin >> node->value;
		cin >> node->weight;
		node->lchild = NULL;
		node->rchild = NULL;
		node->parent = NULL;
		PriorityQueuePush_back(queue, node, node->weight);
	}
	PriorityQueuePrint(queue);
	
	do {
		TreeNode* node1 = NULL;
		TreeNode* node2 = NULL;
		if (!PriorityQueueIsEmpty(queue)) {
			PriorityQueuePop_front(queue, node1);
			cout << "第一个出列的元素:" << node1->value << "\t优先级:" << node1->weight << endl;
		}else {
			break;
		}
		if (!PriorityQueueIsEmpty(queue)) {
			TreeNode* node3 = new TreeNode;
			PriorityQueuePop_front(queue, node2);
			cout << "第二个出列的元素:" << node2->value << "\t优先级:" << node2->weight << endl;
			node3->lchild = node1;
			node1->parent = node3;
			node3->rchild = node2;
			node2->parent = node3;
			node3->value = ' ';
			node3->weight = node1->weight + node2->weight;
			cout << "合并进队列的数:" << node3->value << "优先级:" << node3->weight << endl;
			PriorityQueuePush_back(queue, node3, node3->weight);
		}
		else {
			tree = node1;
			break;
		}
	} while (1);
	return true;
}

//前序遍历
void HuffmanTreePreOrder(HuffTree* tree) { 
	if (tree == NULL) return;
	cout << tree->value << "\t";
	HuffmanTreePreOrder(tree->lchild);
	HuffmanTreePreOrder(tree->rchild);
}

int main(void) {
	HuffTree* tree = NULL;
	initHuffmanTree(tree, 7);
	HuffmanTreePreOrder(tree);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值