重点树
- bst
- bbst(AVL)
- 红黑树
- 伸展树
- B树
- B+树
- B*树
- k-d树
- trie树(字典树)
- 区间树与线段树
二叉树
二叉树的操作
- 一个一般意义上的多叉树是可以转换为一个二叉树的
- 根据中序遍历+前序或后续的一个,就可以构造出一颗树
- 前序+后序 与 真二叉树 是可以还原真二叉树
- 真二叉树:每个节点的出度都是偶数,要么是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;
}