第十四周 项目三 是否二叉排序树?

来源:互联网 发布:软件测试人员岗位职责 编辑:程序博客网 时间:2024/06/13 00:52
/*   *Copyright (c) 2016,烟台大学计算机学院   *All rights reserved.   *文件名称:graph.cpp   *作者:衣龙川   *完成日期:2016年12月8日   *版本号:vc++6.0   *   *问题描述: 是否二叉排序树? *输入描述:无   *程序输出:*/    


graph.cpp:

#include <stdio.h>#include <malloc.h>#include "graph.h"//功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)//      n - 矩阵的阶数//      g - 要构造出来的邻接矩阵数据结构void ArrayToMat(int *Arr, int n, MGraph &g){    int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数    g.n=n;    for (i=0; i<g.n; i++)        for (j=0; j<g.n; j++)        {            g.edges[i][j]=Arr[i*n+j]; //将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j],计算存储位置的功夫在此应用            if(g.edges[i][j]!=0 && g.edges[i][j]!=INF)                count++;        }    g.e=count;}void ArrayToList(int *Arr, int n, ALGraph *&G){    int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数    ArcNode *p;    G=(ALGraph *)malloc(sizeof(ALGraph));    G->n=n;    for (i=0; i<n; i++)                 //给邻接表中所有头节点的指针域置初值        G->adjlist[i].firstarc=NULL;    for (i=0; i<n; i++)                 //检查邻接矩阵中每个元素        for (j=n-1; j>=0; j--)            if (Arr[i*n+j]!=0)      //存在一条边,将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j]            {                p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p                p->adjvex=j;                p->info=Arr[i*n+j];                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p                G->adjlist[i].firstarc=p;            }    G->e=count;}void MatToList(MGraph g, ALGraph *&G)//将邻接矩阵g转换成邻接表G{    int i,j;    ArcNode *p;    G=(ALGraph *)malloc(sizeof(ALGraph));    for (i=0; i<g.n; i++)                   //给邻接表中所有头节点的指针域置初值        G->adjlist[i].firstarc=NULL;    for (i=0; i<g.n; i++)                   //检查邻接矩阵中每个元素        for (j=g.n-1; j>=0; j--)            if (g.edges[i][j]!=0)       //存在一条边            {                p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p                p->adjvex=j;                p->info=g.edges[i][j];                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p                G->adjlist[i].firstarc=p;            }    G->n=g.n;    G->e=g.e;}void ListToMat(ALGraph *G,MGraph &g)//将邻接表G转换成邻接矩阵g{    int i,j;    ArcNode *p;    g.n=G->n;   //根据一楼同学“举报”改的。g.n未赋值,下面的初始化不起作用    g.e=G->e;    for (i=0; i<g.n; i++)   //先初始化邻接矩阵        for (j=0; j<g.n; j++)            g.edges[i][j]=0;    for (i=0; i<G->n; i++)  //根据邻接表,为邻接矩阵赋值    {        p=G->adjlist[i].firstarc;        while (p!=NULL)        {            g.edges[i][p->adjvex]=p->info;            p=p->nextarc;        }    }}void DispMat(MGraph g)//输出邻接矩阵g{    int i,j;    for (i=0; i<g.n; i++)    {        for (j=0; j<g.n; j++)            if (g.edges[i][j]==INF)                printf("%3s","∞");            else                printf("%3d",g.edges[i][j]);        printf("\n");    }}void DispAdj(ALGraph *G)//输出邻接表G{    int i;    ArcNode *p;    for (i=0; i<G->n; i++)    {        p=G->adjlist[i].firstarc;        printf("%3d: ",i);        while (p!=NULL)        {            printf("-->%d/%d ",p->adjvex,p->info);            p=p->nextarc;        }        printf("\n");    }}


graph.h:

#ifndef GRAPH_H_INCLUDED#define GRAPH_H_INCLUDED#define MAXV 100                //最大顶点个数#define INF 32767       //INF表示∞typedef int InfoType;//以下定义邻接矩阵类型typedef struct{    int no;                     //顶点编号    InfoType info;              //顶点其他信息,在此存放带权图权值} VertexType;                   //顶点类型typedef struct                  //图的定义{    int edges[MAXV][MAXV];      //邻接矩阵    int n,e;                    //顶点数,弧数    VertexType vexs[MAXV];      //存放顶点信息} MGraph;                       //图的邻接矩阵类型//以下定义邻接表类型typedef struct ANode            //弧的结点结构类型{    int adjvex;                 //该弧的终点位置    struct ANode *nextarc;      //指向下一条弧的指针    InfoType info;              //该弧的相关信息,这里用于存放权值} ArcNode;typedef int Vertex;typedef struct Vnode            //邻接表头结点的类型{    Vertex data;                //顶点信息    int count;                  //存放顶点入度,只在拓扑排序中用    ArcNode *firstarc;          //指向第一条弧} VNode;typedef VNode AdjList[MAXV];    //AdjList是邻接表类型typedef struct{    AdjList adjlist;            //邻接表    int n,e;                    //图中顶点数n和边数e} ALGraph;                      //图的邻接表类型//功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)//      n - 矩阵的阶数//      g - 要构造出来的邻接矩阵数据结构void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表void MatToList(MGraph g,ALGraph *&G);//将邻接矩阵g转换成邻接表Gvoid ListToMat(ALGraph *G,MGraph &g);//将邻接表G转换成邻接矩阵gvoid DispMat(MGraph g);//输出邻接矩阵gvoid DispAdj(ALGraph *G);//输出邻接表G#endif // GRAPH_H_INCLUDED


main.cpp:

#include <stdio.h>#include <malloc.h>#define MaxSize 100typedef int KeyType;                    //定义关键字类型typedef char InfoType;typedef struct node                     //记录类型{    KeyType key;                        //关键字项    InfoType data;                      //其他数据域    struct node *lchild,*rchild;        //左右孩子指针} BSTNode;int path[MaxSize];                      //全局变量,用于存放路径void DispBST(BSTNode *b);               //函数说明int InsertBST(BSTNode *&p,KeyType k)    //在以*p为根节点的BST中插入一个关键字为k的节点{    if (p==NULL)                        //原树为空, 新插入的记录为根节点    {        p=(BSTNode *)malloc(sizeof(BSTNode));        p->key=k;        p->lchild=p->rchild=NULL;        return 1;    }    else if (k==p->key)        return 0;    else if (k<p->key)        return InsertBST(p->lchild,k);  //插入到*p的左子树中    else        return InsertBST(p->rchild,k);  //插入到*p的右子树中}BSTNode *CreatBST(KeyType A[],int n)//由数组A中的关键字建立一棵二叉排序树{    BSTNode *bt=NULL;                   //初始时bt为空树    int i=0;    while (i<n)        InsertBST(bt,A[i++]);       //将A[i]插入二叉排序树T中    return bt;                          //返回建立的二叉排序树的根指针}void DispBST(BSTNode *bt)//以括号表示法输出二叉排序树bt{    if (bt!=NULL)    {        printf("%d",bt->key);        if (bt->lchild!=NULL || bt->rchild!=NULL)        {            printf("(");            DispBST(bt->lchild);            if (bt->rchild!=NULL) printf(",");            DispBST(bt->rchild);            printf(")");        }    }}/*int JudgeBST(BSTNode *bt)为判断一个树是否为排序二叉树设计的算法的实现*/KeyType predt=-32767; //predt为全局变量,保存当前节点中序前趋的值,初值为-∞int JudgeBST(BSTNode *bt)   //判断bt是否为BST{    int b1,b2;    if (bt==NULL)        return 1;    //空二叉树是排序二叉树    else    {        b1=JudgeBST(bt->lchild);   //返回对左子树的判断,非排序二叉树返回0,否则返回1        if (b1==0 || predt>=bt->key)  //当左子树非排序二叉树,或中序前趋(全局变量)大于当前根结点时            return 0;    //返回“不是排序二叉树”        predt=bt->key;   //记录当前根为右子树的中序前趋        b2=JudgeBST(bt->rchild);   //对右子树进行判断        return b2;    }}int main(){    BSTNode *bt;    int a[]= {43,91,10,18,82,65,33,59,27,73},n=10;    printf("创建排序二叉树:");    bt=CreatBST(a,n);    DispBST(bt);    printf("\n");    printf("bt%s\n",(JudgeBST(bt)?"是一棵BST":"不是一棵BST"));    bt->lchild->rchild->key = 30;  //搞个破坏!    printf("修改后的二叉树:");    DispBST(bt);    printf("\n");    printf("bt%s\n",(JudgeBST(bt)?"是一棵BST":"不是一棵BST"));    return 0;}

运行截图:


0 0
原创粉丝点击