0
点赞
收藏
分享

微信扫一扫

一文了解VR全景在城市园区和电子楼书的应用

未定义变量 2023-10-02 阅读 59
数据结构

在这里插入图片描述


文章目录

前言

📚一、二叉树链式结构的接口补充

📔1.1 二叉树第k层节点的个数

int BinaryTreeLevelKSize(BTNode* root, int k)
{
	assert(k > 0);//检测k是否小于0
	
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}
	
	return BinaryTreeLevelKSize(root->left, k - 1) 
		+ BinaryTreeLevelKSize(root->right, k - 1);
}

📔1.2 二叉树查找值为x的节点

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	
	if (root->val == x)
	{
		return root;
	}

	BTNode* ret = NULL;
	ret = BinaryTreeFind(root->left, x);
	if (ret)
	{
		return ret;
	}

	ret = BinaryTreeFind(root->right, x);
	if (ret)
	{
		return ret;
	}

	return NULL;
}

📔1.3 判断一颗二叉树是否是完全二叉树

bool BinaryTreeComplete(BTNode* root)
{
	//创建及初始化队列
	Que q;
	QueueInit(&q);
	//把根不等于空(NULL)时入队列
	if (root)
	{
		QueuePush(&q, root);
	}
	
	//思路:上一层出带下一层进
	while (!QueueEmpty(&q))
	{
		BTNode* Front = QueueFront(&q);
		//当节点等于空时,break跳出循环
		if (Front == NULL)
		{
			break;
		}
		//NULL也入队列
		QueuePush(&q, Front->left);
		QueuePush(&q, Front->right);
		QueuePop(&q);
	}

	//继续出队列,此时如果遇到不等于空(NULL)的节点
	//那么这颗树就不是完全二叉树
	while (!QueueEmpty(&q))
	{

		BTNode* Front = QueueFront(&q);
		QueuePop(&q);
		if (Front != NULL)
		{
			QueueDestroy(&q);
			return false;
		}

	}

	QueueDestroy(&q);
	//到这里时,已经遍历完整棵树了,此时这棵树就是完全二叉树
	return true;
}

📚二、二叉树的顺序结构

📔2.1 二叉树顺序结构的概念

  • 堆的结构
typedef int HPDataType;
typedef struct Heap
{
	HPDataType* arr;
	int size;
	int capacity;
}HP;

📔2.2 堆实现

📕2.2.1 堆的初始化

  1. 第一种结构:
void HeapInit(HP* php)
{
	assert(php);
	php->arr = NULL;
	php->capacity = 0;
	php->size = 0;
}
  • 第二种结构:
void HeapInitArray(HP* php, HPDataType* arr, int n)
{
	assert(php);
	assert(arr);

	//开辟n个空间
	php->arr = (HPDataType*)malloc(sizeof(HPDataType)*n);
	if (php->arr == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	php->capacity = n;
	php->size = n;

	//把原数组的数据拷贝到在堆上开辟的数组里
	memcpy(php->arr, arr, sizeof(HPDataType) * n);

	//向上调整建堆
	int i = 0;
	for (i = 1; i < n; i++)
	{
		AdjustUp(php->arr, i);
	}

}

📕2.2.2 堆的销毁

void HeapDestroy(HP* php)
{
	assert(php);
	free(php->arr);
	php->arr = NULL;
	php->capacity = 0;
	php->size = 0;
}

📕2.2.3 堆的插入

在这里插入图片描述

//容量满了,扩容
	if (php->size == php->capacity)
	{
		int newCapacity = php->capacity == 0 ? 
					INIT_SIZE : php->capacity * TIMES;
		HPDataType* tmp=(HPDataType*)realloc(php->arr, 
					sizeof(HPDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		php->arr = tmp;
		php->capacity = newCapacity;
	}
	php->arr[php->size] = x;
	php->size++;
	AdjustUp(php->arr, php->size-1);
📃2.2.3.1 向上调整算法
void AdjustUp(int* arr, int child)
{
	int parent = (child - 1) / 2;//计算父亲的位置
	//child等于0时,为循环结束的条件
	while (child > 0)
	{
		if (arr[child] < arr[parent])
		{
			Swap(&arr[child], &arr[parent]);//交换函数
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			//孩子大于父亲时跳出循环
			break;
		}

	}

}
int main()
{
	int arr[] = { 65,100,70,32,50,60 };
	HP hp;
	HeapInit(&hp);
	int i = 0;
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		HeapPush(&hp, arr[i]);
	}
	HeapPrint(&hp);
	HeapDestroy(&hp);

	return 0;
}

在这里插入图片描述

📕2.2.4 堆的删除

void HeapPop(HP* php)
{
	assert(php);
	assert(php->size > 0);

	//交换首尾的数据
	Swap(&php->arr[0], &php->arr[php->size - 1]);
	php->size--;
	//然后向下调整
	AdjustDown(php->arr, php->size, 0);
}
📃2.2.4.1 向下调整算法
void AdjustDown(int* arr, int n, int parent)
{
	//默认选择左孩子
	int child = parent * 2 + 1;
	while (child < n)
	{
		//左孩子表示最小的
		//那么改为右孩子
		if (child+1 < n && arr[child + 1] < arr[child])
		{
			++child;
		}

		if (arr[child] < arr[parent])
		{
			Swap(&arr[child], &arr[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			//孩子大于父亲,就跳出循环
			break;
		}

	}

}

📕2.2.5 获取堆顶元素

HPDataType HeapTop(HP* php)
{
	assert(php);
	assert(php->size > 0);

	return php->arr[0];
}

📕2.2.6 检测堆是否为空

bool HeapEmpty(HP* php)
{
	assert(php);
	return php->size == 0;
}

📔2.3 堆排序

void HeapSort(int* arr, int n)
{
	//向上调整建堆O(N*logN)
	int i = 0;
	for (i = 1; i < n; i++)
	{
		AdjustUp(arr, i);
	}
	
	int end = n-1;
	while (end > 0)
	{
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, end, 0);
		end--;
	}

}
void HeapSort(int* arr, int n)
{
	//向下调整建堆O(N)
	int i = 0;
	for (i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(arr, n, i);
	}

	int end = n-1;
	while (end > 0)
	{
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, end, 0);
		end--;
	}

}

📔2.4 TOPK问题

void CreateNDate()
{
	// 造数据
	int n = 10000;
	srand((unsigned int)time(0));
	const char* file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fopen error");
		return;
	}

	for (int i = 0; i < n; ++i)
	{
		int x = (rand() + i) % 10000000;
		fprintf(fin, "%d\n", x);
	}

	fclose(fin);
}
int main()
{
	//CreateNDate();
	//传入文件名和要k的数值
	PrintTopK("data.txt", 10);

	return 0;
}
void PrintTopK(const char* filename, int k)
{
	FILE* pf = fopen(filename, "r");
	if (pf == NULL)
	{
		perror("fopen fail");
		exit(-1);
	}

	int* heap = (int*)malloc(sizeof(int) * k);
	if (heap == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	
	// 1、取出前k个数据建堆
	int i = 0;
	for (i = 0; i < k; i++)
	{
		fscanf(pf, "%d", &heap[i]);
	}

	//2.、前k个数向下调整,建堆
	//k-1找到最后一个元素的下标
	//(k-1-1)/2找到最后一个节点的父亲节点
	for (i=(k-1-1)/2; i>=0; i--)
	{
		AdjustDown(heap, k, i);
	}

	fclose(pf);
	free(heap);
	pf = NULL;
	heap = NULL;
}
void PrintTopK(const char* filename, int k)
{
	FILE* pf = fopen(filename, "r");
	if (pf == NULL)
	{
		perror("fopen fail");
		exit(-1);
	}

	int* heap = (int*)malloc(sizeof(int) * k);
	if (heap == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	
	// 1、取出前k个数据建堆
	int i = 0;
	for (i = 0; i < k; i++)
	{
		fscanf(pf, "%d", &heap[i]);
	}

	//2.、前k个数向下调整,建堆
	for (i=(k-1-1)/2; i>=0; i--)
	{
		AdjustDown(heap, k, i);
	}

	
	// 读取剩下的数据依次跟堆顶数据比较,
	//大于堆顶就替换进堆,然后再向下调整
	int x = 0;
	while (fscanf(pf, "%d", &x) != EOF)
	{
		//大于堆顶就替换它进堆
		if (x > heap[0])
		{
			heap[0] = x;
			//替换后,再向下调整
			AdjustDown(heap, k, 0);
		}
		
	}

	for (i = 0; i < k; i++)
	{
		printf("%d ", heap[i]);
	}
	printf("\n");

	fclose(pf);
	free(heap);
	pf = NULL;
	heap = NULL;
}
  • 测试
  • 测试结果:
    在这里插入图片描述

📔2.5本篇章的代码

堆的实现代码

举报

相关推荐

0 条评论