0


数据结构之树操作

 本文打出了大部分树的操作 和部分知识点   还有自己编写的哈夫曼树中的select函数(看书上是直接调用便自己打出了自己理解的select函数,有错请在评论区指出)

后续会补充栈,队列,线性表操作总结。

       //二叉树树的存储结构
typedef struct BeTnode{
    char data;
    struct BeTnode*left,*right;
}BeTnode,*BeTree;       
        //        建立先序二叉树   要正好返回 
        BeTree jianlierchashu (BeTree t)
        {
            char ch;
            scanf("%c",&ch);
            if(ch=='#')
            {
                return ;
            }
            if(ch!='#')
            {
                t=(BeTree) malloc (sizeof(BeTnode));
                t->data=ch;
                t->left=NULL;
                t->right=NULL;
                jianlierchashu(t->left);
                jianlierchashu(t->right);
                return t;
            } 
                
        }
         
         //     求二叉树叶子节点的个数
int yezijiediangeshu(BeTree t)
{
    if(t==NULL)
    {
        return 0;
    }
    if(t->left==NULL&&t->right==NULL)
    {
        return 1;
    }
    int n=0,m=0;
    n=yezijiediangeshu(t->left);
    m=yezijiediangeshu(t->right);
    return m+n ;
         }         
         
//          求二叉树节点个数
int  jiediangeshu(BeTree t) 
{
        if(t==NULL)
        {
            return 0;
        }
        int n=0,m=0;
    n=jiediangeshu(t->left);//0 1
    m=jiediangeshu(t->right);//0 
    return 1+n+m;//1
}

 
              //二叉树树的深度
int shendu(BeTree t)
{
    if(t==NULL)
    return 0;
    int n=0,m=0;
    n=shendu(t->left);        
    m=shendu(t->right);
    return n>m?n+1:m+1; 
}    

           
//      中序线索二叉树 
/*
       主要是添加两个标识域
ltage=    1-则左指针域前驱       0-则左指针域左孩子     
rtage=    1-则右指针域后驱       0-则右指针域右孩子 
              物理存储结构 
*/ 
typedef struct TNode{
    char data;
    struct TNode *left;
    struct TNode *right;
    int ltage;
    int rtage;
}TNode,*BTNode; 
    void xiansuoerchashu(BTNode t)
    {
        BTNode pro=NULL;
        if(t)
        {
        xiansuoerchashu(t->left);     //因为为中序所以  要从左开始  递归调用到最左   返回
        if(t->left==NULL)
        {
        t->ltage=1;//设置标记 
        t->left=pro;    //pro为前驱    全局变量    初始值为NULL 
        } 
         else
         t->ltage=0;
         if(pro->right==NULL)    //这里为什么是pro那?因为现在操作的是t   只有t和pro的地址   所以要填充pro的右指针域 
         {
             pro->rtage=1;
             pro->right=t;
          }
          else
          pro->rtage=0; 
          pro=p;       //因为当前节点的操作完成了   所以将其赋值    递归右子树 
          xiansuoerchashu(t->right);
        }
        
         
     } 

           //树的存储 -1   双亲表示法 
    typedef struct PTNode{
        char data;
        int parent;//  双亲位置域 
    }PTNode;      //节点
    //树结构
    # define MAXSIZE 100
    typedef struct {
        PTNode node[MAXSIZE];//创建数组   可以存放MAXSIZE个节点     
        int r,n; //根节点位置个数 
    }PTree;      
    
    
    
    
       
        //树的存储 -2  孩子表示法       
    //孩子节点结构的定义     
typedef struct CTNode{
    int child;  //    int 类型    为该孩子在数组中的下标 
    struct CTNode* nexthaizi;        // 双亲节点的下一个孩子 
}*childptr;         
    //双亲节点结构
    typedef struct          
         {
             char data;
             childptr firstchild;      //孩子链表的头指针 
         }CTBox;
    //树结构
    typedef struct {
            CTBox node[MAXSIZE];
            int r,n;     //根节点的位置和节点数 
    }CTree;
     //方便找孩子  不方便找双亲    则添加一个双亲节点 
    typedef struct          
         {
             char data;
             int   pro; 
             childptr firstchild;      //孩子链表的头指针 
         }CTBox;
         //带双亲的孩子链表 
         
         
         
         //树的存储 -3   二叉链表表示法       
         /*
         左指针域    ---第一个孩子结点
         右指针域    ---向右一个  兄弟结点 
         找双亲比较困难 
         */
         typedef struct CTNode{
             char data;
             struct CTNode * lefthaizi;
                 struct CTNode *rightxdi; 
         }CTNode;
         
         
         
         
         
         
         
         //哈夫曼树
          // 结点结构     
    typedef struct Hafuman  //顺序存储  ---     1维结构数组 
    {
        //权值
        //双亲  左孩子右孩子下标
        int weight;
        int parent,left,right; 
   }Hafuman,*THafuman; //---是动态数组存储一个哈夫曼树

    //建立哈夫曼树(最优二叉树)   
    
    /*
    权值越大越靠近根
    所以找权值要从小到大  从下到上进行构造哈夫曼树 
    每个权值都是根    权值实际也是叶子节点 
    而且不唯一,因为没有限定左右子树,并且有权值重复时,可能树的高度都不唯一,唯一的只是带权路径长度之和最小。
    
    
            王卓老师的口诀 
     构造森林全是根   选用二小造新树
     删除二小添新人   重复2,3剩单根 
    */
   void creatHfm(THafuman t,int n)    //   t是哈夫曼树      n是 有权值的个数(叶子节点)    需要合并n-1次   
   {
       if(n<=1)
       return ;
/*
1.    建数组 for循环初始化  3个域均为0 
2.    选出无双亲 中权值最小的两个  组成新的二叉树
3.    组成后    权值最小的两个  消失(有双亲) 
*/        
    int m=2*n-1;
       t=(THafuman) malloc(sizeof(Hafuman)*(1+m));    //从1开始使用
    for(int i=1;i<m+1;i++)
    {
        t[i].left=0;
        t[i].parent=0;
        t[i].right=0;
    }   
    for(int i=1;i<n+1;i++)
    {
        scanf("%d",&t[i].weight);
    }    
       //-----------------------------------------------------------
  //因为要    选出无双亲 中权值最小的两个  组成新的二叉树   所以要自定义函数胡
 int s1,s2;
 
  for(i=n+1;i<m+1;i++)
  {
     select(t,&s1,&s2,i);  
          t[i].weight=s1+s2;
    t[i].right=s1;
    t[i].left=s2;           
  }     
       
       
    } 
    
    
    int cmp(int *x, int *y) {
    return *x - *y;
}
  void select(THafuman *t,int &s1,int &s2,int n)    //s1,s2是需要返回的值 
  {
      int m=sizeof(t)/sizeof(Hafuman);
    THafuman a[m];//指针数组 
      int j=0;
      
    for(int i=1;i<m;i++)
    {
    if(t[i].parent==0)
    {
     a[j]=t[i];    
        j++;
    }
    }   int i=0;
      qsort(a,j,sizeof(Hafuman),cmp);
      for(i=0;i<m;i++)
      {    int p=0;
           if(a[0]==t[i]||a[1]==t[i])
           {
                      p++;
                   t[i].parent=n;
                   if(p==1)
                *s1=i;  
                   else
                   *s2=i;
           }     
    }
  
          }        
//哈夫曼编码
//算概率大  则权大     则要靠近根
//左分支标记为0,右分支标记为1进行编码     
/*
从根到叶子进行编码 
*/         
         
         
         
         
         
         
         
         
         
         
         
                                      本篇文章主要是树的操作
标签: 数据结构 c语言

本文转载自: https://blog.csdn.net/m0_61469860/article/details/124377897
版权归原作者 &volume 所有, 如有侵权,请联系我们删除。

“数据结构之树操作”的评论:

还没有评论