第七章
/**********
【题目】试编写算法,对一棵以孩子兄弟链表表示
的树统计叶子的个数。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int Leave(CSTree T) /* 统计树T的叶子数 */
{
if(!T)
return 0;
if(!T->firstChild)
return 1+Leave(T->nextSibling);
return Leave(T->firstChild)+Leave(T->nextSibling);
}
/**********
【题目】试编写算法,求一棵以孩子兄弟链表表示的树的度。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int Degree(CSTree T) /* 求树T的度 */
{
int ds,dt,d;
CSTree p;
if(!T)
return 0;
ds=0; dt=0;
for( p = T->firstChild; p ; p= p->nextSibling){
dt++;
d= Degree(p);
if(d>ds)
ds =d;
}
return ds>dt?ds:dt;
}
/**********
【题目】试编写算法,对以双亲表示法存储的树计算深度。
typedef struct {
TElemType data;
int parent; // 双亲位置
} PTNode; // 结点类型
typedef struct {
PTNode nodes[MAX_TREE_SIZE]; // 结点存储空间
int n, r; // 结点数和根的位置
} PTree;
**********/
int PTreeDepth(PTree T) /* 求树T的深度 */
{
int maxdep = 0,i,j,dep;
for(i=0; i<T.n;i++){
dep=0;
for(j =i; j>0; j=T.nodes[j].parent)
dep++;
if(dep>maxdep)
maxdep = dep;
}
return maxdep+1;
}
/**********
【题目】试编写算法,对以双亲孩子表示法存储的树计算深度。
孩子链表类型定义:
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 fun(PCTree T, int pos)
{
if(T.nodes[pos].firstChild == NULL)
return 1;
ChildNode *temp = T.nodes[pos].firstChild;
int depth = 1, max = 1;
while(temp != NULL) {
if( T.nodes[temp->childIndex].firstChild != NULL){
depth = fun(T, temp->childIndex);
if(depth > max)
max = depth;
}
temp = temp->nextChild;
}
return max + 1;
}
int PCTreeDepth(PCTree T) /* 求树T的深度*/
{
int depth;
depth = fun(T, T.r);
return depth;
}
/**********
【题目】试编写算法,对以孩子-兄弟链表表示的树计算深度。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int TreeDepth(CSTree T)
/* 求树T的深度 */
{
int dep1,dep2,dep;
if(!T)
dep = 0;
else{
dep1 = TreeDepth(T->firstChild);
dep2 = TreeDepth(T->nextSibling);
dep = dep1+1>dep2?dep1+1:dep2;
}
return dep;
}
/**********
【题目】已知一棵树的由根至叶子结点按层次输出的
结点序列及每个结点的度。试编写算法,构造此树的
孩子兄弟链表。
孩子兄弟链表类型定义:
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]; // 关系数组
VexType vexs[MAX_VEX_NUM]; // 顶点数组
int n, e; // 顶点数和边(弧)数
GraphKind kind; // 图的类型
} 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);
int i,j,k;
VexType v, w;
G.e = e; G.n = n;
for(int m=0;m<n;m++)
G.vexs[m]=vexs[m];
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;
G.arcs[i][j].adj= 1;
G.arcs[i][j].info= arcs[k].inf;
}
return OK;
}
/**********
【题目】编写算法,在图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,j = 0;
AdjVexNodeP p;
if(k<0||k>=G.n)
return -1;
if(G.vexs[k].firstArc != NULL)
p = G.vexs[k].firstArc;
for( ; p!=NULL;p = p->next)
j++;
return j;
}
/**********
【题目】编写算法,计算以邻接表方式存储的有向图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 */
{
int count;
AdjVexNode *p;
if(G.e==0||G.n==0||k>G.n) return -1;
for(int i=0;i<G.n;i++){
p = G.vexs[i].firstArc;
while(p){
if(p->adjvex==k) count++;
p=p->next;
}
}
return count;
}
/**********
【题目】编写算法,创建有向图的邻接表存储结构。
图的邻接表存储结构的类型定义如下:
#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(n*sizeof(VexNode)); 已有空间?
G.tags = (int*)malloc(n*sizeof(int));
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;
AdjVexNodeP p,q;
G.n = n;
G.e = e;
//G.vexs = (VexNode *)malloc(n*sizeof(VexNode)); 已有空间?
G.tags = (int*)malloc(n*sizeof(int));
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;
q=(AdjVexNode*)malloc(sizeof(AdjVexNode));
if(NULL==q) return OVERFLOW;
q->adjvex = i;
q->next=G.vexs[j].firstArc;
G.vexs[j].firstArc = q;
}
return OK;
}