二叉树和堆的创建以及各种操作

#include"duilie.h"
typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi) {
	if (a[*pi] == '#' || a[*pi] == '\0') {
		return NULL;
	}
	BTNode* b = (BTNode*)malloc(sizeof(BTNode));
	assert(b != NULL);
	b->_data = a[*pi];
	(*pi)++;
	b->_left=BinaryTreeCreate(a, pi);
	(*pi)++;
	b->_right=BinaryTreeCreate(a, pi);
	return b;
}
// 二叉树销毁
void BinaryTreeDestory(BTNode** root) {

	if (*root != NULL)
	{
		BinaryTreeDestory(&(*root)->_left);
		BinaryTreeDestory(&(*root)->_right);
		free(*root);
		*root = NULL;
	}
}
// 二叉树节点个数
int BinaryTreeSize(BTNode* root) {
	if (root == NULL)
		return 0;
	return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root) {
	if (root == NULL)
		return 0;
	if (root->_left == NULL && root->_right == NULL)
		return 1;
	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k) {
	if (root == NULL||k==0)
		return 0;
	if (k==1)
		return 1;
	return  BinaryTreeLevelKSize(root->_left,k-1) + BinaryTreeLevelKSize(root->_right,k-1);
}
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x) {
	BTNode* p;
	if ( root == NULL||root->_data == x )
		return root;
	p =BinaryTreeFind(root->_left, x);
	if (p != NULL) {
		return p;
	}
	return BinaryTreeFind(root->_right, x);	
}
// 二叉树前序遍历,打印类型,中后遍历类似
void BinaryTreePrevOrder(BTNode* root) {
	if (root != NULL) {
		printf("%c", root->_data);
		BinaryTreePrevOrder(root->_left);
		BinaryTreePrevOrder(root->_right);
	}
}
//前序遍历,返回数组的类型,中后遍历类似
void func(struct TreeNode* root,int* a,int*res){
    if(root!=NULL){
        a[(*res)++]=root->val;
        func(root->left,a,res);
        func(root->right,a,res);
    }
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* a=(int*)malloc(sizeof(int)*100);
    *returnSize=0;
    func(root,a,returnSize);
    return a;
}
//非递归的前中后序遍历,用到链栈
void BinTreePreOrder_NoR(BinTree t)
{
	if(t != NULL)
	{
		LinkStack st;
		LinkStackInit(&st);
		LinkStackPush(&st, t);
		while(!LinkStackEmpty(&st))
		{
			BinTreeNode *p = LinkStackTop(&st);
			LinkStackPop(&st);
			printf("%c ", p->data);
			if(p->rightChild != NULL)
				LinkStackPush(&st, p->rightChild);
			if(p->leftChild != NULL)
				LinkStackPush(&st, p->leftChild);
		}
	}
}
void BinTreeInOrder_NoR(BinTree t)
{
	if(t != NULL)
	{
		LinkStack st;
		LinkStackInit(&st);

		do
		{
			while(t != NULL)
			{
				LinkStackPush(&st, t);
				t = t->leftChild;
			}
			BinTreeNode *p = LinkStackTop(&st);
			LinkStackPop(&st);
			printf("%c ", p->data);
			if(p->rightChild != NULL)
				t = p->rightChild;
		}while(!LinkStackEmpty(&st) || t!=NULL);
	}
}
void BinTreePostOrder_NoR(BinTree t)
{
	if(t != NULL)
	{
		BinTreeNode *prev = NULL;
		LinkStack st;
		LinkStackInit(&st);

		do
		{
			while(t != NULL)
			{
				LinkStackPush(&st, t);
				t = t->leftChild;
			}
			BinTreeNode *p = LinkStackTop(&st);
			if(p->rightChild==NULL || prev==p->rightChild)
			{
				LinkStackPop(&st);
				printf("%c ", p->data);
				prev = p;
			}
			else
				t = p->rightChild;
		}while(!LinkStackEmpty(&st));
	}
}

// 层序遍历,用队列
void BinaryTreeLevelOrder(BTNode* root) {
	if (root != NULL){
		Queue Q;
		QueueInit(&Q);
		QueuePush(&Q, root);
		while (!QueueEmpty(&Q)){
			BTNode* node = QueueFront(&Q);
			QueuePop(&Q);
			printf("%c", node->_data);
			//从每层第一个开始将该节点的子节点放入队尾
			if (node->_left != NULL)
				QueuePush(&Q, node->_left);
			if (node->_right != NULL)
				QueuePush(&Q, node->_right);
		}
	}
}
// 判断二叉树是否是完全二叉树,用到队列
int BinaryTreeComplete(BTNode* root) {
	Queue qu;
	BTNode* cur;
	int tag = 0;
	QueueInit(&qu);
	QueuePush(&qu, root);
	while (!QueueEmpty(&qu)) {
		cur = QueueFront(&qu);
		//putchar(cur->data);
		//有右子树没有左子树则不是完全二叉树
		if (cur->_right && !cur->_left) {
			return 0;
		}
		if (cur->_left) {
			QueuePush(&qu, cur->_left);
		}
		if (tag && (cur->_left || cur->_right)) {
			return 0;
		}
		if (cur->_right) {
			QueuePush(&qu, cur->_right);
		}
		else {
			//若该节点没有右子树就将该标签置为1
			tag = 1;
		}
		QueuePop(&qu);
	}
	QueueDestroy(&qu);
	return 1;
}
//判断是否为平衡树
void inorder(BTnode* root) {
    if (root != NULL) {
        inorder(root->left);
        printf("%c ", root->val);
        inorder(root->right);
    }
}
int lhigh(BTnode* l) {
    if (l == NULL)
        return 0;
    int lh = lhigh(l->left);
    int rh = lhigh(l->right);
    return (lh > rh ? lh : rh) + 1;
}
int rhigh(BTnode* r) {
    if (r == NULL)
        return 0;
    int lh = lhigh(r->left);
    int rh = lhigh(r->right);
    return (lh > rh ? lh : rh) + 1;
}
bool isBalanced(BTnode* root) {
    while (root != NULL) {
        int lh = lhigh(root->left);
        int rh = rhigh(root->right);
        if (lh - rh > 1 || rh - lh>1)
            return false;
    }
    return true;
}
//判断是否为单值二叉树
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int sum(struct TreeNode* root) {
    if (root == NULL) {
        return 0;
    }
    return sum(root->left) + sum(root->right) + 1;
}
void func(struct TreeNode* root, int* a, int* res) {
    if (root != NULL) {
        a[(*res)++] = root->val;
        func(root->left, a, res);
        func(root->right, a, res);
    }
}
bool isUnivalTree(struct TreeNode* root) {
    int k = sum(root);
    int* a = (int*)malloc(sizeof(int) * 100);
    int  n = 0;
    func(root, a, &n);
    int b = a[0];
    int c = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] == b) {
            c++;
        }
    }
    if (c != k)
        return false;
    return true;
}
//判断是否包含子树
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if (p == NULL && q == NULL)
        return true;
    if (p == NULL || q == NULL)
        return false;
    return (p->val == q->val) && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
    if (root == NULL)
        return false;
    return isSameTree(root, subRoot) ||
        isSubtree(root->left, subRoot) ||
        isSubtree(root->right, subRoot);
}
//判断是否是对称二叉树是否镜像对称
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool func(struct TreeNode* p,struct TreeNode* q){
    if(p==NULL&&q==NULL)
        return true;
    if(p==NULL||q==NULL)
       return false;
    return (p->val==q->val)&&func(p->left,q->right)&&func(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root){
   return func(root,root);
}
//判断两个树是否相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    if(p==NULL&&q==NULL)
    return true;
    if(p==NULL||q==NULL)
    return false;
    return (p->val==q->val)&&isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
//翻转一棵二叉树
struct TreeNode* invertTree(struct TreeNode* root){
    if(root==NULL)
    return NULL;
    struct TreeNode* t=root->left;
    root->left=root->right;
    root->right=t;
    invertTree(root->left);
    invertTree(root->right);
    return root;
}
//树的高度
int maxDepth(struct TreeNode* root){
    if(root==NULL)
    return 0;
    int left_h=maxDepth(root->left);
    int right_h=maxDepth(root->right);
    return(left_h>right_h?left_h:right_h)+1;
}
//是否是单值二叉树
int sum(struct TreeNode* root){//此函数算节点总数
    if(root==NULL){
        return 0;
    }
    return sum(root->left)+sum(root->right)+1;
}
void func(struct TreeNode* root,int* a,int*res){
    if(root!=NULL){
        a[(*res)++]=root->val;
        func(root->left,a,res);
        func(root->right,a,res);
    }
}
bool isUnivalTree(struct TreeNode* root){
    int k=sum(root);
    int* a=(int*)malloc(sizeof(int)*100);
    int  n=0;
    func(root,a,&n);
    int b=a[0];
    int c=0;
    for(int i=0;i<n;i++){
        if(a[i]==b){
            c++;
        }
    }
    if(c!=k)
    return false;
    return true;
}
//克隆一棵树
BinTreeNode* Clone(BinTree t)
{
	BinTreeNode *p;
	if(t == NULL)
		return NULL;

	p = (BinTreeNode*)malloc(sizeof(BinTreeNode));
	assert(p != NULL);
	p->data = t->data;
	p->leftChild = Clone(t->leftChild);
	p->rightChild = Clone(t->rightChild);
	return p;
}
//找某个值节点
BinTreeNode* Find(BinTree t, ElemType key)
{
	BinTreeNode *p;
	if(t==NULL || t->data==key)
		return t;
	p = Find(t->leftChild, key);
	if(p != NULL)
		return p;
	return Find(t->rightChild, key);
}
//找父节点
BinTreeNode* Parent(BinTree t, BinTreeNode *p)
{
	BinTreeNode *ret;
	if(t==NULL || t->leftChild==p || t->rightChild==p)
		return t;
	ret = Parent(t->leftChild, p);
	if(ret != NULL)
		return ret;
	return Parent(t->rightChild, p);
}
int main() {
	char* a= "ABD##E#H##CF##G##";
	int n=0;
	BTNode* bt;
	bt=BinaryTreeCreate(a,&n);
	int k=BinaryTreeSize(bt);
	int ks = BinaryTreeLevelKSize(bt, 4);
	char x = 'E';
	BTNode* p=BinaryTreeFind(bt, x);
	BinaryTreePrevOrder(bt);
	printf("\n");
	BinaryTreeLevelOrder(bt);
	printf("\n");
	return 0;
}

堆:

#include<stdio.h>
#include<assert.h>
typedef int HPDataType;
typedef struct Heap
{
	HPDataType* _a;
	int _size;
	int _capacity;
}Heap;
void hpshow(Heap* hp) {
	for (int i = 0; i < hp->_size; i++) {
		printf("%d ", hp->_a[i]);
	}
}
//向上排,一个一个插入时写法,不需要比较兄弟节点大小
void AdjustUp(Heap* hp, int start) {
	int j = start;
	int i = (j - 1) / 2;
	while (j>=0){
		if (hp->_a[i] < hp->_a[j]) {
			HPDataType t = hp->_a[i];
			hp->_a[i] = hp->_a[i];
			hp->_a[i] = t;
			j = i;		
			i = (j - 1) / 2;
		}		
		else
			break;
	}
}
//向下排,create一次性创建堆时调用
void AdjustDown(Heap* hp, int start) {
	int i = start;
	int j = i * 2 + 1;
	while (j<hp->_size){
		if (hp->_a[j]<hp->_a[j + 1]&&j+1<hp->_size) {
			j++;
		}
		if (hp->_a[i] < hp->_a[j]) {
			HPDataType t = hp->_a[i];
			hp->_a[i] = hp->_a[j];
			hp->_a[j] = t;
			i = j;
			j = i * 2 + 1;
		}
		else
			break;
	}
}
void _AdjustDown(Heap* hp, int start) {
	int i = start;
	int j = i * 2 + 1;
	while (j < hp->_size) {
		if (hp->_a[j] > hp->_a[j + 1]&&j+1<hp->_size) {
			j++;
		}
		if (hp->_a[i] > hp->_a[j]) {
			HPDataType t = hp->_a[i];
			hp->_a[i] = hp->_a[j];
			hp->_a[j] = t;
			i = j;
			j = i * 2 + 1;
		}
		else
			break;
	}
}
// 堆的构建
void HeapCreate(Heap* hp, HPDataType* a, int n) {
	hp->_capacity = n;
	hp->_a = (HPDataType*)malloc(sizeof(HPDataType)*hp->_capacity);
	assert(hp->_a != NULL);
	for (int i = 0; i < n; i++) {
		hp->_a[i] = a[i];
	}
	hp->_size = n;
	int k = (n - 1) / 2;
	while (k>=0){
		AdjustDown(hp, k);
		k--;
	}
}
void HeapCreatetopk(Heap* hp, HPDataType* a, int n) {
	hp->_capacity = n;
	hp->_a = (HPDataType*)malloc(sizeof(HPDataType) * hp->_capacity);
	assert(hp->_a != NULL);
	for (int i = 0; i < n; i++) {
		hp->_a[i] = a[i];
	}
	hp->_size = n;
	int k = (n - 1) / 2;
	while (k >= 0) {
		_AdjustDown(hp, k);
		k--;
	}
}
// 堆的销毁
void HeapDestory(Heap* hp) {
	free(hp->_a);
	hp->_a == NULL;
	hp->_capacity = hp->_size = 0;
}
// 堆的插入
void HeapPush(Heap* hp, HPDataType x) {
	if (hp->_capacity >= hp->_size) {
		hp->_a = (HPDataType*)realloc(sizeof(HPDataType) * (hp->_capacity+3));
	}
	hp->_a[hp->_size] = x;
	AdjustUp(hp, hp->_size);
	hp->_size++;
}
// 堆的删除
void HeapPop(Heap* hp) {
	if (hp->_size == 0)
		return;
	HPDataType t = hp->_a[0];
	hp->_a[0] = hp->_a[hp->_size-1];
	hp->_a[hp->_size-1] = t;
	hp->_size--;
	AdjustDown(hp, 0);
}
// 取堆顶的数据
HPDataType HeapTop(Heap* hp) {
	if (hp->_size == 0) {
		return 0;
	}
	return hp->_a[0];
}
// 堆的数据个数
int HeapSize(Heap* hp) {
	return hp->_size;
}
// 堆的判空
int HeapEmpty(Heap* hp) {

}


// TopK问题:找出N个数里面最大/最小的前K个问题。
// 比如:未央区排名前10的泡馍,西安交通大学王者荣耀排名前10的韩信,全国排名前10的李白。等等问题都是Topk问题,
// 需要注意:
// 找最大的前K个,建立K个数的小堆
// 找最小的前K个,建立K个数的大堆
void PrintTopK(int* a, int n, int k) {
	Heap hp;
	HeapCreatetopk(&hp, a, k);
	for (int i = k; i < n; i++) {
		if (a[i] >= HeapTop(&hp)) {
			hp._a[0] = a[i];
			_AdjustDown(&hp, 0);
		}
	}
	int m = (k - 1) / 2;
	while (m>=0){
		AdjustDown(&hp, m);
		m--;
	}
	int b[] = { 0 };
	for (int i = 0; i < k; i++) {
		b[i] = HeapTop(&hp);
		HeapPop(&hp);
	}
	for (int i = 0; i < k; i++) {
		printf("%d ", b[i]);
	}
	return;
}
void TestTopk() {

}


// 对数组进行堆排序
void HeapSort(int* a, int n) {
	Heap hp;
	HeapCreate(&hp, a, n);
	int b[]= { 0 };
	for (int i = 0; i < n; i++) {
		hpshow(&hp);
		printf("\n");
		b[i] = HeapTop(&hp);
		HeapPop(&hp);	
	}
	for (int i = 0, j = n - 1; i < n; i++, j--) {
		a[i] = b[j];
	}
}
int main() {
	Heap hp;//默认创建大堆
	int a[] = { 27,15,19,18,28,34,65,49,25,37 };
	int n = sizeof(a) / sizeof(a[0]);
	PrintTopK(a, n, 4);
	/*HeapCreatetopk(&hp, a, n);
	hpshow(&hp);*/

	/*HeapSort(a, n);
	for (int i = 0; i < n; i++) {
		printf("%d,", a[i]);
	}*/
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值