close

這個Heap Extractmin的部份寫得很爛

本來有改寫一份

但不知道跑哪去了= =

有機會再修改

不過linked list的部份蠻有創意的

所以記錄下來好了


#include <iostream>

using std::cout;
using std::cin;
using std::endl;

#include <cmath>
#include <ctime>

#define MAX 32767

// structure definition
struct Node {   
   long id;
   float weight;
   long value;
}; // end struct Time


void createAdjList( Node **Adj, long numberOfNodes, long degree[] );
//void generateANode( Node &node, long numberOfNodes, long i );
//bool duplicate( Node **Adj, long i, long j );
void printAdjList(  long numberOfNodes, long pi[] , long d[]);
void Dijsktra( Node **Adj, long numberOfNodes, long degree[], long d[], long pi[]);

int main()
{

 long numberOfNodes;
 long time1, time2;


 srand( time(0) );

 do {
  cout << "How many nodes( nodes at least 10 )? ";
  cin >> numberOfNodes;
 } while( numberOfNodes <= 9);
 cout << endl;

 time1 = time(0);

 long *degree = new long[ numberOfNodes + 1 ];
 long *d = new long[ numberOfNodes + 1 ];
// long *color = new long[ numberOfNodes + 1 ];
 long *pi = new long[ numberOfNodes + 1 ];

// Node **Adj = new Node*[ numberOfNodes + 1 ];
 Node **Adj;
 Adj = new Node*[ numberOfNodes + 1 ];

 createAdjList( Adj, numberOfNodes, degree );
 
 Dijsktra( Adj, numberOfNodes, degree, d, pi);


 printAdjList( numberOfNodes,  pi ,  d );
 cout<<endl;
 time2 = time(0);
 cout << time2 - time1 << " seconds" << endl << endl;

 


 delete [] degree;
 for( long i = 1; i <= numberOfNodes; i++ )
  delete [] Adj[i];
 delete [] Adj;

 /*char ch;

 cout << "Press any key to continue";
 ch = cin.get();
 ch = cin.get();*/
 system("pause");

 

 return 0; 

} // end main

void DFSVISIT(Node **Adj, long numberOfNodes,Node color[],long u,long degree[])
{
 color[u].value = 1;
 for(long i = 1;i<=degree[u];i++)
 {
  if( color[Adj[u][i].id].value == 0 )
   DFSVISIT(Adj,numberOfNodes,color,Adj[u][i].id,degree);
 }
}

void DFS(Node **Adj, long numberOfNodes,Node color[],long degree[])
{

 for(long i = 1;i<=numberOfNodes;i++)
  color[i].value = 0;

  if( color[1].value == 0 )
   DFSVISIT(Adj,numberOfNodes,color,1,degree);
 
}

void createAdjList( Node **Adj, long numberOfNodes, long degree[] )
{
 long i,j,k,p,realdegree;
 long weightUpperBound = 20;
 long numberOfEdges = 0;
// long degreeUpperBound = static_cast<long>(log10(numberOfNodes));
 long degreeUpperBound = static_cast<long>(sqrt(numberOfNodes));
 long *array = new long[numberOfNodes + 1 ];
 Node *color = new Node[numberOfNodes + 1 ]; 


 srand( time(0) );

 for( i = 1; i <= numberOfNodes; i++ ) {
  degree[i] = rand() % degreeUpperBound + 1;
  realdegree = degree[1];
  numberOfEdges += degree[i];
  
 }

// cout << "\nThe graph has " << numberOfEdges << " edges.\n";


 for(i = 1;i<=numberOfNodes;i++)
 {
  array[i] = i;
 }
 Adj[1] = new Node[numberOfNodes + 1];

 cout<<"Tree: "<<endl;
 for( i = 1; i <= numberOfNodes; i++ )
 {

  if( i>1 )
  Adj[i] = new Node[ degree[i] + 1 ];

  p = numberOfNodes;
   
   //cout<<i<<"-> ";
   for( j = 1; j <= degree[i] ; j++)
   {
     
    k = rand() % p + 1;

    while(i==k)
    {
     k = rand() % p + 1;
    }

    Adj[i][j].id = array[k];

    if( k!=p )
    {
     if( p==i )
     {
      array[k] = array[p-1];
      p--;
     }
     else
     array[k] = array[p];
    }
    p--;

    Adj[i][j].weight = rand() % weightUpperBound + 1; //放入weight arrary亂數值 且不超過weightUpperBound
    

   // cout<<" ("<<Adj[i][j].id<<" , "<<Adj[i][j].weight<<")";
   

   }

   //cout<<endl;
   for(long k = 1;k<=numberOfNodes;k++)
   {
    array[k] = k;
   }


  
 }

 DFS(Adj,numberOfNodes,color,degree);

 for(long s = 1;s<=numberOfNodes;s++)
 {
  if( color[s].value == 0 )
  {
   realdegree++;
   Adj[1][realdegree].id = s;
   Adj[1][realdegree].weight = rand() % weightUpperBound + 1;
  }
 }
 degree[1] = realdegree;
 
 for( i = 1; i <= numberOfNodes; i++ )
 {
  cout<<i<<"-> ";
  for(j = 1;j<=degree[i];j++)
  {
   cout<<" ("<<Adj[i][j].id<<" , "<<Adj[i][j].weight<<")";
  }
  cout<<endl;
 }
 
 cout<<endl;
   
}

void MinHeapify( long Q[], long i, long numberOfNodes,long d[] )
{
 long l,r,mini,buffer;
 l = 2*i;
 r = (2*i)+1;

 if( l<=numberOfNodes && Q[l]<Q[i] )
  mini = l;
 else
  mini = i;
 if( r<=numberOfNodes && Q[r]<Q[mini] )
  mini = r;

 if( mini != i )
 {
  buffer = Q[i];
  Q[i] = Q[mini];
  Q[mini] = buffer;

  MinHeapify(Q,mini,numberOfNodes,d);
 }

}

long HeapExtractMin( long Q[], long &count,long d[] ,long numberOfNodes)
{
 long min;
 min = Q[1];
 Q[1] = Q[count];
 count--;
 MinHeapify(Q,1,numberOfNodes,d);
 return min;
}

void HeapDecreaseKey( long Q[], long i, long key,long d[])
{
 long buf,par;
 par = i/2;

 Q[i] = key;
 while( i > 1 && Q[par] > Q[i] )
 {
  buf = Q[i];
  Q[i] = Q[par];
  Q[par] = buf;
  i = par;
  par = i/2;
 }
}

void MinHeapInsert( long Q[],long key,long numberOfNodes,long d[] )
{
 numberOfNodes++;
 Q[numberOfNodes] = -10000;
 HeapDecreaseKey(Q,numberOfNodes,key,d);
}

void Dijsktra( Node **Adj, long numberOfNodes, long degree[], long d[], long pi[])
{
 long *Q = new long[numberOfNodes + 1 ];
 long *array = new long[numberOfNodes + 1 ];
 long u,count,tail,k,buf;
 long s = 1;
 count = numberOfNodes;
 tail = numberOfNodes;

 for( long i = 1; i <= numberOfNodes; i++ )
 {
  d[i] = 10000;
  pi[i] = NULL;
  MinHeapInsert(Q,d[i],i,d);
  array[i] = i;
  
 }

 d[s] = 0;

 HeapDecreaseKey(Q,s,d[s],d);

 while( count != 0 )
 {
  u = HeapExtractMin( Q,count,d,numberOfNodes);
  k = 1;
  
  while( tail != 0 && k<=tail )
  {
   if( d[array[k]] == u )
   {
    for( long j = 1;j<=degree[array[k]];j++ )
    {
     if( d[Adj[array[k]][j].id] > d[array[k]]+Adj[array[k]][j].weight )
     {
      d[Adj[array[k]][j].id] = d[array[k]]+Adj[array[k]][j].weight;
      pi[Adj[array[k]][j].id] = array[k];
      HeapDecreaseKey(Q,Adj[array[k]][j].id,d[Adj[array[k]][j].id],d); //////////
     }
    }
    buf = array[k];
    array[k] = array[tail];
    array[tail] = buf;
    tail--;
    break;
   }
   k++;
  }
   
  
 }
}

void printAdjList( long numberOfNodes, long pi[] , long d[] )
{
 cout<<"Tree edges: "<<endl;
 for(long i = 1;i<=numberOfNodes;i++ )
 {
  cout<<"("<<pi[i]<<" , "<<i<<")"<<endl;
 }
 cout<<endl;
 for(long j = 1;j<=numberOfNodes;j++ )
 {
  if( d[j] == 10000 )
   cout<<"d["<<j<<"] = 無限大"<<endl;
  else
   cout<<"d["<<j<<"] = "<<d[j]<<endl;
 }
}

 

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 flyinsky76 的頭像
    flyinsky76

    Deja Vu

    flyinsky76 發表在 痞客邦 留言(0) 人氣()