哈密尔顿(Hamilton)回路(软件设计师考题)

【说明】
一个无向连通图G点上的哈密尔顿(Hamilton)回路是指从图G上的某个顶点出发,经过图上所有其他顶点一次且仅一次,最后回到该顶点的路径。一种求解无向图上哈密尔顿回路算法的基本思想如下:
假设图G存在一个从顶点V0出发的哈密尔顿回路 V0 —— V1——V2——V3——...——Vn-1——V0。算法从顶点V0出发,访问该顶点的一个未被访问的邻接顶点V1,接着从顶点V1出发,访问V1一个未被访问的邻接顶点V2,…;对顶点Vi,重复进行以下操作:访问Vi的一个未被访问的邻接接点Vi+1;若Vi的所有邻接顶点均已被访问,则返回到顶点Vi-1,考虑Vi-1的下一个未被访问的邻接顶点,仍记为Vi;直到找到一条哈密尔顿回路或者找不到哈密尔顿回路,算法结束。

【C代码】
下面是算法的C语言实现。
(1)常量和变量说明
n:图G中的顶点数
c[ ] [ ]:图G的邻接矩阵
k:统计变量,当期已经访问的定点数为k+1
x[k]:第k个访问的顶点编号,从0开始
visited[x[k]]:第k个顶点的访问标志,0表示未访问,1表示已访问
(2)C程序

#include <stdio.h>
#include <stdlib.h>
#define MAX 10

void Hamilton(int n,int c[n][n])
{
  int i;
  int x[MAX];
  int visited[MAX];
  int k;
  /*初始化x数组贺visited数组*/
  for (i=0;i<n;i++)
  {
    x[i]=0;
    visited[i]=0;
  }
  /*访问起始顶点*/
  k=0;
  visited[x[0]]=1;
  x[0]=0;
  k=k+1;
  /*访问其他顶点*/
  while(k>=1)
  {
    x[k]=x[k]+1;
    while(x[k]<n)
    {
      if (visited[x[k]]==0 &&c[x[k-1]][x[k]]==1)
      {/*邻接顶点x[k]未被访问过*/
        break;
      }
      else
      {
        x[k] = x[k] +1;
      }
    }
  
    if(x[k]<n&&k==n-1&&c[x[k]][0]==1)
    { /*找到一条哈密尔顿回路*/
      for (k=0;k<n;k++)
      {
        printf("%d--",x[k] ); /*输出哈密尔顿回路*/
      }
      printf("%d\n",x[0] );
      return;
    }
    else if (x[k]<n&&k<n-1)
    {/*设置当期顶点的访问标志,继续下一个顶点*/
      visited[x[k]]=1;
      k=k+1;
    }
    else
    {/*没有未被访问过的邻接顶点,回退到上一个顶点*/
      x[k]=0;
      visited[x[k-1]]=0;
      k=k-1;
    }
  }
  printf("not found");
}

int main()
{
  int c[5][5]={0,1,1,1,1,
  1,0,1,1,1,
  1,1,0,1,0,
  1,1,1,0,0,
  1,1,0,0,1};
  Hamilton(5,c);
	
	int c_a[4][4]={0,1,0,0,
  0,0,1,0,
  0,0,0,1,
  0,0,0,0,};
  Hamilton(4,c_a);
	
}

#include <stdio.h>
#include <stdlib.h>
#define MAX 10

void Hamilton(int n,int c[n][n])
{
  int i;
  int x[MAX];
  int visited[MAX];
  int k;
  /*初始化x数组贺visited数组*/
  for (i=0;i<n;i++)
  {
    x[i]=0;
    visited[i]=0;
  }
  /*访问起始顶点*/
  k=0;
  visited[x[0]]=1;
  x[0]=0;
  k=k+1;
  /*访问其他顶点*/
  while(k>=1)
  {
    x[k]=x[k]+1;
    while(x[k]<n)
    {
      if (visited[x[k]]==0 &&c[x[k-1]][x[k]]==1)
      {/*邻接顶点x[k]未被访问过*/
        break;
      }
      else
      {
        x[k] = x[k] +1;
      }
    }
  
    if(x[k]<n&&k==n-1&&c[x[k]][0]==1)
    { /*找到一条哈密尔顿回路*/
      for (k=0;k<n;k++)
      {
        printf("%d--",x[k] ); /*输出哈密尔顿回路*/
      }
      printf("%d\n",x[0] );
      return;
    }
    else if (x[k]<n&&k<n-1)
    {/*设置当期顶点的访问标志,继续下一个顶点*/
      visited[x[k]]=1;
      k=k+1;
    }
    else
    {/*没有未被访问过的邻接顶点,回退到上一个顶点*/
      x[k]=0;
      visited[x[k-1]]=0;
      k=k-1;

    }
  }
  printf("not found");
}

int main()
{
  int c[5][5]={0,1,1,1,1,
  1,0,1,1,1,
  1,1,0,1,0,
  1,1,1,0,0,
  1,1,0,0,1};
  Hamilton(5,c);
    
    int c_a[4][4]={0,1,0,0,
  0,0,1,0,
  0,0,0,1,
  0,0,0,0,};
  Hamilton(4,c_a);
    
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值