第十二周数据结构作业2(哥们很菜,望大佬指点)

#include<iostream>
#include<stdio.h>
#include<stack>
#include<queue>
#include<malloc.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<opencv.hpp>
using namespace cv;
using namespace std;

//struct area
typedef struct node {
	int data;
	int short bal;
	struct node *left_child;
	struct node *right_child;
	struct node *parent;
}BST;
typedef struct {
	int x;
	int y;
}POS;

//universal variance area 
int Mapsequence[60] = { 0 };
int countMap = 1;
POS pos;
BST *ROOT=NULL;//平衡二叉树的根节点

//function announce
BST *SortTreeCreate();
BST *SortTreeSearch(BST *root, int key);
void Levelorder(BST *Tree);
void mapping(BST *T);
void Posfunction(int num);
void drawnode(int b, int g, int r);
void RotateRL(BST *parent, BST *T);
int Height(BST *T);
void Calbalance(BST *T);
void RotateRight(BST *parent, BST *T);
void RotateLR(BST *parent, BST *T);
void RotateLeft(BST *parent, BST *T);
void InsertBalance(BST *x, BST *T);
void RotateRL(BST *parent, BST *T);
void Insert(int data);

//function announce
Mat image(1000, 1000, CV_8UC3);


int main()
{
	namedWindow("tree");
	int key, i = 1; BST  *p = NULL;
	printf("Please enter the key you want to search:");
	scanf("%d", &key);
	SortTreeCreate();//创建平衡二叉树查找树
	mapping(ROOT);//给二叉树查找树中的每个节点编号
	drawnode(0, 255, 0);//用绿色画节点
	p = SortTreeSearch(ROOT, key);
	if (p)//判断需要查找的节点是否存在
	{
		printf("The key:%d is exisiting!\n", p->data);
		while (Mapsequence[i++] != 0)
		{
			if (Mapsequence[i - 1] == p->data)break;
		}
		Posfunction(i - 1);
		circle(image, Point(pos.x, pos.y), 25, Scalar(0, 0, 255), -1);
		imshow("tree", image);
		waitKey(0);
	}
	else
		printf("No this key in Binary Search Tree!\n");
}

//function area 
BST *SortTreeCreate()
{
	int data, n = 0, i = 0, runone = 1;
	FILE *fp;
	BST  *p;
	if (!(fp = fopen("C:\\Users\\chenh\\Desktop\\新建文件夹 (3)\\DATA.txt", "r")))
	{
		printf("Open the file error!\n");
		exit(1);
	}
	//This while is to read the data data file and creat Binary Search Tree
	while (!feof(fp))
	{
		fscanf(fp, "%d\n", &data);
		Insert(data);
	}
	return ROOT;
}
BST *SortTreeSearch(BST *root, int key)
{
	if (!root) return NULL;//if root is null
	if (key == root->data) return root;
	if (key < root->data)
		return SortTreeSearch(root->left_child, key);
	return SortTreeSearch(root->right_child, key);
}
void mapping(BST *T)
//This function is to mapping node map
//这个函数的作用是将树节点的序号映射到一个数组中(编号)
{
	Levelorder(T);
}
void Levelorder(BST *Tree) //层序遍历_队列实现
{
	//利用了一点点C++的东西 稍微看一下就知道了,给该二叉树对应的满二叉树编号以便于之后的画图
	queue < BST *> q;
	if (Tree != NULL)
	{
		q.push(Tree);//Add root to queue
		Mapsequence[countMap++] = Tree->data;//给二叉树中的每一个节点编号
	}
	while (q.empty() == false)  //队列不为空判断
	{
		//printf("%d → ", q.front()->data);
		if (q.front() != NULL)
		{
			if (q.front()->left_child != NULL)   //如果有左孩子,left_Child入队列
			{
				q.push(q.front()->left_child);
				Mapsequence[countMap++] = q.front()->left_child->data;
			}
			else
			{
				Mapsequence[countMap++] = -520;//-520表示没有该编号位置没有左节点
				q.push(NULL);
			}

			if (q.front()->right_child != NULL)   //如果有右孩子,right_Child入队列
			{
				q.push(q.front()->right_child);
				Mapsequence[countMap++] = q.front()->right_child->data;
			}
			else
			{
				Mapsequence[countMap++] = -520;
				q.push(NULL);
			}
		}
		else
		{
			Mapsequence[countMap++] = -520;
			Mapsequence[countMap++] = -520;
		}
		q.pop();  //已经遍历过的节点出队列
	}
}
void drawnode(int b, int g, int r)
{
	int i = 1;
	while (Mapsequence[i++] != 0)
	{
		if (Mapsequence[i - 1] == -520)continue;
		Posfunction(i - 1);
		circle(image, Point(pos.x, pos.y), 15, Scalar(b, g, r), -1);
		char s[3]; s[0] = (Mapsequence[i - 1] / 10 + '0'); s[1] = (Mapsequence[i - 1] % 10 + '0');
		s[2] = '\0';
		//putText这个函数是将节点的内容画在节点上
		putText(image, s, Point(pos.x, pos.y), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 2, 8);
		imshow("tree", image);
		waitKey(0);
		if (Mapsequence[2 * (i - 1)] != -520 && Mapsequence[2 * (i - 1)] != 0)
		{
			int x = pos.x; int y = pos.y;
			Posfunction(2 * (i - 1));
			line(image, Point(x, y), Point(pos.x, pos.y), Scalar(255, 255, 255), 2, CV_AA);
			imshow("tree", image);
			waitKey(0);
		}

		if (Mapsequence[2 * (i - 1) + 1] != -520 && Mapsequence[2 * (i - 1) + 1] != 0)
		{
			Posfunction(i - 1);
			int x = pos.x; int y = pos.y;
			Posfunction(2 * (i - 1) + 1);
			line(image, Point(x, y), Point(pos.x, pos.y), Scalar(255, 255, 255), 2, CV_AA);
			imshow("tree", image);
			waitKey(0);
		}

	}
}
void Posfunction(int num)
//5层以内满二叉树画法,建立编号与位置坐标的映射(对应关系)
{
	if (num < 1)
	{
		printf("enter num is illeage\n");
		exit(1);
	}
	else if (num == 1)
	{
		pos.x = 500; pos.y = 50;
		return;
	}
	else if (num == 2 || num == 3)
	{
		pos.y = 150;
		if (num == 2)
			pos.x = 300;
		else if (num == 3)
			pos.x = 700;
		return;
	}
	else if (num >= 4 && num <= 7)
	{
		pos.y = 250;
		pos.x = 200 * (num - 3);
		return;
	}
	else if (num >= 8 && num <= 15)
	{
		pos.y = 350;
		pos.x = 150 + 100 * (num - 8);
		return;
	}
	else if (num >= 16 && num <= 31)
	{
		pos.y = 550;
		pos.x = 125 + 50 * (num - 16);
		return;
	}
	else
	{
		printf("此画图函数解决不了了!!!\n");
	}

}
int Height(BST *T) 
//计算树的高度
{
	int n, m;
	if (T == NULL)
	{
		return 0;
	}
	n = Height(T->right_child);
	m = Height(T->left_child);
	if (m > n) 
	{
		return m + 1;
	}
	else 
	{
		return n + 1;
	}
}
void Calbalance(BST *T) 
//递归计算平衡因子
{
	if (T == NULL)
	{
		return;
	}
	T->bal = Height(T->right_child) - Height(T->left_child);//此处是右树高度减左树高度,在重新平衡的判定中起到作用
	Calbalance(T->right_child);
	Calbalance(T->left_child);
}
void InsertBalance(BST *x, BST *T)
//传参 parent 是最小不平衡子树的根节点 T是整棵树的根节点指针
//传参类型为指针的地址
{
	BST *parent = NULL;
	//x节点是插入节点的父亲节点
	//若插入节点不是树根结点
	if (x) 
	{
		parent = x->parent;//考察插入节点父亲节点的父亲节点
		while (parent)//当父亲存在时
		{
			//失衡节点是parent
			if (parent->bal < -1) //当右子树-左子树<-1
			{
				if (parent->left_child->bal == -1)
				{
					RotateRight(parent, T);
				}
				else
				{
					RotateLR(parent, T);
				}
				break;
			}
			if (parent->bal > 1)//当右子树-左子树>1
			{
				if (parent->right_child->bal == 1)
				{
					RotateLeft(parent, T);
				}
				else 
				{
					RotateRL(parent, T);
				}
				break;
			}
			else if (parent->bal == 0)
			{
				break;
			}
			parent = parent->parent;
		}
	}
}
void RotateRight(BST *parent, BST *T)
{
	//parent为最小不平衡子树的根节点
	BST *x = (parent)->parent;//记录父亲节点
	BST *SubL = (parent)->left_child;//记录根节点的左孩子
	BST *SubLR = SubL->right_child;//根节点左孩子的右孩子
	//parent的左孩子为SubLR
	parent->left_child = SubLR;
	if (SubLR) 
	{
		SubLR->parent = parent;
	}
	//SubL的右孩子为parent
	SubL->right_child = (parent);
	parent->parent = SubL;
	//若x不存在,则说明parent即是根节点
	if (!x) 
	{
		ROOT = SubL;
		SubL->parent = NULL;
	}
	//存在则判断parent是x的左孩子还是右孩子,SubL替换
	else {
		if (x->left_child == parent) 
		{
			x->left_child = SubL;
		}
		else 
		{
			x->right_child = SubL;
		}
		SubL->parent = x;
	}
}
void RotateLeft(BST *parent, BST *T) {
	BST *x = parent->parent;
	BST *SubR = parent->right_child;
	BST *SubRL = SubR->left_child;
	//parent的右孩子为SubRL
	parent->right_child = SubRL;
	if (SubRL) 
	{
		SubRL->parent = parent;
	}
	//SubR的左孩子为parent
	SubR->left_child = parent;
	parent->parent = SubR;
	//x的孩子为SubR
	if (!x)//如果x不存在
	{

		T = SubR;
		SubR->parent = NULL;
	}
	else 
	{
		if (x->left_child == parent) 
		{
			x->left_child = SubR;
		}
		else 
		{
			x->right_child = SubR;
		}
		SubR->parent = x;
	}
}
void RotateLR(BST *parent, BST *T) 
{
	//先对SubL进行左转变化、再对parent进行右转变化
	RotateLeft(parent->left_child, T);
	RotateRight(parent, T);
}
void RotateRL(BST *parent, BST *T)
{
	RotateRight(parent->right_child, T);
	RotateLeft(parent, T);
}
void Insert(int data) 
{
	BST *parent = NULL;//记录插入节点的父亲节点
	BST *p = ROOT;
	if (ROOT == NULL)//第一次插入的时候
	{
		BST *q = (BST *)malloc(sizeof(BST));
		q->bal = 0;
		q->data = data;
		q->left_child = NULL;
		q->parent = NULL;
		q->right_child = NULL;
		ROOT = q;
	}
	else
	{
		//找到插入位置
		while (p)
		{
			parent = p;//记录父亲节点
			if (data < p->data)
			{
				p = p->left_child;
			}
			else
			{
				p = p->right_child;
			}
		}
		//创新节点并插入
		BST *q = (BST *)malloc(sizeof(BST));
		q->bal = 0;
		q->data = data;
		q->left_child = NULL;
		q->parent = NULL;
		q->right_child = NULL;
		if (data < parent->data)
		{
			parent->left_child = q;
		}
		else 
		{
			parent->right_child = q;
		}
		q->parent = parent;
	}
	//更新平衡因子并维护平衡
	Calbalance(ROOT);
	InsertBalance(parent, ROOT);
	Calbalance(ROOT);
}
发布了29 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43343116/article/details/90641122
今日推荐