数据结构 - 二叉树的建立 遍历高度 哈夫曼树的建立 译码 编码

本周学习了数据结构中的树现在对此进行一些总结

首先进行树的创建

树的定义

树是一种非常重要的非线性数据结构,可用来描述客观世界中广泛存在的具有分支或层次关系的对象。

树的建立

tree* creatTree() { 
//ABC##DE#G##F###  
    tree* p;
    char value;
    scanf("%c", &value);
    if (value != '#') {
        p = (tree*)malloc(sizeof(struct tree));
        p->data = value;
        p->lchild = creatTree();
        p->rchild = creatTree();
    } else {
        p = NULL;
    }
    return p;
}

建立一颗如图所示的树

树的遍历

先序遍历

void preOrder (tree * root){
    if(root) {
        printf("%c",root->data);
        preOrder(root->lchild); 
        preOrder(root->rchild); 
    } 
} 

中序遍历

void preOrder1 (tree * root){
    if(root) {
       
        preOrder1(root->lchild); 
        printf("%c",root->data);
        preOrder1(root->rchild); 
    } 
} 

后序遍历

void preOrder1 (tree * root){
    if(root) {
       
        preOrder1(root->lchild); 
        preOrder1(root->rchild); 
        printf("%c",root->data);
    } 
} 

树的最大高度

int treeHeight(tree* t) {
    if(t == NULL)
        return 0;
    if(t->lchild == NULL && t->rchild == NULL)
        return 1;
    return max(treeHeight(t->lchild),treeHeight(t->rchild))+1;
}

树的非叶子结点的遍历

int leaves(tree *t) {
    int count = 0;
    if (t == NULL) {
        return 0;
    }
    if (t -> lchild != NULL || t -> rchild != NULL) {
        count = leaves(t -> lchild);
        count += leaves(t -> rchild);
        count++;
    }
    return count;
}

先序和中序遍历唯一的二叉树

tree * creatTT (int l,int r,int inl,int inr) {
 	if(l>r)
 	return NULL;
 	
 	tree* root = (tree*)malloc(sizeof(struct tree));
 	root->data = b[r];
 	int i ;
 	for(i = inl; i <= inr; i++ ) {
 		if (a[i] == b[r])
 		break;
	 }
	 int numleft = i - inl;
	 root->lchild = creatTT(l + 1, l + numleft, inl,i - 1);
	 root->rchild = creatTT (l + numleft + 1,r, i+1,inr);
	 return root;
 }

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct  tree {
    char data;
    struct tree* lchild, *rchild;
};
char a[100];
char b[100];
tree* creatTree() { 
//  char ch;
//  struct tree *t; 
////    tree *t = (tree*)malloc(sizeof(struct tree));
//  scanf("%c",ch);
//  if(ch == '#') {
//  t = NULL;
//  } else {
//      t = (tree*)malloc(sizeof(struct tree));
//      t->data =ch;
//      t->lchild = creatTree();
//      t->rchild = creatTree();
//  }
//  return t;
//ABC##DE#G##F###  
    tree* p;
    char value;
    scanf("%c", &value);
    if (value != '#') {
        p = (tree*)malloc(sizeof(struct tree));
        p->data = value;
        p->lchild = creatTree();
        p->rchild = creatTree();
    } else {
        p = NULL;
    }
    return p;
}
void preOrder (tree * root){
    if(root) {
        printf("%c",root->data);
        preOrder(root->lchild); 
        preOrder(root->rchild); 
    } 
} 
void preOrder1 (tree * root){
    if(root) {
      
        preOrder1(root->lchild); 
        printf("%c",root->data);
        preOrder1(root->rchild); 
    } 
} 
void preOrder2 (tree * root){
    if(root) {
        preOrder2(root->lchild); 
        preOrder2(root->rchild);
        printf("%c",root->data); 
    } 
} 
void leverolTraverse (tree* t) {
    tree * arr[100];
    int front = -1,rear = -1;
    if (t != NULL) {
        arr[++rear] = t;
        while(front < rear) {
            t = arr[++front];
            printf("%c",t->data);
            if (t->lchild != NULL) {
                arr[++rear] = t->lchild;
            }
            if(t->rchild != NULL) {
                arr[++rear] = t->rchild;
        }   
        }
    }
    
}
 tree * creatT (int l,int r,int inl,int inr) {
 	if(l>r)
 	return NULL;
 	
 	tree* root = (tree*)malloc(sizeof(struct tree));
 	root->data = a[l];
 	int i ;
 	for(i = inl; i <= inr; i++ ) {
 		if (b[i] == a[l])
 		break;
	 }
	 int numleft = i - inl;
	 root->lchild = creatT(l + 1, l + numleft, inl,i - 1);
	 root->rchild = creatT (l + numleft + 1,r, i+1,inr);
	 return root; 
 }
 tree * creatTT (int l,int r,int inl,int inr) {
 	if(l>r)
 	return NULL;
 	
 	tree* root = (tree*)malloc(sizeof(struct tree));
 	root->data = b[r];
 	int i ;
 	for(i = inl; i <= inr; i++ ) {
 		if (a[i] == b[r])
 		break;
	 }
	 int numleft = i - inl;
	 root->lchild = creatTT(l + 1, l + numleft, inl,i - 1);
	 root->rchild = creatTT (l + numleft + 1,r, i+1,inr);
	 return root;
 }
 
  
int main(void) {
    struct tree * t;
    scanf("%s",a);
    scanf("%s",b);
    int  n = strlen(a);
    t = creatTT(0,n-1,0,n-1);
   // t = creatTT(n);
    //leverolTraverse(t);
   // ABC##DE#G##F###
    preOrder(t);
   // printf("\n");
   // preOrder1(t);
   // printf("\n");
   //	 preOrder2(t);
 }

哈夫曼树的建立

void CrtHuffmanTree(HuffmanTree ht,int w[],int n){
    int i,s1,s2,m;
    m=2*n-1;
    for(i=0;i<n;i++){
        ht[i].weight=w[i];ht[i].parent=-1;
        ht[i].lchild=-1;ht[i].rchild=-1;
    }
    for(i=n;i<m;i++){
        ht[i].weight=0;ht[i].parent=-1;
        ht[i].lchild=-1;ht[i].rchild=-1;
    }
    /*选择 合并*/
    for(i=n;i<m;i++) {
        select(ht,i-1,&s1,&s2);
        ht[i].weight=ht[s1].weight+ht[s2].weight;
        ht[s1].parent=i;
        ht[s2].parent=i;
        ht[i].lchild=s1;
        ht[i].rchild=s2;
    }
}
void select(HuffmanTree ht,int pos,int *s1,int *s2){
    int i,j,m1,m2;/*m1存放最小权值,s1是m1在数组的下标*/
    m1=m2=MAXINT;/*m2存放次小权值,s2是m2在数组的下标*/ 
    for(j=0;j<=pos;j++) {
        if(ht[j].weight<m1&&ht[j].parent==-1){
            m2=m1;*s2=*s1;
            *s1=j;m1=ht[j].weight;
        }
        else if(ht[j].weight<m2&&ht[j].parent==-1){
            m2=ht[j].weight;
            *s2=j;
        }
    }
    /*if(*s1>*s2){//使s1小于s2
        i=*s1;*s1=*s2;*s2=i;        
    }*/
}

编码
void  numtochar(numcode ns,HuffmanTree ht,char s[]){
    char *p=ns;int key;HTNode g;
    while(*p!='\0'){
        g=ht[M-1];
        //printf("\nht[M-1]=%d\n",g.weight);                
        while(g.lchild!=-1&&g.rchild!=-1&&(*p!='\0')){
            switch(*p){              
            case '0':key=g.lchild;g=ht[g.lchild];break;
            case '1':key=g.rchild;g=ht[g.rchild];break;
            }
            p++;
            //printf("P++=%c\n",*p);
        }
        printf("%c",s[key]);


    }
}

译码

void chartocode(charcode c,char s[],HuffmanCode hc){
    char *p=c;  
    while(*p!='\0'){    
        for(int j=0;j<N;j++){
            if(*p==s[j])
                printf("%s",hc[j]);
        }
        p++;
    }
    printf("\n");   
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 6
#define M 2*N-1
#define MAXINT 32767
#define ch 30
#define NUM 100
typedef char numcode[NUM];
typedef char charcode[ch];
typedef char* HuffmanCode[N] ;
typedef struct{
    int weight;
    int parent;
    int lchild;
    int rchild; 
}HTNode,HuffmanTree[M]; 



void select(HuffmanTree ht,int pos,int *s1,int *s2);

void CrtHuffmanTree(HuffmanTree ht,int w[],int n){
    int i,s1,s2,m;
    m=2*n-1;
    for(i=0;i<n;i++){
        ht[i].weight=w[i];ht[i].parent=-1;
        ht[i].lchild=-1;ht[i].rchild=-1;
    }
    for(i=n;i<m;i++){
        ht[i].weight=0;ht[i].parent=-1;
        ht[i].lchild=-1;ht[i].rchild=-1;
    }
    /*选择 合并*/
    for(i=n;i<m;i++) {
        select(ht,i-1,&s1,&s2);
        ht[i].weight=ht[s1].weight+ht[s2].weight;
        ht[s1].parent=i;
        ht[s2].parent=i;
        ht[i].lchild=s1;
        ht[i].rchild=s2;
    }
}
void select(HuffmanTree ht,int pos,int *s1,int *s2){
    int i,j,m1,m2;/*m1存放最小权值,s1是m1在数组的下标*/
    m1=m2=MAXINT;/*m2存放次小权值,s2是m2在数组的下标*/ 
    for(j=0;j<=pos;j++) {
        if(ht[j].weight<m1&&ht[j].parent==-1){
            m2=m1;*s2=*s1;
            *s1=j;m1=ht[j].weight;
        }
        else if(ht[j].weight<m2&&ht[j].parent==-1){
            m2=ht[j].weight;
            *s2=j;
        }
    }
    /*if(*s1>*s2){//使s1小于s2
        i=*s1;*s1=*s2;*s2=i;        
    }*/
}

void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n){
    char *cd;int start,c,p,i;
    cd=(char*)malloc(n*sizeof(char));
    cd[n-1]='\0';   
    for(i=0;i<n;i++){
        start=n-1;c=i;
        p=ht[i].parent;
        while(p!=-1){
            --start;
            if(ht[p].lchild==c) cd[start]='0';
            else    cd[start]='1';
            c=p;p=ht[p].parent;
        }
        hc[i]=(char*)malloc((n-start)*sizeof(char));        
        //printf("%s\n",&cd[start]);
        strcpy(hc[i],&cd[start]);

    }
    free(cd);
}

void printcode(char s[],HuffmanCode hc){
    //printf("\n----%s----\n",hc[0]);
    for(int i=0;i<N;i++){
        printf("%c:",s[i]);
        printf("%s\n",hc[i]);

    }
}
void chartocode(charcode c,char s[],HuffmanCode hc){
    char *p=c;  
    while(*p!='\0'){    
        for(int j=0;j<N;j++){
            if(*p==s[j])
                printf("%s",hc[j]);
        }
        p++;
    }
    printf("\n");   
}
void  numtochar(numcode ns,HuffmanTree ht,char s[]){
    char *p=ns;int key;HTNode g;
    while(*p!='\0'){
        g=ht[M-1];
        //printf("\nht[M-1]=%d\n",g.weight);                
        while(g.lchild!=-1&&g.rchild!=-1&&(*p!='\0')){
            switch(*p){              
            case '0':key=g.lchild;g=ht[g.lchild];break;
            case '1':key=g.rchild;g=ht[g.rchild];break;
            }
            p++;
            //printf("P++=%c\n",*p);
        }
        printf("%c",s[key]);


    }
}
int main(){ 
    HuffmanTree ht;HuffmanCode hc;charcode c;numcode ns;
    char s[N]={'A','B','C','D','E','F'};
    int  w[N];

    for(int i=0;i<N;i++){
        scanf("%d",&w[i]) ;
    } 
    scanf("%s",&c);
    scanf("%s",&ns);
//  printf("\n") ;
//  for(int i=0;i<N;i++){
//      printf("%d",w[i]) ;
//  } 
//  printf("\n") ;

    CrtHuffmanTree(ht,w,6);


    CrtHuffmanCode(ht,hc,6);
    printcode(s,hc);
    chartocode(c,s,hc); 

    numtochar(ns,ht,s);
}
发布了34 篇原创文章 · 获赞 4 · 访问量 723

猜你喜欢

转载自blog.csdn.net/weixin_44824650/article/details/103104343