二项堆Binomial Queues

在这里插入图片描述
在这里插入图片描述

二项堆的具体实现代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct BinNode *Position;
typedef struct BinNode *BinTree;
typedef struct Collection *BinQueue;

struct BinNode
{
	int Element;
	Position LeftChild;
	Position Sibling;
}BINNODE;
struct Collection
{
	int CurrentSize;
	BinTree TheTrees[100];
}COLLECTION;

BinTree CombineTrees(BinTree T1,BinTree T2);
BinQueue Merge(BinQueue H1, BinQueue H2);
void print(BinTree T);

int main()
{
    
    char initial[100];
    BinQueue heap=NULL, temp=NULL;
    int i=0,j=0;
    int N=0;
    scanf("%s",initial);
    heap=(BinQueue)malloc(sizeof(COLLECTION));
    heap->CurrentSize=1;
    for(i=0;i<100;i++)
    {
        heap->TheTrees[i]=NULL;
    }
    heap->TheTrees[0] = (BinTree)malloc(sizeof(struct BinNode));//从第0个开始建树//
	heap->TheTrees[0]->Element=initial[0]-'0';//放入第一个数据并自动转化成整数型//
	heap->TheTrees[0]->LeftChild = NULL;
	heap->TheTrees[0]->Sibling = NULL;
	j=2;//因为第一个数放进去了,所以从第二个数开始//
	while(initial[j]!=','&&initial[j]!='\n'&&initial[j]!='\0')
	{
	    temp=(BinQueue)malloc(sizeof(COLLECTION));//临时建立另一个指针数组//
	    temp->CurrentSize=1;
	    for(i=0;i<99;i++)
	    {
	    	temp->TheTrees[i]=NULL;//记得全部初始化否则在不同的运行环境下会出现不同的错误//
		}
	    
	    temp->TheTrees[0] = (BinTree)malloc(sizeof(struct BinNode));//分配内存//
		temp->TheTrees[0]->Element=initial[j]-'0';//从第二个数开始//
		temp->TheTrees[0]->LeftChild = NULL;
		temp->TheTrees[0]->Sibling = NULL;
		heap = Merge(heap,temp);//合并//
		j=j+2;//在这里我们的测试数据都是个位数所以直接移动到后第二个即可//
	}

	scanf("%d",&N);
	if(N>=heap->CurrentSize)
	{
	    printf("0,");
	}
	else if (heap->TheTrees[N]==NULL)
	{
		printf("0,");
	}
	else
	{	   
	    print(heap->TheTrees[N]);
	}
}

void print(BinTree T)
{
    if(T!=NULL)
    {
        printf("%d,",T->Element);
        if(T->LeftChild!=NULL)
        {
            if(T->LeftChild->Sibling!=NULL)
            {
                printf("%d,",T->LeftChild->Sibling->Element);
            }
            print(T->LeftChild);
        }
    }
}
BinTree CombineTrees(BinTree T1,BinTree T2)
{
    if(T1==NULL)
    {
        return T2;
    }
    if(T2==NULL)
    {
        return T1;
    }
	if(T1->Element>T2->Element)
	{
		return CombineTrees(T2,T1);
	}
	T2->Sibling = T1->LeftChild;
	T1->LeftChild = T2;
	return T1;
}

BinQueue Merge(BinQueue H1,BinQueue H2 )
{
    BinTree T1, T2, Carry = NULL;
	int i, j;
	H1->CurrentSize += H2-> CurrentSize;
	for ( i=0, j=1; j<= H1->CurrentSize; i++, j*=2 )
	{
	    T1 = H1->TheTrees[i]; T2 = H2->TheTrees[i]; /*current trees */
	    switch( 4*!!Carry + 2*!!T2 + !!T1 )
	    {
		case 0: /* 000 */
	 	case 1: /* 001 */
	 	        {
	 	            break;
	        	}
		case 2: /* 010 */
		        {
		            H1->TheTrees[i] = T2;
		            H2->TheTrees[i] = NULL;
		            break;
		        }
		
		case 3: /* 011 */
		        {
		            Carry = CombineTrees( T1, T2 );
			        H1->TheTrees[i] =NULL;
					H2->TheTrees[i] = NULL;
					break;
		        }
	    case 4: /* 100 */
		        {
		            H1->TheTrees[i] = Carry;
		            Carry = NULL;
		            break;
		        }
		case 5: /* 101 */
		        {
		            Carry = CombineTrees( T1, Carry );
			        H1->TheTrees[i] = NULL;
			        break;
		        }
		case 6: /* 110 */
		        {
		            Carry = CombineTrees( T2, Carry );
			        H2->TheTrees[i] = NULL;
			        break;
		        }
		case 7: /* 111 */
		        {
		            H1->TheTrees[i] = Carry;
			        Carry = CombineTrees( T1, T2 );
			        H2->TheTrees[i] = NULL;
			        break;
		        }
	    }
	}
	return H1;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
二项Binomial Heap)是一种非常高效的数据结构,它可以在插入、删除和合并等操作上达到O(logn)的时间复杂度。下面是二项的C语言实现代码: ```c #include <stdio.h> #include <stdlib.h> // 二项节点结构体 typedef struct node { int val; // 节点的值 int degree; // 节点的度数 struct node *child; // 节点的左孩子 struct node *sibling; // 节点的右兄弟 } Node; // 创建节点 Node *create_node(int val) { Node *node = (Node *)malloc(sizeof(Node)); node->val = val; node->degree = 0; node->child = NULL; node->sibling = NULL; return node; } // 合并两个二项 Node *merge(Node *h1, Node *h2) { if (h1 == NULL) { return h2; } if (h2 == NULL) { return h1; } Node *head = NULL; // 合并后的的头节点 Node *tail = NULL; // 合并后的的尾节点 Node *p1 = h1; Node *p2 = h2; while (p1 != NULL && p2 != NULL) { if (p1->degree <= p2->degree) { if (head == NULL) { head = p1; } else { tail->sibling = p1; } tail = p1; p1 = p1->sibling; } else { if (head == NULL) { head = p2; } else { tail->sibling = p2; } tail = p2; p2 = p2->sibling; } } if (p1 != NULL) { tail->sibling = p1; } else { tail->sibling = p2; } return head; } // 插入节点 Node *insert(Node *h, int val) { Node *node = create_node(val); return merge(h, node); } // 查找最小值节点 Node *find_min(Node *h) { Node *min_node = h; Node *p = h->sibling; while (p != NULL) { if (p->val < min_node->val) { min_node = p; } p = p->sibling; } return min_node; } // 删除最小值节点 Node *delete_min(Node *h) { Node *min_node = find_min(h); if (min_node == h) { // 头节点就是最小值节点 h = h->sibling; } else { // 删除最小值节点,然后将其子树与其他树合并 Node *pre_min_node = h; while (pre_min_node->sibling != min_node) { pre_min_node = pre_min_node->sibling; } pre_min_node->sibling = min_node->sibling; Node *child_h = min_node->child; // 将最小值节点的子树反转后插入到中 Node *new_h = NULL; while (child_h != NULL) { Node *next_child_h = child_h->sibling; child_h->sibling = new_h; new_h = child_h; child_h = next_child_h; } h = merge(h, new_h); free(min_node); } return h; } int main() { Node *h = NULL; // 二项 int n, op, val; scanf("%d", &n); while (n--) { scanf("%d", &op); switch (op) { case 0: // 插入节点 scanf("%d", &val); h = insert(h, val); break; case 1: // 查找最小值节点 printf("%d\n", find_min(h)->val); break; case 2: // 删除最小值节点 h = delete_min(h); break; } } return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值