圖的深度優先遍歷(堆疊實現和非堆疊實現)

gudesheng發表於2008-01-03

// 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;



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=935611


相關文章