广工anyview数据结构-09~10(乱码不贴)

这篇博客介绍了如何在不同的数据结构表示的树中计算节点的度和树的深度。提供了针对孩子兄弟链表、双亲表示法、双亲孩子链表表示的树的深度计算算法。此外,还涵盖了如何构造孩子兄弟链表树、并查集查找操作的非递归实现、有向图邻接数组存储结构的创建以及邻接表存储结构的相关操作,如顶点出度和入度的计算。
摘要由CSDN通过智能技术生成
/**********
【题目】试编写算法,对一棵以孩子兄弟链表表示
的树统计叶子的个数。
孩子兄弟链表类型定义:
typedef struct CSTNode {
  TElemType  data;
  struct CSTNode  *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int Leave(CSTree T) /* 统计树T的叶子数 */
{
  int count=0;
  if(!T) return 0;
  if(!T->firstChild) count=1;
  if(T->firstChild) count+=Leave(T->firstChild);
  if(T->nextSibling) count+=Leave(T->nextSibling);
  return count;

}




/**********
【题目】试编写算法,求一棵以孩子兄弟链表表示的树的度。
孩子兄弟链表类型定义:
typedef struct CSTNode {
  TElemType  data;
  struct CSTNode  *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/


void CountDegree(CSTree T,int &count,int &max)
{
 int ChildCount=1;
 if(T->nextSibling) 
  {
   count++;
   CountDegree(T->nextSibling,count,max);
   if(count>max) max=count;
  }
 if(T->firstChild)
 {
   CountDegree(T->firstChild,ChildCount,max);
   if(ChildCount>max) max=ChildCount;
 }
 
}


int Degree(CSTree T) /* 求树T的度 */
{
 int count=1,max=1;
 if(!T) return 0;
 CountDegree(T,count,max);
 return max;
}




/**********
【题目】试编写算法,对以双亲表示法存储的树计算深度。
typedef struct {
  TElemType data;
  int     parent;  // 双亲位置
} PTNode; // 结点类型
typedef struct {
  PTNode nodes[MAX_TREE_SIZE]; // 结点存储空间
  int  n, r; // 结点数和根的位置
} PTree;
**********/
int PTreeDepth(PTree T) /* 求树T的深度 */
{
 int MaxDepth=1,CurDepth=0,i;
 PTNode temp;
 for(i=1;i<=T.n-1;i++)
  {
    CurDepth=1;
    temp=T.nodes[i];
    while(temp.parent!=T.r)
      {
        CurDepth++;
        temp=T.nodes[temp.parent];
      }
    if(CurDepth+1>MaxDepth) MaxDepth=CurDepth+1;
  }
  return MaxDepth; 
}





/**********
【题目】试编写算法,对以双亲孩子表示法存储的树计算深度。
孩子链表类型定义:
typedef struct ChildNode {  // 孩子结点
  int childIndex;
  struct ChildNode *nextChild;
} ChildNode; // 孩子结点类型
typedef struct  {
  TElemType data;
  int     parent;  // 双亲位置
  struct ChildNode *firstChild; // 孩子链表头指针
} PCTreeNode; // 结点类型
typedef struct {
  PCTreeNode *nodes; // 结点存储空间
  int  n, r; // 结点数和根的位置
} PCTree;
**********/
int PCTreeDepth(PCTree T) /* 求树T的深度 */
{
    int max=0,dep,m;
    int i;
    int Index;
    ChildNode *child,*childc;
    if(!T.nodes[T.r].firstChild)return 1;
    for(childc=T.nodes[T.r].firstChild;childc;childc=childc->nextChild){
        dep = 1;
        Index=childc->childIndex;
        child=childc;
        while(child){            
            child=T.nodes[Index].firstChild;
            Index=child->childIndex;
            dep++;
        }
        if(max<dep) max = dep;
    }
    return max;
}






/**********
【题目】试编写算法,对以孩子-兄弟链表表示的树计算深度。
孩子兄弟链表类型定义:
typedef struct CSTNode {
  TElemType  data;
  struct CSTNode  *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int TreeDepth(CSTree T)
/* 求树T的深度 */
{
   int maxd=0,d;
   CSTree p;
   if(!T)return 0;
   if(!T->firstChild)return 1;
   for(p=T->firstChild;p;p=p->nextSibling){
     d=TreeDepth(p);
     if(d>maxd)maxd=d;
   }
   return maxd+1;
}




/**********
【题目】已知一棵树的由根至叶子结点按层次输出的
结点序列及每个结点的度。试编写算法,构造此树的
孩子兄弟链表。
孩子兄弟链表类型定义:
typedef struct CSTNode {
  TElemType  data;
  struct CSTNode  *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
CSTNode* searchTree(CSTree T,char x)
/* 在树T中查找x */
{
    CSTree temp1,temp2;
    if(T==NULL)return NULL;
    if(T->data==x)return T;
    else
    {
       temp1=searchTree(T->firstChild,x);
       temp2=searchTree(T->nextSibling,x);
       if(temp1!=NULL)
            return temp1;
       else if(temp2!=NULL)
            return temp2;
       else 
            return NULL;
    }
}


void BuildCSTree(CSTree &T, char *node, int *degree)
/* 由结点的层序序列node和各结点的度degree构造树的孩子兄弟链表T */
{  
  int child=0,index=1,i=0,k=0;
  CSTNode *p,*q,*temp;
  
  q=(CSTNode *)malloc(sizeof(CSTNode));
  q->firstChild=NULL;
  q->nextSibling=NULL;
  q->data=node[0];
  T=q;
  temp=q;
  while(node[i]!='\0')
  {   
        q=temp;       
        child=degree[i];    
        for(int j=0;j<child;j++)
        {
            p=(CSTNode *)malloc(sizeof(CSTNode));
            p->firstChild=NULL;
            p->nextSibling=NULL;
            p->data=node[index++];
            if(j==0)
            {
                q->firstChild=p;
                q=q->firstChild;
            }
            else
            {
                q->nextSibling=p;
                q=q->nextSibling;
            }
        }
        i++; 
        temp=searchTree(T,node[i]);
        if(temp==NULL)break;
  }
}





/**********
【题目】试编写非递归算法,实现并查集带路径压缩的
查找操作。
并查集的类型定义如下:
typedef struct {
  int *parent;
  int  n;
} MFSet;
**********/
int find(MFSet S, int i) 
/* 并查集带路径压缩的查找的非递归实现 */
{
    int k, j, r;
    r = i;
    while(S.parent[r]>=0)     //查找根节点
        r = S.parent[r];      //找到根节点,用r记录下
    k = i;
    while(k != r)             //非递归路径压缩操作
    {
        j = S.parent[k];         //用j暂存parent[k]的父节点
        S.parent[k] = r;        //parent[x]指向根节点
        k = j;                    //k移到父节点
    }
    return r;         //返回根节点的值    
}




/**********
【题目】编写算法,创建有向图的邻接数组存储结构。
//图的邻接数组存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define MAX_VEX_NUM  4
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef int VRType;
typedef char InfoType;
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct {
    VRType adj; // 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否;
                // 对带权图,则为权值类型
    InfoType *info; // 该弧相关信息的指针(可无)
}ArcCell;//,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
  ArcCell arcs[MAX_VEX_NUM][MAX_VEX_NUM]; // 关系数组,对无权图,用0或1表示相邻否,
              // 对带权图,则为权值或INFINITY
  VexType vexs[MAX_VEX_NUM]; // 顶点数组
  int n, e;   // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
  //int *tags;  // 标志数组,可用于在图的遍历中标记顶点访问与否
} MGraph; // 邻接数组类型
typedef struct {
  VexType v, w;
  int inf;
} ArcInfo;
可调用以下基本操作:
Status InitGraph(MGraph &G, GraphKind kind, int n);
  // 初始化含n个顶点空间的kind类的空图G
int LocateVex(MGraph G, VexType v); // 查找顶点v在图G中的位序
**********/
Status CreateDG(MGraph &G, VexType *vexs, int n, 
                           ArcInfo *arcs, int e)
/* 创建含n个顶点和e条边的有向图G,vexs为顶点信息,arcs为边信息 */
{
    InitGraph(G,DG,n);
    G.n=n;
    int k1,k2;
    for(int i=0;i<n;i++){
        G.vexs[i]=vexs[i];
    }
    G.e=e;
    
    for(i=0;i<e;i++){
        k1=LocateVex(G,arcs[i].v);
        k2=LocateVex(G,arcs[i].w);
        G.arcs[k1][k2].adj=1;
    }
}




/**********
【题目】编写算法,在图G中,相对于k顶点的当前
邻接顶点m顶点,求下一个邻接顶点。
图的邻接数组存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define MAX_VEX_NUM  4
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef int VRType;
typedef char InfoType;
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct {
    VRType adj; // 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否;
                // 对带权图,则为权值类型
    InfoType *info; // 该弧相关信息的指针(可无)
}ArcCell;//,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
  ArcCell arcs[MAX_VEX_NUM][MAX_VEX_NUM]; // 关系数组
  VexType vexs[MAX_VEX_NUM]; // 顶点数组
  int n, e;   // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
} MGraph; // 邻接数组类型
**********/
int NextAdjVex(MGraph G, int k, int m)
/* 在图G中,相对于k顶点的当前邻接顶点m顶点,求下一个邻接顶点 */
{
  int i;
  if(G.n==0&&k==0&&m==0) return 0;
  for(i=m+1;i<G.n;i++)
        if(G.arcs[k][i].adj!=0)
            return i;


  return -1;
}





/**********
【题目】编写算法,在图G中置顶点v到顶点w的弧或边。
图的邻接数组存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define MAX_VEX_NUM  4
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef int VRType;
typedef char InfoType;
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct {
    VRType adj; // 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否;
                // 对带权图,则为权值类型
    InfoType *info; // 该弧相关信息的指针(可无)
}ArcCell;//,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
  ArcCell arcs[MAX_VEX_NUM][MAX_VEX_NUM]; // 关系数组
  VexType vexs[MAX_VEX_NUM]; // 顶点数组
  int n, e;   // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
} MGraph; // 邻接数组类型
可调用以下基本操作:
int LocateVex(MGraph G, VexType v); // 查找顶点v在图G中的位序
**********/
Status SetArc(MGraph &G, VexType v, VexType w, ArcCell info)
/* 在图G中置顶点v到顶点w的弧或边 */
{
    int i,j,k;
    VRType *p;    
    i=LocateVex(G,v);
    j=LocateVex(G,w);    
    if(i<0||j<0||v==w) return ERROR;
    else if(G.arcs[i][j].adj!=info.adj){
     G.e++;
     G.arcs[i][j]=info;
    } 
    return OK;      


}





/**********
【题目】编写算法,计算以邻接表方式存储的有向图G中k顶点的出度。
图的邻接表存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct AdjVexNode {
  int adjvex;  // 邻接顶点在顶点数组中的位序
  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)
  int info;    // 存储边(弧)相关信息,对于非带权图可不用
} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型
typedef struct VexNode {
  VexType data;    // 顶点值,VexType是顶点类型,由用户定义
  struct AdjVexNode *firstArc; // 邻接链表的头指针
} VexNode; // 顶点数组的元素类型
typedef struct {
  VexNode *vexs;  // 顶点数组,用于存储顶点信息
  int n, e;       // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
  int *tags;      // 标志数组
} ALGraph;  // 邻接表类型
**********/
int outDegree(ALGraph G, int k) 
/* 求有向图G中k顶点的出度。若k顶点不存在,则返回-1 */
{
   int i,outD=0,j;
   AdjVexNode *p;
   if(k<0||k>=G.n) return -1;
   p=G.vexs[k].firstArc;
   while(p!=NULL){
      outD++;
      p=p->next;
   }
   
  return outD;
   
}





/**********
【题目】编写算法,计算以邻接表方式存储的有向图G中
k顶点的入度。
图的邻接表存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct AdjVexNode {
  int adjvex;  // 邻接顶点在顶点数组中的位序
  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)
  int info;    // 存储边(弧)相关信息,对于非带权图可不用
} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型
typedef struct VexNode {
  VexType data;    // 顶点值,VexType是顶点类型,由用户定义
  struct AdjVexNode *firstArc; // 邻接链表的头指针
} VexNode; // 顶点数组的元素类型
typedef struct {
  VexNode *vexs;  // 顶点数组,用于存储顶点信息
  int n, e;       // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
  int *tags;      // 标志数组
} ALGraph;  // 邻接表类型
**********/
int inDegree(ALGraph G, int k)
/* 求有向图G中k顶点的入度。若k顶点不存在,则返回-1 */
{
   AdjVexNode *p;
   if(k<0||k>G.n) return -1;
   int degree[20];
   int i;
    for(i=0;i<G.n;i++){
        degree[i]=0;
    }
    for(i=0;i<G.n;i++){
       while(G.vexs[i].firstArc){
         degree[G.vexs[i].firstArc->adjvex]++;
         G.vexs[i].firstArc=G.vexs[i].firstArc->next;
        }
    }
   return degree[k];
}






/**********
【题目】编写算法,创建有向图的邻接表存储结构。
图的邻接表存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define MAX_VEX_NUM  4
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct AdjVexNode {
  int adjvex;  // 邻接顶点在顶点数组中的位序
  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)
  int info;    // 存储边(弧)相关信息,对于非带权图可不用
} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型
typedef struct VexNode {
  VexType data;    // 顶点值,VexType是顶点类型,由用户定义
  struct AdjVexNode *firstArc; // 邻接链表的头指针
} VexNode; // 顶点数组的元素类型
typedef struct {
  VexNode vexs[MAX_VEX_NUM];  // 顶点数组,用于存储顶点信息
  int n, e;       // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
  int *tags;      // 标志数组
} ALGraph;  // 邻接表类型
 
可调用以下基本操作:
int LocateVex(ALGraph G, VexType v); // 查找顶点v在图G中的位序
**********/
Status CreateDG(ALGraph &G, VexType *vexs, int n,
                            ArcInfo *arcs, int e)
/* 创建含n个顶点和e条边的有向图G,vexs为顶点信息,arcs为边信息 */
{
   int i,j,k;
   VexType v,w;
   AdjVexNodeP p;
   G.n=n;G.e=e;
  // G.vexs=(VexNode*)malloc(sizeof(VexNode)*n);
   G.tags=(int*)malloc(sizeof(int)*n);
   for(i=0;i<G.n;i++)
     {  G.tags[i]=UNVISITED;
        G.vexs[i].data=vexs[i];
        G.vexs[i].firstArc=NULL;
     }
    for(k=0;k<G.e;k++)
      {  v=arcs[k].v;w=arcs[k].w;
         i=LocateVex(G,v);j=LocateVex(G,w);
         if(i<0||j<0) return ERROR;
         p=(AdjVexNode*)malloc(sizeof(AdjVexNode));
         if(NULL==p)  return OVERFLOW;
         p->adjvex=j;
         p->next=G.vexs[i].firstArc;
         G.vexs[i].firstArc=p;
      }
      return OK;   
}






/**********
【题目】编写算法,创建无向图的邻接表存储结构。
图的邻接表存储结构的类型定义如下:
#define UNVISITED  0
#define VISITED    1  
#define MAX_VEX_NUM  4
#define INFINITY MAXINT // 计算机允许的整数最大值,即∞
typedef char VexType;
typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网
typedef struct AdjVexNode {
  int adjvex;  // 邻接顶点在顶点数组中的位序
  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)
  int info;    // 存储边(弧)相关信息,对于非带权图可不用
} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型
typedef struct VexNode {
  VexType data;    // 顶点值,VexType是顶点类型,由用户定义
  struct AdjVexNode *firstArc; // 邻接链表的头指针
} VexNode; // 顶点数组的元素类型
typedef struct {
  VexNode vexs[MAX_VEX_NUM]; //*vexs; 顶点数组,用于存储顶点信息
  int n, e;       // 顶点数和边(弧)数
  GraphKind kind; // 图的类型
  int *tags;      // 标志数组
} ALGraph;  // 邻接表类型
 
可调用以下基本操作:
int LocateVex(ALGraph G, VexType v); // 查找顶点v在图G中的位序
**********/
Status CreateUDG(ALGraph &G, VexType *vexs, int n,
                            ArcInfo *arcs, int e)
/* 创建含n个顶点和e条边的无向图G,vexs为顶点信息,arcs为边信息 */
{
    int i,j,k;
    VexType v,w;
    AdjVexNode *p;
    G.n=n;G.e=e;
    G.kind=UDG; 
    for(i=0;i<G.n;i++){
        G.tags[i]=0;
        G.vexs[i].data= vexs[i];
        G.vexs[i].firstArc=NULL;        
    }
    for(k=0;k<G.e;k++){
        v=arcs[k].v;
        w=arcs[k].w;
        i=LocateVex(G,v);
        j=LocateVex(G,w);
        if(i<0||j<0) return ERROR;
        p=(AdjVexNode*)malloc(sizeof(AdjVexNode));
        p->adjvex=j;
        p->next=G.vexs[i].firstArc;
        G.vexs[i].firstArc=p;
        
        p=(AdjVexNode*)malloc(sizeof(AdjVexNode));
        p->adjvex=i;
        p->next=G.vexs[j].firstArc;
        G.vexs[j].firstArc=p;
    }
    return OK;
}


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值