图的深度优先遍历(堆栈实现和非堆栈实现)

来源:互联网 发布:javascript速成手册 编辑:程序博客网 时间:2024/05/16 14:45

// Chart.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"

//如:FROMHEAD = 1,则用头插法;否则:则用尾插法
#define  FROMHEAD 1
/*
 如:HASHEAD 被定义,则各顶点的邻接点链中<带起始顶点>;
 否则:各顶点的邻接点链中<不带起始顶点>;
*/
#define  HASHEAD
#define  MAX 50
#define  SIZE 5
//邻接点结构
struct tnode
{
 int order;
 int data;
 int right;
 struct tnode *next;
};
//头接点结构
struct hnode
{
 int vertex;
 int data;
 struct tnode *ptnode;
};

#ifdef HASHEAD
 //<带起始顶点>
 int ChartNode[5][3] = {{1,'A',4},{2,'B',4},{3,'C',5},{4,'D',5},{5,'E',3}};
 int ConnectTable[] = {0,1,2,3,1,0,2,3,2,0,1,3,4,3,0,1,2,4,4,2,3};
#else
 //<不带起始顶点>
 int ChartNode[5][3] = {{1,'A',3},{2,'B',3},{3,'C',4},{4,'D',4},{5,'E',2}};
 int ConnectTable[] = {1,2,3,0,2,3,0,1,3,4,0,1,2,4,2,3};
#endif
/*
function CreateChart()功能:依次访问图中的各个节点
 参数描述:
 int max:图的顶点个数
 int fromhead:插入邻接占点的方式
  fromhead=1 头插入方式
  fromhead=0 尾插入方式
*/
void CreateChart(hnode HeadNode[],int max,int fromhead)
{
 int i,j,k;
 tnode *p,*tail;
 for(i=0;i {
  HeadNode[i].vertex = ChartNode[i][2];
  HeadNode[i].data = 65+i;
  HeadNode[i].ptnode = NULL;
  //printf("顶点[%c]有[%d]个邻接点!/n",HeadNode[i].data,HeadNode[i].vertex);
 }
 for(i=0,k=0;i {
  for(j=0;j  {
   p = (tnode *)malloc(sizeof(tnode));
   if(p==NULL)
   {
    exit(1);
   }
   else
   {
    p->order = ChartNode[ConnectTable[k+j]][0];
    p->data  = ChartNode[ConnectTable[k+j]][1];
    p->next  = NULL;
    
    if(fromhead)
    {
     //新节点放在前面<紧接头节点的后面>头插法
     p->next  = HeadNode[i].ptnode;
     HeadNode[i].ptnode = p;
    
    }
    else
    {
     //新节点放在后面<紧接最后一个表节点的后面>尾插法
     if(HeadNode[i].ptnode==NULL)
     {
      HeadNode[i].ptnode = p;
      tail = p;
     }
     else
      tail->next = p;
     tail = p;
     //printf("顶点[%c]的第[%d]个邻接点是[%c]!/n",HeadNode[i].data,j,p->data);
    }
   }
  }
  k = k+HeadNode[i].vertex;
 }
}

/*
function AccessChartNode()功能:依次访问图中的各个节点
*/
void AccessChartNode(hnode HeadNode[],int max)
{
 int i;
 tnode *p;
 for(i=0;i {
  p = HeadNode[i].ptnode;
  printf("/n顶点[%c]的[%d]个邻接点:/n",HeadNode[i].data,HeadNode[i].vertex);
  while(p!=NULL)
  {
   printf("顶点[%d][%c]/t",p->order,p->data);
   p = p->next;
  }
  printf("/n");
 }
}

/*
function FirstDeepAccess1()功能:图的[深度优先遍历]算法<非堆栈实现算法>
*/
void FirstDeepAccess1(hnode HeadNode[],int max)
{
 int i;
 tnode *p;
 int visited[SIZE+1];
 for(i=0;i<=max;i++)
  visited[i] = 0;
 for(i=0;i {
  //printf("/n循环[%d]次/n",i);
  p = HeadNode[i].ptnode;
  while(p!=NULL)
  {
   if(!visited[p->order])
   {
    printf("顶点[%d][%c]/t",p->order,p->data);
    visited[p->order] = 1;
   }
    p = p->next;
  }
 }
}

/*
function FirstDeepAccess2()功能:图的[深度优先遍历]算法<堆栈实现算法>
*/
void FirstDeepAccess2(hnode HeadNode[],int max)
{
 int i,top;
 tnode *p;
 tnode *stack[SIZE+1];
 int visited[SIZE+1];
 for(i=0;i<=max;i++)
  visited[i] = 0;
 for(i=0;i {
  //printf("/n循环[%d]次/n",i);
  top = 1;
  stack[top] = HeadNode[i].ptnode;//将本次访问的起始节点进栈,以便将来正确返回
  while(top!=0)
  {
   p = stack[top];
   while((p!=NULL)&&(visited[p->order]))//节点非空,且已访问
    p = p->next;
   if(p==NULL)//当前节点没有邻接点,或有但都已经访问
    top--;
   else
   {
    printf("顶点[%d][%c]/t",p->order,p->data);
    visited[p->order] = 1;
    stack[++top] = p;
   }
  }
 }
}


int main(int argc, char* argv[])
{
 hnode HeadNodeArray[SIZE];
 if(FROMHEAD)
  printf("[表节点以头插入方式]");
 else
  printf("[表节点以尾插入方式]");
 CreateChart(HeadNodeArray,SIZE,FROMHEAD);
 //AccessChartNode(SIZE);
 printf("/n此图的[深度优先遍历1]结果:/n");
 FirstDeepAccess1(HeadNodeArray,SIZE);
 printf("/n此图的[深度优先遍历2]结果:/n");
 FirstDeepAccess2(HeadNodeArray,SIZE);
 printf("/n运行完毕!/n");
 return 0;