二叉树与哈夫曼树实验

二叉树先序构建xianxuzhongxu后续遍历求高度节点个数交换子树 

#include<stdio.h>
#include<stdlib.h>
#define Elementype int
 
//二叉树结点结构体
typedef struct btnode{
    Elementype element;
    struct btnode* lChild;
    struct btnode* rChild;
}BTNode;
//二叉树结构体
typedef struct binarytree{
    BTNode* root;
}BinaryTree;
//先序遍历
void PreOrder(BTNode* t){
    if(!t)
        return;
    printf("%c",t->element);
    PreOrder(t->lChild);
    PreOrder(t->rChild);
}
void PreOrderTree(BinaryTree* bt){
    PreOrder(bt->root);
}
//中序遍历
void MidOrder(BTNode* t){
    if(!t)
        return;
    MidOrder(t->lChild);
    printf("%c",t->element);
    MidOrder(t->rChild);
}
void MidOrderTree(BinaryTree* bt){
    MidOrder(bt->root);
}
//后序遍历
void AfterOrder(BTNode* t){
    if(!t)
        return;
    AfterOrder(t->lChild);
    AfterOrder(t->rChild);
    printf("%c",t->element);
}
void AfterOrderTree(BinaryTree* bt){
    AfterOrder(bt->root);
}
//先序创建
BTNode* PreCreateBT(BTNode* t){
    char ch;
    ch=getchar();
    if(ch=='#')
        t=NULL;
    else{
        t=(BTNode*)malloc(sizeof(BTNode));
        t->element=ch;
        t->lChild=PreCreateBT(t->lChild);
        t->rChild=PreCreateBT(t->rChild);
    }
    return t;
}
void PreMakeTree(BinaryTree* bt){
    printf("please input ch:");
    bt->root=PreCreateBT(bt->root);
}
//二叉树高度
int DepthBT(BTNode* t){
    if(t==NULL)
        return 0;
    int lh, rh;
    lh = DepthBT(t->lChild);
    rh = DepthBT(t->rChild);
    if(lh>rh)
        return lh+1;
    else
        return rh+1;
}
int DepthTree(BinaryTree* bt){
    return DepthBT(bt->root);
}
//求二叉树节点个数
int NumberBT(BTNode* t){
    if(!t)
        return 0;
    return NumberBT(t->lChild)+NumberBT(t->rChild)+1;
}
int NumberTree(BinaryTree* bt){
    return NumberBT(bt->root);
}
//交换子树
void ExchangeBT(BTNode* t){
    if(!t)
        return;
    if(t->lChild!=NULL||t->rChild!=NULL){
        int temp = t->lChild;
        t->lChild = t->rChild;
        t->rChild = temp;
        ExchangeBT(t->lChild);
        ExchangeBT(t->rChild);
    }
}
void ExchangeTree(BinaryTree* bt){
    ExchangeBT(bt->root);
}
int main(){
    BinaryTree tree;
    PreMakeTree(&tree); 
    printf("先序遍历:");
    PreOrderTree(&tree);
    printf("中序遍历:");
    MidOrderTree(&tree);
    printf("后序遍历:");
    AfterOrderTree(&tree);
    int hight=DepthTree(&tree); 
    printf("二叉树高度:%d",hight);
    int num=NumberTree(&tree);
    printf("二叉树结点个数:%d",num);
    ExchangeTree(&tree);
    printf("交换子树先序遍历:");
    PreOrderTree(&tree);
    return 0;
}

哈夫曼树

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define ElemenType int 
//有序单链表
typedef struct hfmTNode{
  int  w;//存储整形权重
  ElemenType element;
  struct Link *next;//指向直接后继元素的指针
  struct Link *lchild;
  struct Link *rchild;
}HFMTNode;


//初始化链表 
HFMTNode* InitLink(){
  HFMTNode* link = (HFMTNode*)malloc(sizeof(HFMTNode));//创建头结点 
  link->next = NULL;//头结点的next为空
  link->lchild = link->rchild = NULL;
  return link; 
}

//排序插入元素
void InsertLink(HFMTNode* link,HFMTNode* node){
  
  HFMTNode* p = link;
  HFMTNode* q = p->next;
  
  while(q && node->w>q->w)
  {
  	p=q;//记录位置 
  	q=q->next;
   }
   node->next = q;
   p->next = node;
}

//删除节点,返回被删除的节点 
HFMTNode* DelLink(HFMTNode* link,int index){
  HFMTNode *p, *s;
  int i = 0;
  p = link;
  while(i<index-1 && p->next != NULL)	//搜索指定位置前一个节点
  {
  	i++;
  	p = p->next;
  }
  if(i != index-1 || p->next == NULL)
  	printf("删除位置非法");
  s = p->next;
  p->next = s->next;
  return s;
} 
//打印有序链表
void PrintLink(HFMTNode* link){
  HFMTNode* p = link->next;
  while(p){
  	printf("(%d,%d)",p->element,p->w);
  	p = p->next;
  }
  printf("\n");
}

//打印树
void PrintTree(HFMTNode* BT){
  if (BT != NULL)
  {
      printf("%d", BT->w); //输出根结点的值
      if (BT->lchild != NULL || BT->rchild != NULL)
      {
          printf("(");
          PrintTree(BT->lchild); //输出左子树
          if (BT->rchild != NULL)
              printf(",");
          PrintTree(BT->rchild); //输出右子树
          printf(")");
      }
  }
} 

//创建哈夫曼树 
HFMTNode* CreateHuffManTree(HFMTNode* link,int n){
  	HFMTNode *del1,*del2,*p;
  	HFMTNode* node ;
  	int w_sum,i;
  	p = link;		
  	for(i=0;i<n-1;i++){
  	del1 = DelLink(p,1);//最小的元素 
  	del2 = DelLink(p,1);//第二小的元素
  	w_sum = del1->w + del2->w; //两个最小的数的和
  	
  	node = (HFMTNode*)malloc(sizeof(HFMTNode));
  	node->lchild= del1;
  	node->rchild= del2;
  	node->w = w_sum;
  	
  	InsertLink(link,node);
  	}
  	return node; 
}


//哈夫曼编码 
void getCoding(HFMTNode *tree,int len){
  if(!tree)
  return;
  static int a[20]; //定义静态数组a,保存每个叶子的编码,数组长度至少是树深度减一
  int i;
  if(!tree->lchild && !tree->rchild){//叶子节点
  	printf(" %d的哈夫曼编码为:",tree->element);
  	for(i = 0; i < len; i++)
  	printf("%d",a[i]);
  	printf("\n");
  }
  else{//访问到非叶子结点时分别向左右子树递归调用,并把分支上的0、1编码保存到数组a的对应元素中,向下深入一层时len值增1 
  	a[len] = 0;
  	getCoding(tree->lchild, len + 1);
  	a[len] = 1;
  	getCoding(tree->rchild, len + 1);
  	
  }
}
//哈夫曼解码
void DQ(int arrlen,int arr[],HFMTNode *parent){
    for (int i = 0; i < arrlen; i++){
        deCoding(parent, 0, arr[i]);
    }
}
void deCoding(HFMTNode *tree,int len,int alpha){//len=0
    static int b[20];
    if(!tree->lchild&&!tree->rchild){//叶节点break
        if(tree->element==alpha){//???
            for (int j = 0; j < len;j++){
                printf("%d", b[j]);
            }
        }
    }else{//如果是非叶节点
        b[len] = 0;
  	    deCoding(tree->lchild, len + 1,alpha);
  	    b[len] = 1;
  	    deCoding(tree->rchild, len + 1,alpha);
    }
}

int main(){
  HFMTNode* link = InitLink();//初始化链表
  HFMTNode* tree;
  int num,w,i,len,element;//长度;
  printf("输入元素个数:");
  scanf("%d",&num);getchar();
  for(i=0;i<num;i++){
  	printf("第%d个元素的字符:",i+1);
  	scanf("%d",&element);getchar();
  	printf("第%d个元素的权重:",i+1);
  	scanf("%d",&w);getchar();
  	HFMTNode* node = (HFMTNode*)malloc(sizeof(HFMTNode));;
  	node->element = element;node->w = w;
  	InsertLink(link,node);
  }
  printf("******************\n");
  tree = CreateHuffManTree(link,num);
  printf("哈夫曼树:"); 
  PrintTree(tree);printf("\n"); 
  getCoding(tree,0);
  printf("******************\n");
  printf("想要解码的字符串,输入字符个数+1:");
  scanf("%d",&len);
  int arr[len];
  printf("input string:");
  for (int i=0; i < len;i++){
    scanf("%d", &arr[i]); //一开始携程%d了
  }
  DQ(len,arr,tree);
  return 0;
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值