数据结构_图_邻接表做存储结构实现求无向图的连通分量_C++实现

调了一个晚上终于把这段程序给调通了,原来对孩子兄弟链表的理解有点偏差,还有就是对递归有了跟深刻的理解,当然最大的收获就是发现程序中错误的能力进一步提高,借助于Visual Stdio这个强大的编程环境,可以让我迅速地积累编程经验,快速的发现程序中隐含的漏洞,而且他强大的自定义功能也让编程变得得心应手。推荐使用。。。


"head.h"


#include<iostream>
#define MAX_VEX_NUM 20
using namespace std;

class NODE//记录孩子结点的序号等信息
{
public:
       NODE();
       int child;
       NODE * next;
};

NODE::NODE()
{
       child=0;
       next=NULL;
}

class VexNode//记录顶点信息
{
public:
       VexNode();
       bool visited;
       char vexname;
       NODE * firstchild;
};

VexNode::VexNode()
{
        visited=false;
        firstchild=NULL;
}

class VexBox//储存图的邻接表
{
public:
       VexBox();
       VexNode vexbox[MAX_VEX_NUM];
       int vexnum;
};

VexBox::VexBox()
{
       vexnum=0;
}

class CSTreeNode//生成树节点
{
public:
    CSTreeNode();
    char name;
    CSTreeNode *lchild,*rsibling;
};

CSTreeNode::CSTreeNode()
{
    lchild=rsibling=NULL;
}

class Graph
{
public:
       Graph();
       void ShowGraph();//接口函数
private:
       void GetVexList();//得到顶点信息
       void GetChild();//得到各个顶点的孩子信息
       void DFSForest();
       void DFSTree(int ,CSTreeNode *);
       void Print();//输出图的顶点孩子信息
       void PrintTree();
       void InOrderPrintTree(CSTreeNode *);//中序输出生成树
       VexBox l;//定义一个邻接表
       CSTreeNode *root;//生成树根
};

Graph::Graph()
{
      root=NULL;
}

void Graph::ShowGraph()//接口函数
{
     cout<<"ShowGraph Called !"<<endl<<endl;
     GetVexList(); //得到顶点信息
     GetChild();//得到各个顶点的孩子信息
     Print();//输出邻接表信息
     DFSForest();//深度优先遍历该图并建立连通分量的生成森林
     PrintTree();//输出各连通分量
}

void Graph::GetVexList()//得到顶点信息
{
     cout<<"GetVexList Called !"<<endl<<endl;
     cout<<"Please Enter The Vertexes :"<<endl<<endl;
     char name;
     while(cin>>name)
     {
          l.vexbox[l.vexnum++].vexname=name;
     }
     cin.clear();
}

void Graph::GetChild()//得到各个顶点的孩子信息
{
    cout<<"GetChild Called !"<<endl<<endl;
    int num;
    NODE *p,*newnode;
    for(int i=0;i<l.vexnum;i++)
    {
        cout<<"Input The Children Of VerTex "<<l.vexbox[i].vexname<<" : "<<endl<<endl;
        while(cin>>num)
        {
            newnode=new NODE;
            newnode->child=num;
            if((p=l.vexbox[i].firstchild)==NULL)
            {
                l.vexbox[i].firstchild=newnode;
            }
            else
            {
                while(p->next!=NULL)
                {
                    p=p->next;
                }
                p->next=newnode;
            }
        }
        cin.clear();
    }
}

void Graph::Print()//输出邻接表信息
{
    cout<<"Print Called !"<<endl<<endl;
    NODE * p;
    for(int i=0;i<l.vexnum;i++)
    {
        p=l.vexbox[i].firstchild;
        cout<<l.vexbox[i].vexname<<" : "<<endl;
        while(p!=NULL)
        {
            cout<<"\t"<<l.vexbox[p->child].vexname<<endl;
            p=p->next;
        }
    }
}

void Graph::DFSForest()//深度优先遍历该图并建立连通分量的生成森林
{
    cout<<"DFSForest Called !"<<endl<<endl;
    CSTreeNode *p,*newnode;
    for(int i=0;i<l.vexnum;i++)//对列表内的所有节点进行遍历
    {
        if(l.vexbox[i].visited==false)//如果未被访问
        {
            newnode=new CSTreeNode;//新开辟一个节点
            newnode->name=l.vexbox[i].vexname;//当前节点名字赋给新的节点
            if(root==NULL)//如果root未指向任何节点
            {
                p=root=newnode;
            }
            else
            {
                p->rsibling=newnode;//否则就把新开辟的节点挂在右兄弟上
                p=p->rsibling;//p指向新开辟的节点
            }
            DFSTree(i,p);//以p为根节点建立新树
        }
    }
}

void Graph::DFSTree(int i,CSTreeNode *t)//左孩子右兄弟,左孩子右兄弟!!!在这纠结了半天
{
    bool first=true;
    l.vexbox[i].visited=true;//标记为已访问
    NODE*q=l.vexbox[i].firstchild;
    CSTreeNode * newnode,*p;
    while(q!=NULL)
    {
        if(l.vexbox[q->child].visited==false)//如果未被访问
        {
    	    l.vexbox[q->child].visited=true;
            newnode=new CSTreeNode;
            newnode->name=l.vexbox[q->child].vexname;
            if(first)//孩子
            {
                t->lchild=newnode;
                p=newnode;
                first=false;
            }
            else//兄弟
            {
                p->rsibling=newnode;
                p=p->rsibling;
            }
            DFSTree(q->child,newnode);
        }
		q=q->next;
	}
}

void Graph::PrintTree()//调用InOrderPrintTree()输出生成森林的相关信息
{
    cout<<"PrintTree Called !"<<endl<<endl;
    CSTreeNode *p=root;
    while(p!=NULL)
    {
		cout<<p->name;
		InOrderPrintTree(p->lchild);
        cout<<endl<<endl;
        p=p->rsibling;
    }
}

void Graph::InOrderPrintTree(CSTreeNode *t)//递归遍历每一棵树
{
    if(t==NULL)
		return;
    cout<<t->name;
    InOrderPrintTree(t->lchild);
    InOrderPrintTree(t->rsibling);
}



"main.cpp"



#include"head.h"

int main()
{
    Graph g;
    g.ShowGraph();
	system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值