Loading

重点树

  1. bst
  2. bbst(AVL)
  3. 红黑树
  4. 伸展树
  5. B树
  6. B+树
  7. B*树
  8. k-d树
  9. trie树(字典树)
  10. 区间树与线段树

二叉树

二叉树的操作

  1. 一个一般意义上的多叉树是可以转换为一个二叉树的
  2. 根据中序遍历+前序或后续的一个,就可以构造出一颗树
  3. 前序+后序 与 真二叉树 是可以还原真二叉树
  4. 真二叉树:每个节点的出度都是偶数,要么是0,要么是2,不可能是1

树的同构

# include <stdio.h>
# define Null -1

typedef struct Node
{
     char Data;
     char Left;
     char Right;
}Node;

Node T1[10],T2[10];

int CreatTree(Node T[])
{
    int N,Cheak[10]={0};
    int i,Root=Null;
    scanf("%d\\n",&N);
    for(i=0;i<N;i++)
    {

        scanf("%c %c %c\\n",&T[i].Data,&T[i].Left,&T[i].Right);
        if(T[i].Left=='-')
            T[i].Left=Null;
        else
        {
            T[i].Left=T[i].Left-'0';
            Cheak[T[i].Left]=1;
        }
        if(T[i].Right=='-')
            T[i].Right=Null;
        else
        {
            T[i].Right=T[i].Right-'0';
            Cheak[T[i].Right]=1;
        }
    }

    for (i = 0; i < N; i++)
    {
        if(!Cheak[i])
        {
            Root=i;
            break;
        }

    }
    return Root;
}

int Isomprphic(int root1,int root2)
{
    if( (root1 == Null) && (root2 == Null))//都是空 ,同构 
         return 1;
     if( (root1 == Null) && (root2 != Null) || (root1 != Null)&&(root2 == Null))//其中一个为空,不同构 
         return 0;
     if(T1[root1].Data != T2[root2].Data)     //根数据不同,不同构 
         return 0;
     if( (T1[root1].Left == Null) && (T2[root2].Left == Null) ) //左子树为空,则判断右子树 
         return Isomprphic(T1[root1].Right, T2[root2].Right);
         
    if((T1[root1].Left != Null) && (T2[root2].Left != Null) &&
         ( T1[T1[root1].Left].Data == T2[T2[root2].Left].Data) )//两树左子树皆不空,且值相等 
         return (Isomprphic(T1[root1].Left, T2[root2].Left) &&  //判断其子树 
                 Isomprphic(T1[root1].Right, T2[root2].Right) );
     else //两树左子树有一个空  或者  皆不空但值不等  
         return (Isomprphic(T1[root1].Left, T2[root2].Right) &&  //交换左右子树判断 
                Isomprphic(T1[root1].Right, T2[root2].Left) );
}

int main()  
{
    
    int Root1=CreatTree(T1);
    int Root2=CreatTree(T2);
    if (Isomprphic(Root1,Root2))
        printf("Yes\\n");
    else
        printf("No\\n");
    return 0;
}

曼哈顿树的编码与解码

# include <stdio.h>         
# include <stdlib.h>
# include <string.h>
# define MaxSize 100
# define MinWeight -1

typedef struct HuffmanNode* HuffmanTree;
typedef struct HuffmanNode
{
	char Data;
	int Weight;
	HuffmanTree Left,Right;
} HuffmanNode;

typedef struct HeapNode* MinHeap;
typedef struct HeapNode
{
	char* Data;
	int* Weight;
	HuffmanTree* P;
	int size;
	int Capacity; 
}HeapNode;

MinHeap Creat(int sum)
{
	MinHeap H=(MinHeap)malloc(sizeof(HeapNode));
	H->Weight=(int*)malloc((MaxSize+1)*sizeof(int));
	H->Data=(char*)malloc((MaxSize+1)*sizeof(char));
	H->P=(HuffmanTree*)malloc((MaxSize+1)*sizeof(HuffmanTree));
	H->size=0;
	H->Capacity=MaxSize;
	H->Weight[0]=MinWeight;
	return H;
}

void Initialize(MinHeap H)
{
	int i;
	for (i = 1; i <= H->size; i++)
	{
		H->P[i]=(HuffmanTree)malloc(sizeof(HuffmanNode));
		H->P[i]->Weight=H->Weight[i];
		H->P[i]->Data=H->Data[i];
		H->P[i]->Left=NULL;
		H->P[i]->Right=NULL;
	}
	return;
}

void PercDown(MinHeap H,int i)
{
	int Parent, Child;
	 int X;
	 char temp;
   	HuffmanTree Change;
    X = H->Weight[i]; /* 取出根结点存放的值 */
    for( Parent=i; Parent*2<=H->size; Parent=Child ) {
        Child = Parent * 2;
        if( (Child!=H->size) && (H->Weight[Child]>H->Weight[Child+1]) )
            Child++;  /* Child指向左右子结点的较小者 */
        if( X <= H->Weight[Child] ) break; /* 找到了合适位置 */
        else 
        {
            H->Weight[Parent] = H->Weight[Child];
            Change=H->P[Child];
            H->P[Child]=H->P[Parent];
            H->P[Parent]=Change;
            temp=H->Data[Child];
            H->Data[Child]=H->Data[Parent];
            H->Data[Parent]=temp;
            
        }
    }
    H->Weight[Parent] = X;
	return;
}

void BuildMinHeap(MinHeap H) //建立最小堆
{
	int i;
	for (i = H->size/2; i >0; i--)
		PercDown(H,i);
}

int IsEmpty(MinHeap H)
{
	if (H->size==0)
		return 1;
	else
		return 0;
}

HuffmanTree DeletMin(MinHeap H)
{
	int Parent,Child;
	int MaxItem,temp;
	char temp2;
	HuffmanTree MaxItemP,Change;
	if (IsEmpty(H))
	{
		printf("堆为空\\n");
		return NULL;
	}
	MaxItemP=H->P[1];
	H->P[1]=H->P[H->size];
	H->Data[1]=H->Data[H->size];
	temp=H->Weight[H->size--];
	for( Parent=1; Parent*2<=H->size; Parent=Child ) {
		 Child = Parent * 2;
		 if( (Child!=H->size) && (H->Weight[Child]>H->Weight[Child+1]) )
		 Child++;  /* Child指向左右子结点的较小者 */
		 if( temp <= H->Weight[Child] ) break; /* 找到了合适位置 */
	        else 
	        {
	            H->Weight[Parent] = H->Weight[Child];
	            Change=H->P[Child];
	            H->P[Child]=H->P[Parent];
	            H->P[Parent]=Change;
	            temp2=H->Data[Child];
	            H->Data[Child]=H->Data[Parent];
	            H->Data[Parent]=temp2;
	        }
    }
    H->Weight[Parent] = temp;
    return MaxItemP;
}

int IsFull(MinHeap H)
{
	if(H->size==H->Capacity)
		return 1;
	else
		return 0;
}

void Insert(MinHeap H,HuffmanTree T)
{
	int i;
	int item=T->Weight;
	char temp;
	HuffmanTree Change;
	if(IsFull(H))
	{
		printf("堆满\\n");
		return;
	}
	i=++H->size;
	H->P[H->size]=T;
	for(;H->Weight[i/2]>item;i/=2)
	{
		H->Weight[i]=H->Weight[i/2];
		Change=H->P[i];
		H->P[i]=H->P[i/2];
		H->P[i/2]=Change;
		temp=H->Data[i];
		 H->Data[i]=H->Data[i/2];
		 H->Data[i/2]=temp;
	}
	H->Weight[i]=item;
}

HuffmanTree Huffman(MinHeap H) //建立曼哈顿树(链表)
{
	int i;
	int m=H->size;
	HuffmanTree T;
	BuildMinHeap(H);
	for(i=1;i<m;i++)
	{
		T=(HuffmanTree)malloc(sizeof(HuffmanNode));
		T->Left=DeletMin(H);
		T->Right=DeletMin(H);
		T->Weight=T->Left->Weight+T->Right->Weight;
		T->Data='*';
		Insert(H,T);
	}
	T=DeletMin(H);
	return T;
}

void Encode(HuffmanTree T,int Level,char str[])
{
	if(T->Left==NULL && T->Right==NULL)
	{
		str[Level]='\\0';       //加‘\\0’表示结束
		printf("%c %s\\n",T->Data,str);
		return;
	}
	else
	{
		str[Level]='0';
		Encode(T->Left,Level+1,str);
		str[Level]='1';
		Encode(T->Right,Level+1,str);
	}
}

void Decoded(HuffmanTree T,char str2[])     //解码
{
	char pr[100];
	int i=0;
	HuffmanTree Head=T;
	while(*str2!='\\0')
	{	
			if (*str2=='0')
				Head=Head->Left;
			else
				Head=Head->Right;
			if(Head->Left==NULL)
			{
				
				pr[i]=Head->Data;
				i++;
				pr[i+1]='\\0';
				Head=T;
			}
			str2++;
	}
	if(Head!=T)               //当把最后一个数字遍历后,如果正好是在叶节点的位置,说明可以正好全部解码
		printf("解码失败\\n");
	else
		printf("%s\\n",pr);	
}



	
int main()      //未解决:如果是“AAAA”怎么办?
{					//编码:链表(表示曼哈顿树)+数组(用来做最小堆)
	int N=0;
	scanf("%d",&N);
	int i,j;
	char str[100]={'\\0'},str2[100];
	MinHeap H=Creat(MaxSize);
	HuffmanTree T;
	for(i=1,j=0;i<=N;i++,j++)
	{
		getchar();
		scanf("%c %d",&H->Data[i],&H->Weight[i]);
		H->size++;
	}
	Initialize(H);
	T=Huffman(H);
	Encode(T,0,str);

	scanf("%s",str2);
	Decoded(T,str2);
	return 0;
}
posted @ 2021-05-30 20:13  兔子翻书  阅读(41)  评论(0)    收藏  举报