Author: JULY, March 18, 2011
Source: http://blog.csdn.net/v_july_v.
------------------------------------------
Introduction:
The purpose of writing this article is very simple. For one reason, I personally think: in the previous article, I continued later. The gradual implementation of the Dijkstra algorithm's fibonacci heap c is not good enough, I would like to write a sequel to the Dijkstra algorithm, that is, the second three.
Given the difficulty of understanding the Fibonacci heap, this article uses a simple minimum heap as an example. At the same time, this program also has reference to the implementation of netizens. If you have any questions, please let me know.
Dijkstra algorithm + Heap complete algorithm IDEA
In the previous article, we have learned that the Dijkstra algorithm is as follows:
DIJKSTRA (G, w, s)
1 INITIALIZE-SINGLE-SOURCE (G, s) // 1. INITIALIZE the node.
2 S Ø
3 Q 1_v [G] // 2. initialize the queue
4 while Q =ø
5 do u then EXTRACT-MIN (Q) // 3. Extract the smallest node from the smallest Queue (before that, create the smallest heap first)
6 S ← S limit {u}
7 for each vertex v ε Adj [u]
8 do RELAX (u, v, w) // 4. Relaxation operation.
In this case, we will not go into details, so we can simply write the following c/c ++ source code:
Void dijkstra (ALGraph G, int s, int d [], int pi [], int Q [])
{// Q [] is the smallest priority queue. Q [1. n] stores the graph vertex number, and Q [0] stores the heap size.
// The priority queue has the key concept. Here the key can be obtained from d. For example, the size (key) of Q [2] is d [Q [2]
InitSingleSource (G, s, d, pi); // 1. initialize the node.
// 2. initialize the queue
Q [0] = G. vexnum;
For (int I = 1; I <= Q [0]; I ++)
{
Q [I] = I-1;
}
Q [1] = s;
Q [s + 1] = 0;
Int u;
Int v;
While (Q [0]! = 0)
{
BuildMinHeap (Q, d); // 3.1. Create the minimum heap.
U = extractMin (Q, d); // 3.2. Extract the smallest node from the smallest queue.
ArcNode * arcNodePt = G. vertices [u]. firstarc;
While (arcNodePt! = NULL)
{
V = arcNodePt-> adjvex;
Relax (u, v, G, d, pi); // 4. Relaxation operation.
ArcNodePt = arcNodePt-> nextarc;
}
}
}
OK. Next, let's write the code to implement this Dijkstra algorithm step by step. First, we will provide the source code of 1st, initialize the node work, and 4. Relax the two operations:
Void initSingleSource (ALGraph G, int s, int d [], int pi [])
{// 1. initialize node work
For (int I = 0; I <G. vexnum; I ++)
{
D [I] = INFINITY;
Pi [I] = NIL;
}
D [s] = 0;
}
Void relax (int u, int v, ALGraph G, int d [], int pi [])
{// 4. Relaxation operation.
// U is the vertex number of the newly added set S.
If (d [v]> d [u] + getEdgeWeight (G, u, v ))
{
D [v] = d [u] + getEdgeWeight (G, u, v );
Pi [v] = u;
}
}
OK. Next, let's elaborate on the 3rd operations. 3. Extract the smallest node from the smallest Queue (before that, create the smallest heap first ).
Minimum Heap node creation and Extraction
In my article 2, heap sorting algorithm, I have explained the establishment of the largest heap:
2.3.1 create a heap (O (N ))
BUILD-MAX-HEAP)
1 heap-size [A] bytes length [A]
2 for I operate | _ length [A]/2 _ | downto 1
3 do MAX-HEAPIFY)
// Create a heap. How do I create a column? The original is constantly calling MAX-HEAPIFY (A, I) to build the largest heap.
Build the minimum heap, it is also one thing, the above Code to change the two places can be, A, MAX-> MIN, two, MAX-HEAPIFY (A, I)-> MIN-HEAPIFY (A, I ). In this case, is the column simple? Yes, it is very simple.
First, create the minimum heap:
Void buildMinHeap (int Q [], int d []) // create the minimum heap
{
For (int I = Q [0]/2; I> = 1; I --)
{
MinHeapify (Q, d, I); // call minHeapify to maintain the heap nature.
}
}
Then, you have to write the minHeapify code to keep the minimum heap nature:
Void minHeapify (int Q [], int d [], int I)
{// Smallest, l, r, and I are subscripts of the priority queue element, ranging from 1 ~ Heap-size [Q]
Int l = 2 * I;
Int r = 2 * I + 1;
Int smallest;
If (l <= Q [0] & d [Q [l] <d [Q [I])
{
Smallest = l;
}
Else
{
Smallest = I;
}
If (r <= Q [0] & d [Q [r] <d [Q [smallest])
{
Smallest = r;
}
If (smallest! = I)
{
Int temp = Q [I];
Q [I] = Q [smallest];
Q [smallest] = temp;
MinHeapify (Q, d, smallest );
}
}
You can compare the code for creating the smallest heap with the code for creating the largest heap. It's exactly the same as changing the letters:
MAX-HEAPIFY (A, I) // code for creating the largest heap
1 l LEFT (I)
2 r align RIGHT (I)
3 if l ≤ heap-size [A] and A [l]> A [I]
4 then largest rjl
5 else largest connector I
6 if r ≤ heap-size [A] and A [r]> A [largest]
7 then largest release r
8 if largest = I
9 then exchange A [I] <-> A [largest]
10 MAX-HEAPIFY (A, largest)
OK. Finally, it is 3. Extract the minimum node from the smallest queue, as shown below:
Int extractMin (int Q [], int d []) // 3. Extract the smallest node from the smallest queue
{// Extract the content of the smallest element in the priority queue. The vertex label (0 ~ G. vexnum-1 ),
// These labels are stored in Q [1. n ].
If (Q [0] <1)
{
Cout <"heap underflow! "<Endl;
Return-10000;
}
Int min = Q [1];
Q [1] = Q [Q [0];
Q [0] = Q [0]-1;
MinHeapify (Q, d, 1 );
Return min;
}
Creating an ALGraph
First, define several macros,
# Define MAX_VERTEX_NUM 20 // The maximum number of nodes in the graph
# Define INFINITY 10000
# Define NIL-1
Create several data structures:
Typedef struct ArcNode // arc node, which is the table node of the adjacent linked list.
{
Int adjvex; // The Position of the arc pointing to the End Node. In fact, the subscript of the array is saved.
ArcNode * nextarc; // pointer to the next arc
Int weight; // weight.
} ArcNode;
Typedef struct VNode
{
ArcNode * firstarc;
} VNode, AdjList [MAX_VERTEX_NUM];
Typedef struct
{
AdjList vertices;
Int vexnum, arcnum;
} ALGraph;
Write several function functions:
Void initALGraph (ALGraph * GPt, int vn) // initialize the node
{
GPt-> arcnum = 0;
GPt-> vexnum = vn;
For (int I = 0; I <vn; I ++)
{
GPt-> vertices [I]. firstarc = NULL;
}
}
Void insertArc (ALGraph * GPt, int vhead, int vtail, int w) // Add node operations
{
ArcNode * arcNodePt = new ArcNode;
ArcNodePt-> nextarc = NULL;
ArcNodePt-> adjvex = vtail;
ArcNodePt-> weight = w;
ArcNode * tailPt = GPt-> vertices [vhead]. firstarc;
If (tailPt = NULL)
{
GPt-> vertices [vhead]. firstarc = arcNodePt;
}
Else
{
While (tailPt-> nextarc! = NULL)
{
TailPt = tailPt-> nextarc;
}
TailPt-> nextarc = arcNodePt;
}
GPt-> arcnum ++;
}
Void displayGraph (ALGraph G) // print the node
{
ArcNode * arcNodePt;
For (int I = 0; I <G. vexnum; I ++)
{
ArcNodePt = G. vertices [I]. firstarc;
Cout <"vertex" <I <":";
While (arcNodePt! = NULL)
{
Cout <arcNodePt-> adjvex <"(" <"weight" <arcNodePt-> weight <")" <"";
ArcNode