数据结构图的基本操作

请问这个为什么运行无反应,连操作的提示信息都不显示?

img


#include <iostream>
#include <queue>
using namespace std;
#define MVNum 100    //最大顶点数
#define OK 1
#define ERROR 0
#define MaxInt 10000
typedef int Status;
typedef char VerTexType;
typedef int ArcValue;
typedef struct ArcNode{  //边结点
int adjvex;         //该边所指向的顶点的位置
struct ArcNode *nextarc;    //指向下一条边的指针
ArcValue value;     //权值
}ArcNode;

typedef struct VNode{    //顶点信息
VerTexType data;
ArcNode *firstarc;       //指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];   //AdjList表示邻接表类型

typedef struct {          //邻接表
AdjList vertices;
int arcs[1000][1000];
int vexnum,arcnum;       //图的当前顶点数和边数
int kind;                //图的种类
}ALGraph;
typedef struct QNode{
     VerTexType   data;
     struct QNode  *next;
}QNode, *QueuePtr;
typedef struct {
     QueuePtr  front;  // 队头指针
     QueuePtr  rear;   // 队尾指针
}LinkQueue;      // 链队列

// 构造一个空队列
void InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=new QNode;
Q.front->next=NULL;

}
//入队
void EnQueue (LinkQueue &Q, VerTexType v)
{ //插入元素e为Q的新的队列尾元素
QNode* p=new QNode;
p->data=v;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;

 }
//出队
Status DeQueue (LinkQueue &Q, VerTexType &v)
{
if(Q.front==Q.rear)return ERROR;
QNode* p=Q.front->next;
v=p->data;    //返回被删除元素
Q.front->next=p->next;//修改头结点指针
if(Q.rear==p)
Q.rear=Q.front;
delete p;//释放被删结点
return v;

}

//判断链队列是否为空
bool QueueEmpty (LinkQueue Q){
    return (Q.front==Q.rear);
 }


//邻接表建立图
int LocateVex(ALGraph G, int v){
    for(int i=0;i<G.vexnum;i++){
        if(v==G.vertices[i].data){
            return i;
        }
    }
}
Status CreateUDG(ALGraph &G){
cin>>G.vexnum>>G.arcnum;      //输入总顶点数,总边数
for(int i=0;i<G.vexnum;i++){
    cin>>G.vertices[i].data;    //输入顶点值
    G.vertices[i].firstarc=NULL;   //初始化表头结点指针域为NULL
}
int v1,v2;     //v1,v2为依附于一条边的两个顶点
int i,j;
for(int k=0;k<G.arcnum;k++){   //输入各边构建邻接表
    cin>>v1>>v2;
    i = LocateVex(G, v1);
    j = LocateVex(G, v2);
    ArcNode *p1;  //生成一个新的边结点*p1
    p1->adjvex=j;     //邻接点序号为j
    p1->nextarc= G.vertices[i].firstarc;
    G.vertices[i].firstarc=p1;
    //将新结点*p1插入顶点vi的边表头部
    ArcNode *p2; //生成另一个对称的新的边结点*p2
    p2->adjvex=i;           //邻接点序号为i
    p2->nextarc= G.vertices[j].firstarc;
    G.vertices[j].firstarc=p2;
        //将新结点*p2插入顶点vj的边表头部

}
}
//邻接表深度优先遍历算法
bool  visited [MVNum]={false};          // 访问标志数组
void DFS_AL(ALGraph G, int v){  //图G为邻接矩阵类型
  cout<<v;
  visited[v] = true;      //访问第v个顶点
  ArcNode *p=G.vertices[v].firstarc;  //p指向v的边链表的第一个边结点
  while(p!=NULL) //边结点非空
  {
     int w=p->adjvex;  //表示w是v的邻接点
     if(!visited[w])  DFS_AL(G, w);
    //如果w未访问,则递归调用DFS
     p=p->nextarc; //p指向下一个边结点
  }
}
void DFSTraverse(ALGraph  G)
{         // 对图G做深度优先遍历
   for (int v=0; v<G.vexnum; ++v) // 访问标志数组初始化
              visited[v] = false;
   for (int v=0; v<G.vexnum; ++v)
         if (!visited[v])
               DFS_AL(G,v);  // 对尚未访问的顶点调用DFS
 }

//邻接表广度优先遍历算法
bool  Visited [MVNum]={false};          // 访问标志数组
void BFS(ALGraph G,int v){
    LinkQueue Q;
    //按广度优先非递归遍历连通图G
    cout<<v; Visited[v] = true;             //访问第v个顶点
    InitQueue(Q);//辅助队列Q初始化,置空
    EnQueue(Q, v);                        //v进队
    while(!QueueEmpty(Q)){           //队列非空
       VerTexType u=DeQueue(Q, u);                    //队头元素出队并置为u
       ArcNode *p=G.vertices[u].firstarc;
       while(p!=NULL){
          int w=p->adjvex;
          if(!Visited[w]){ //w为u的尚未访问的邻接顶点
               cout<<w; Visited[w] = true; EnQueue(Q, w); //w进队}
          p=p->nextarc; }
         }
 }}

void Dijkstra(ALGraph G,int v0){
    //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
    int n=G.vexnum;
    int v,Path[n];//n为G中顶点的个数
    bool S[MVNum];
    int D[MVNum];
    for(int v = 0; v<n; ++v){                 //n个顶点依次初始化
       S[v] = false;                      //S初始为空集
       D[v] = G.arcs[v0][v];               //将v0到各个终点的最短路径长度初始化
       if(D[v]< MaxInt)  Path[v]=v0; //v0和v之间有弧,将v的前驱置为v0
       else Path [v]=-1;                   //如果v0和v之间无弧,则将v的前驱置为-1
      }//for
      S[v0]=true;                        //将v0加入S
      D[v0]=0;                              //源点到源点的距离为0
/*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
      for(int i=1;i<n; ++i){//对其余n?1个顶点,依次进行计算
        int Min= MaxInt;
        for(int w=0;w<n; ++w){
          if(!S[w]&&D[w]<Min)
              { v=w; Min=D[w];} }//选择一条当前的最短路径,终点为v
        S[v]=true; //将v加入S
        for(int w=0;w<n; ++w)
           //更新从v0出发到集合V?S上所有顶点的最短路径长度
            if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){
                D[w]=D[v]+G.arcs[v][w];       //更新D[w]
                Path [w]=v;                      //更改w的前驱为v
            }//if
         }//for
         //输出v0到其他结点所需最短路径
             for(int i=0;i<n;i++){
                 cout<<i<<":"<<D[i]<<endl;
             }
}


void show_help()
{
    cout<<"1----邻接表建立图"<<endl;
    cout<<"2----采用深度优先搜索方式遍历图"<<endl;
    cout<<"3----采用广度优先搜索方式遍历图"<<endl;
    cout<<"4----实现Dijkstra最短路径算法"<<endl;
    cout<<"5----退出"<<endl;
}

int main()
{
    int operate_code;
    show_help();
    ALGraph G;
    VerTexType v;
    LinkQueue Q;
    int i;
    while(1)
    {
        cout<<"请输入操作代码:";
        cin>>operate_code;
        if(operate_code==1)
        {
          CreateUDG(G);
        }
        else if(operate_code==2)
        {
            DFSTraverse(G);
        }
        else if(operate_code==3)
        {
            BFS(G,v);
        }
        else if(operate_code==4)
        {
            //Dijkstra(G,v);
        }
        else if(operate_code==5)
        {
            break;
        }
        else
        {
            cout<<"\n操作码错误!!!"<<endl;
            cin.clear();
            cin.sync();
            show_help();
        }


    }
    //调用销毁线性表函数,如  Destroy_List(L);

    return 0;
}

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7619101
  • 这篇博客也不错, 你可以看下【开卷数据结构 】图的基本介绍,不进来看看吗?
  • 除此之外, 这篇博客: 数据结构线性表的链式存储结构(单链表)的表示及其基本操作中的 求指定位置的元素值 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 定义一个指针p指向头结点,当i=1时,p=p->next,指向第一个结点,当i=position时,指向所找的位置,返回该位置的数据域即可。

    Status GetElem(LinkList L,Elemtype position)
    {
    	Elemtype i;
    	LinkList p;
    	p=L;
    	for(i=1;i<=position;i++)
    	{
    		p=p->next;
    	}
    	return p->data;
    } 
    

    调用

    case 5:
    			    if(flag!=0)
    				{
    					printf("请输入你所查找的位置\n");
    					scanf("%d",&position);
    					if(position<=0||position>ListLength(L))
    	                {
    	                   	printf("不存在这个位置\n");
    					}else
    					{
    						elem=GetElem(L,position);
    					    printf("该位置上的元素是%d\n",elem);
    					}					
    			    }else
    				{
    					printf("链表未初始化\n");
    				} 
    				system("pause");
    				break;
    
  • 您还可以看一下 程张浩老师的微信小程序项目实战之我画你猜视频课程课程中的 商品的展示功能和删除功能小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    问题可能出现在代码实现方面,需要检查代码的逻辑和语法错误,具体解决方案如下:

    1.检查程序是否在后台运行,是否进入了死循环或者无限等待状态,需要检查程序中的所有相互作用的流程并确定软件的运行路径;

    2.检查程序是否缺少关键的功能或者需要的权限,并给它加上需要的功能和权限;

    3.将程序及其依赖的资源在另一台机器上进行测试,在不同的环境中执行,以获取更多的信息。如果有需要可以重新编译和部署程序;

    4.检查程序的内存和CPU使用情况,尝试缓存一些数据,以节省系统内存和CPU资源,也可以使用垃圾回收机制实现自动内存回收的功能;

    5.针对数据结构图操作的问题,需要进行代码重构和优化,根据具体的需求和数据结构,选择适当的算法并实现,如堆排序、归并排序,或者其他数据结构,如贝叶斯网络、神经网络等。

    6.在代码运行过程中,可以根据需要增加调试信息,以便更好地理解程序的内部运行机制,可以使用调试输出,以打印出程序的内部状态和数据。

    7.考虑把程序进行分解,将程序即其依赖的资源进行分离,减少系统瓶颈,尽量避免循环语句的嵌套和递归调用。

    针对最后一道题目,以下为其代码实现:

    #include<stdio.h>
    #include<string.h> 
    int main()
    {
        char str[1000];
        int count[26] = {0};
        fgets(str, 1000, stdin); //输入一行字符串
        int len = strlen(str); //计算字符串长度
        for(int i = 0; i < len; i++)
        {
            if(str[i] >= 'a' && str[i] <= 'z') //没有区分大小写
            {
                int index = str[i] - 'a'; //计算出对应的字母索引
                count[index]++; //统计该字母出现的个数
            } 
        }
        for(int i = 0; i < 26; i++)
        {
            if(count[i] > 0)
            {
                printf("%c:%d\n", i + 'a', count[i]); //输出每个字母出现的个数
            }
        }
        return 0;
    }