class FullPQ {};
class EmptyPQ {};
#include "Max_Heap.h"
template<class ItemType>
class PQType
{
public:
PQType(int max);
~PQType();
void MakeEmpty();
bool IsEmpty() const;
bool IsFull() const;
void Enqueue(ItemType newItem);
void Dequeue(ItemType& item);
private:
int length;
HeapType<ItemType> items;
int maxItems;
};
template<class ItemType>
void PQType<ItemType>::Enqueue(ItemType newItem)
{
if (length == maxItems)
throw FullPQ();
else
{
length++;
items.elements[length - 1] = newItem;
items.ReheapUp(0, length - 1);
}
}
template<class ItemType>
void PQType<ItemType>::Dequeue(ItemType& item)
{
if (length == 0)
throw EmptyPQ();
else
{
item = items.elements[0];
items.elements[0] = items.elements[length - 1];
length--;
items.ReheapDown(0, length - 1);
}
}
template<class ItemType>
PQType<ItemType>::PQType(int max)
{
maxItems = max;
items.elements = new ItemType[max];
length = 0;
}
template<class ItemType>
void PQType<ItemType>::MakeEmpty()
{
length = 0;
}
template<class ItemType>
PQType<ItemType>::~PQType()
{
delete[] items.elements;
}
template<class ItemType>
void PQType<ItemType>::Dequeue(ItemType& item)
{
if (length == 0)
throw EmptyPQ();
else
{
item = items.elements[0];
items.elements[0] = items.elements[length - 1];
length--;
items.ReheapDown(0, length - 1);
}
}
template<class ItemType>
void PQType<ItemType>::Enqueue(ItemType newItem)
{
if (length == maxItems)
throw FullPQ();
else
{
length++;
items.elements[length - 1] = newItem;
items.ReheapUp(0, length - 1);
}
}
template<class ItemType>
bool PQType<ItemType>::IsFull() const
{
return length == maxItems;
}
template<class ItemType>
bool PQType<ItemType>::IsEmpty() const
{
return length == 0;
}
Implementation | Enqueue | Dequeue |
---|---|---|
Heap | O(logN) | O(logN) |
Linked-List | O(N) | O(N) |
BST (Balanced) | O(logN) | O(logN) |
BST (Skewed) | O(N) | O(N) |
template<class ItemType>
void HeapType<ItemType>::ReheapDown_re(int root, int bottom)
{
int maxChild;
int leftChild = root * 2 + 1;
int rightChild = root * 2 + 2;
if (leftChild <= bottom)
{
if (leftChild == bottom)
maxChild = leftChild;
else
{
if (elements[leftChild] <= elements[rightChild])
maxChild = rightChild;
else
maxChild = leftChild;
}
if (elements[maxChild] > elements[root])
{
swap(elements[maxChild], elements[root]);
ReheapDown_re(maxChild, bottom);
}
}
}
template<class ItemType>
void HeapType<ItemType>::ReheapDown(int root, int bottom)
{
int maxChild, leftChild, rightChild;
bool reheaped = false;
leftChild = root * 2 + 1;
while (leftChild <= bottom && !reheaped) {
if (leftChild == bottom)
maxChild = leftChild;
else {
rightChild = root * 2 + 2;
maxChild = (elements[leftChild] <= elements[rightChild]) ? elements[rightChild] : elements[leftChild];
}
if (elements[root] < elements[maxChild]) {
Swap(elements[root], elements[maxChild]);
root = maxChild;
leftChild = root * 2 + 1;
}
else
reheaped = true;
}
}
template<class ItemType>
void HeapType<ItemType>::ReheapUp(int root, int bottom)
{
int parent;
if (bottom > root)
{
parent = (bottom - 1) / 2;
if (elements[parent] < elements[bottom])
{
swap(elements[parent], elements[bottom]);
ReheapUp(root, parent);
}
}
}
template<class ItemType>
void HeapType<ItemType>::ReheapUp(int root, int bottom)
{
int parent;
bool reheaped = false;
while (bottom > root && !reheaped) {
parent = (bottom - 1) / 2;
if (elements[parent] < elements[bottom]) {
Swap(elements[parent], elements[bottom]);
bottom = parent;
}
else
reheaped = true;
}
}
Adjacency Matrix: Array 기본으로 구현
Vertices: Vertex에 해당하는 index를 알려 주는 1차원 배열
Adjacency Matrix: Vertex끼리의 edge 존재 유무와 weight를 알려 주는 2차원 배열
Array Based이기 때문에 충분한 크기를 설정해 둬야 함
Vertices의 index를 정렬해 놓으면 Searching 시간을 줄일 수 있음
Adjacency List: Linked-List로 구현
Compare
template<class VertexType>
class GraphType
{
public:
GraphType();
GraphType(int maxV);
~GraphType();
void AddVertex(VertexType vertex);
void AddEdge(VertexType fromVertex, VertexType toVertex, int weight);
int WeightIs(VertexType fromVertex, VertexType toVertex);
void ClearMarks();
bool IsMarked(VertexType vertex);
void MarkVertex(VertexType vertex);
void GetToVertices(VertexType vertex, QueType<VertexType>& adjVertices);
private:
int numVertices;
int maxVertices;
VertexType* vertices;
int edges[50][50];
bool* marks;
};
template<class VertexType>
GraphType<VertexType>::GraphType()
{
numVertices = 0;
maxVertices = 50;
vertices = new VertexType[50];
marks = new bool[50];
}
template<class VertexType>
GraphType<VertexType>::~GraphType()
{
delete[] vertices;
for (int i - 0; i < maxVertices; i++)
delete[] edges[i];
delete[] marks;
}
template<class VertexType>
void GraphType<VertexType>::AddVertex(VertexType vertex)
{
vertices[numVertices] = vertex;
for (int index = 0; index < numVertices; index++)
{
edges[numVertices][index] = NULL_EDGE;
edges[index][numVertices] = NULL_EDGE;
}
numVertices++;
}
template<class VertexType>
int IndexIs(VertexType* vertices, VertexType vertex)
{
int index = 0;
while (!(vertex == vertices[index]))
index++;
return index;
}
template<class VertexType>
void GraphType<VertexType>::AddEdge(VertexType fromVertex, VertexType toVertex, int weight)
{
int row;
int col;
row = IndexIs(vertices, fromVertex);
col = IndexIs(vertices, toVertex);
edges[row][col] = weight;
}
template<class VertexType>
int GraphType<VertexType>::WeightIs (VertexType fromVertex, VertexType toVertex)
{
int row;
int col;
row = IndexIs(vertices, fromVertex);
col = IndexIs(vertices, toVertex);
return edges[row][col];
}
template<class VertexType>
void GraphType<VertexType>::ClearMarks()
{
for (int i = 0; i < numVertices; i++)
marks[i] = false;
}
template<class VertexType>
bool GraphType<VertexType>::IsMarked(VertexType vertex)
{
index = IndexIs(vertices, vertex);
return (marks[index] == true);
}
template<class VertexType>
void GraphType<VertexType>::MarkVertex(VertexType vertex)
{
index = IndexIs(vertices, vertex);
marks[index] = true;
}
template<class VertexType>
void GraphType<VertexType>::GetToVertices(VertexType vertex, QueType<VertexType>& adjVertices)
{
int fromIndex;
int toIndex;
fromIndex = IndexIs(vertices, vertex);
for (toIndex = 0; toIndex < numVertices; toIndex++)
if (edges[fromIndex][toIndex] != NULL_EDGE)
adjVertices.Enqueue(vertices[toIndex]);
}
template<class VertexType>
void GraphType<VertexType>::DepthFirstSearch(VertexType startVertex, VertexType endVertex)
{
StackType<VertexType> stack;
QueType<VertexType> vertexQ;
bool found = false;
VertexType vertex;
VertexType item;
ClearMarks();
stack.Push(startVertex);
while (!stack.IsEmpty() && !found)
{
stack.Pop(vertex);
if (vertex == endVertex)
{
std::cout << vertex << std::endl;
found = true;
}
else
{
if (!IsMarked(vertex))
{
MarkVertex(vertex);
std::cout << vertex << std::endl;
GetToVertices(vertex, vertexQ);
while (!vertexQ.IsEmpty())
{
vertexQ.Dequeue(item);
if (!IsMarked(item))
stack.Push(item);
}
}
}
}
if (!found)
std::cout << "Path not found." << std::endl;
}
template<class VertexType>
void GraphType<VertexType>::BreathFirstSearch(VertexType startVertex, VertexType endVertex)
{
QueType<VertexType> queue;
QueType<VertexType> vertexQ;
bool found = false;
VertexType vertex;
VertexType item;
ClearMarks();
queue.Enqueue(startVertex);
while (!queue.IsEmpty() && !found)
{
queue.Dequeue(vertex);
if (vertex == endVertex)
{
std::cout << vertex << std::endl;
found = true;
}
else
{
if (!IsMarked(vertex))
{
MarkVertex(vertex);
std::cout << vertex << std::endl;
GetToVertices(vertex, vertexQ);
while (!vertexQ.IsEmpty())
{
vertexQ.Dequeue(item);
if (!IsMarked(item))
queue.Enqueue(item);
}
}
}
}
if (!found)
std::cout << "Path not found." << std::endl;
}
template<class VertexType>
void GraphType<VertexType>::DeleteEdge(VertexType fromVertex, VertexType toVertex)
{
int row;
int col;
row = IndexIs(vertices, fromVertex);
col = IndexIs(vertices, toVertex);
edges[row][col] = NULL_EDGE;
}
template<class VertexType>
bool GraphType<VertexType>::DepthFirstSearch_re(VertexType startVertex, VertexType endVertex)
{
QueType<VertexType> vertexQ;
VertexType vertex;
if (startVertex == endVertex)
{
std::cout << endVertex << std::endl;
return true;
}
GetToVertices(startVertex, vertexQ);
while (!vertexQ.IsEmpty())
{
vertexQ.Dequeue(vertex);
if (vertex != startVertex)
{
if (DepthFirstSearch_re(vertex, endVertex))
{
std::cout << startVertex << std::endl;
return true;
}
}
else
continue;
}
return false;
}
class HeapType:
elements = []
numElemnents = 0
def ReHeapUp(self, root, bottom):
reheaped = False
while(bottom > root and not reheaped):
parent = (bottom - 1) / 2
if (self.elements[parent] < self.elements[bottom]):
self.elements[parent], self.elements[bottom] = self.elements[bottom], self.elements[parent]
bottom = parent
else:
reheaped = True
def ReHeapDown(self, root, bottom):
reheaped = False
leftChild = root * 2 + 1
while(leftChild <= bottom and not reheaped):
if(leftChild == bottom):
maxChild = leftChild
else:
rightChild = root * 2 + 2
if (self.elements[leftChild] <= self.elements[rightChild]):
maxChild = rightChild
else:
maxChild = leftChild
if(self.elements[root] < self.elements[maxChild]):
self.elements[root], self.elements[maxChild] = self.elements[maxChild], self.elements[root]
root = maxChild
leftChild = root * 2 + 1
else:
reheaped = True
class HeapType:
elements = []
numElemnents = 0
def ReHeapUp(self, root, bottom):
reheaped = False
while(bottom > root and not reheaped):
parent = (bottom - 1) / 2
if (self.elements[parent] > self.elements[bottom]):
self.elements[parent], self.elements[bottom] = self.elements[bottom], self.elements[parent]
bottom = parent
else:
reheaped = True
def ReHeapDown(self, root, bottom):
reheaped = False
leftChild = root * 2 + 1
while(leftChild <= bottom and not reheaped):
if(leftChild == bottom):
minChild = leftChild
else:
rightChild = root * 2 + 2
if (self.elements[leftChild] >= self.elements[rightChild]):
minChild = rightChild
else:
minChild = leftChild
if(self.elements[root] > self.elements[minChild]):
self.elements[root], self.elements[minChild] = self.elements[minChild], self.elements[root]
root = minChild
leftChild = root * 2 + 1
else:
reheaped = True
from Max_Heap import *
MAX_ITEMS = 100
class PQType():
def __init__(self):
self.items = HeapType()
self.length = 0
def make_empty(self):
self.length = 0
def enqueue(self, newitem):
if(not self.length == MAX_ITEMS):
self.length += 1
self.items.elements[self.length-1] = newitem
self.items.ReHeapUp(0, self.length-1)
def dequeue(self):
if(not self.length == 0):
item = self.items.elements[0]
self.items.elements[0] = self.items.elements[self.length-1]
self.length -= 1
self.items.ReHeapDown(0, self.length -1)
return item
def is_full(self):
return self.length == MAX_ITEMS
def is_empty(self):
return self.length == 0
from QueType import *
from StackType import *
NULL_EDGE = 0
def index_is(vertices, vertex):
index = 0
while index < len(vertices) and vertex != vertices[index]:
index += 1
if not index < len(vertices):
return -1
else:
return index
class GraphType:
def __init__(self, maxV=50):
self.numVertices = 0
self.maxVertices = maxV
self.vertices = [None] * maxV
self.edges = [[NULL_EDGE] * maxV for _ in range(maxV)]
self.marks = [None] * maxV
def add_vertex(self, vertex):
self.vertices[self.numVertices] = vertex
for index in range(self.numVertices):
self.edges[self.numVertices][index] = NULL_EDGE
self.edges[index][self.numVertices] = NULL_EDGE
self.numVertices += 1
def add_edge(self, fromVertex, toVertex, weight):
row = index_is(self.vertices, fromVertex)
col = index_is(self.vertices, toVertex)
self.edges[row][col] = weight
def weight_is(self, fromVertex, toVertex):
row = index_is(self.vertices, fromVertex)
col = index_is(self.vertices, toVertex)
return self.edges[row][col]
def get_to_vertices(self, vertex, adjVertices):
fromIndex = index_is(self.vertices, vertex)
for toIndex in range(self.numVertices):
if(self.edges[fromIndex][toIndex] != NULL_EDGE):
adjVertices.enqueue(self.vertices[toIndex])
def clear_marks(self):
for index in range(self.numVertices):
self.marks[index] = False
def is_marked(self, vertex):
index = index_is(self.vertices, vertex)
return self.marks[index]
def mark_vertex(self, vertex):
index = index_is(self.vertices, vertex)
self.marks[index] = True
def delete_edge(self, fromVertex, toVertex):
row = index_is(self.vertices, fromVertex)
col = index_is(self.vertices, toVertex)
self.edges[row][col] = NULL_EDGE
from GraphType import *
def depth_first_search(graph, startVertex, endVertex):
stack = StackType()
vertexQ = QueType()
found = False
graph.clear_marks()
stack.push(startVertex)
while(not stack.is_empty() and not found):
vertex = stack.top()
stack.pop()
if(vertex == endVertex):
print(endVertex)
found = True
else:
if(not graph.is_marked(vertex)):
graph.mark_vertex(vertex)
print(vertex)
graph.get_to_vertices(vertex, vertexQ)
while(not vertexQ.is_empty()):
item = vertexQ.dequeue()
if(not graph.is_marked(item)):
stack.push(item)
if(not found):
print("Path not found.")
from GraphType import *
def breadth_first_search(graph, startVertex, endVertex):
queue = QueType()
vertexQ = QueType()
found = False
graph.clear_marks()
queue.enqueue(startVertex)
while(not queue.is_empty() and not found):
vertex = queue.dequeue()
if(vertex == endVertex):
print(endVertex)
found = True
else:
if(not graph.is_marked(vertex)):
graph.mark_vertex(vertex)
print(vertex)
graph.get_to_vertices(vertex, vertexQ)
while(not vertexQ.is_empty()):
item = vertexQ.dequeue()
if(not graph.is_marked(item)):
queue.enqueue(item)
if(not found):
print("Path not found.")