• toc {:toc}

Heap

  • 루트둜 올수둝 더 ν¬κ±°λ‚˜ μž‘μ•„μ§€λŠ” μ™„μ „ 이진 트리

  • νž™ μ„±μ§ˆ

    • νž™μ˜ 각 λ…Έλ“œμ— λŒ€ν•΄ λ…Έλ“œ 값은 μžμ‹μ˜ 값보닀 컀야 ν•œλ‹€.(Maxheap)
  • λ©”λͺ¨λ¦¬ νž™κ³Ό 연관성이 μžˆλŠ” 것은 μ•„λ‹ˆλ‹€.

  • λ£¨νŠΈκ°€ 항상 κ°€μž₯ 큰 κ°’μ΄κ±°λ‚˜ κ°€μž₯ μž‘μ€ 값이닀.

  • 루트 제거 β†’ κ°€μž₯ 큰 κ°’ μΆ”μΆœ

    • 리프 λ…Έλ“œ 쀑 κ°€μž₯ 였λ₯Έμͺ½ 값을 루트둜 λ³΅μ‚¬ν•˜κ³  리프 λ…Έλ“œ 값은 μ‚­μ œν•œλ‹€.
    • νž™ μ„±μ§ˆμ— 따라 ReheapDown을 톡해 μœ„μΉ˜λ₯Ό μ°Ύμ•„κ°„λ‹€.
template<class ItemType>
void HeapType<ItemType>::MAX_ReheapDown(int root, int bottom)
{
    int maxChild;
    int rightChild;
    int leftChild;
    
    leftChild = root * 2 + 1;
    rightChild = root * 2 + 2;
 
	if (leftChild <= bottom){
	    if(leftChild == bottom){ // μžμ‹μ΄ 1개 μžˆλŠ” 경우
	        maxChild = leftChild;
	    }
	    else{  // μžμ‹μ΄ 2개 μžˆλŠ” 경우
	        if(elements[leftChild] <= elements[rightChild]){
	            maxChild = rightChild;
	        }
	        else{
	            maxChild = leftChild;
	        }
	    }
	    if(elements[maxChild] == null_val) return;
	    if(elements[root] < elements[maxChild]){
	        Swap(elements[root], elements[maxChild]);
	        MAX_ReheapDown(maxChild, bottom);
	    }
	}
}
  • λ…Έλ“œ μ‚½μž…
    • λ§ˆμ§€λ§‰ λΉˆμΉΈμ— λ„£κ³  μœ„λ‘œ μ˜¬λ¦°λ‹€.
template<class ItemType>
void HeapType<ItemType>::MAX_ReheapUp(int root, int bottom)
{
    int parent;
 
    if(bottom > root){  // treeκ°€ λΉ„μ–΄μžˆμ§€ μ•Šλ‹€λ©΄
        parent = (bottom - 1) / 2;
        if(elements[bottom] > elements[parent]){
            Swap(elements[bottom], elements[parent]);
            MAX_ReheapUp(root, parent);
        }
    }
}

Priority Queue

  • λ‹€μŒ λ°©μ‹μœΌλ‘œ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€.
  • Unsorted Listv - Dequeue β†’ 전체 리슀트λ₯Ό 탐색해야 ν•˜λ―€λ‘œ O(N)
  • Array-Based Sorted List β†’ Enqueue λΉ„μš©μ΄ λΉ„μ‹Έλ‹€ O(N)
  • Linked Sorted List β†’ Enqueue λΉ„μš©μ΄ λΉ„μ‹Έλ‹€ O(N)
  • Binary Search Tree β†’ ν‰κ· μ μœΌλ‘œ Enqueue, Dequeueκ°€ O(logN)
  • Heap β†’ μ΅œμ•…μ˜ κ²½μš°μ—λ„ O(logN) 이 보μž₯λœλ‹€.
class FullPQ(){};
class EmptyPQ(){};
template<class ItemType>
class PQType
{
public:
	PQType(int);
	~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>
PQType<ItemType>::PQType(int max){
	maxItems = max;
	items = new ItemType[max];
	length = 0;
}
template<class ItemType>
void PQType<ItemType>::MakeEmpty(){
	length = 0;
}
template<class ItemType>
PQType<ItemType>::~PQType(){
	delete [] items;
}
 
template<class ItemType>
void PQType<ItemType>::Dequeue(ItemType& item)
{
	if (length == 0)
		throw EmptyPQ();
	else {
		item = items[0];
		items[0] = items[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[length-1] = newItem;
		items.ReheapUp(0, length-1);
	}
}
  • Enqueue, DequeueλŠ” νž™μ˜ λ…Έλ“œλ₯Ό μΆ”κ°€, μ‚­μ œν•˜λŠ” 것과 κ°™λ‹€.

Graph

  • 무방ν–₯ κ·Έλž˜ν”„

  • λ°©ν–₯ κ·Έλž˜ν”„

  • κ·Έλž˜ν”„ ν‘œν˜„

    • 인접 ν–‰λ ¬
      • λ©”λͺ¨λ¦¬ : O((V의 개수)^2)
      • κ°’μ˜ 확인이 λΉ λ₯΄λ‹€. O(1)
    • 인접 리슀트
      • λ©”λͺ¨λ¦¬ : O((V의 개수) + (E의 개수))
      • 동적 할당이 κ°€λŠ₯ν•˜λ‹€.
      • νŠΉμ • λ…Έλ“œμ™€ μΈμ ‘ν•œ λ…Έλ“œλ₯Ό λΉ λ₯΄κ²Œ μ ‘κ·Όν•  수 μžˆλ‹€.
      • μ™„μ „ κ·Έλž˜ν”„μΈ 경우 각 list λ³„λ‘œ n-1개의 μ—£μ§€λ₯Ό κ°€μ§€κΈ° λ•Œλ¬Έμ— 행렬에 λΉ„ν•΄ 이득이 λ˜μ§€ μ•ŠλŠ”λ‹€.
const int NULL_EDGE = 0;
template<class VertexType>
class GraphType {
public:
	GraphType(int);
	~GraphType();
	void MakeEmpty();
	bool IsEmpty() const;
	bool IsFull() const;
	void AddVertex(VertexType);
	void AddEdge(VertexType, VertexType, int);
	int WeightIs(VertexType, VertexType);
	void GetAdjacents(VertexType,QueType<VertexType>&);
	void ClearMarks();
	void MarkVertex(VertexType);
	bool IsMarked(VertexType) const;
private:
	int numVertices;
	int maxVertices;
	VertexType* vertices;
	int **edges; // 이쀑 포인터 -> ν–‰λ ¬
	bool* marks;
};
 
template<class VertexType>
GraphType<VertexType>::GraphType(int maxV){
	numVertices = 0;
	maxVertices = maxV;
	vertices = new VertexType[maxV]; 
	edges = new int[maxV];   // 배열을 동적 ν• λ‹Ή λ°›λŠ”λ‹€.
	for(int i = 0; i < maxV; i++)
		edges[i] = new int[maxV];
		marks = new bool[maxV];
}
 
template<class VertexType>
GraphType<VertexType>::~GraphType(){
	delete [] vertices;
	for(int i = 0; i < maxVertices; i++)
		delete [] edges[i];
	delete [] edges;
	delete [] marks;
}
 
void GraphType<VertexType>::AddVertex(VertexType vertex){
	vertices[numVertices] = vertex;  // 이름 λͺ¨μŒμ— μΆ”κ°€
	for(int index = 0; index < numVertices; index++) {
		// μ—£μ§€ κ°€μ€‘μΉ˜μ— NULLκ°’ μΆ”κ°€
		edges[numVertices][index] = NULL_EDGE;
		edges[index][numVertices] = NULL_EDGE;
	}
	numVertices++;
}
template<class VertexType>
void GraphType<VertexType>::AddEdge(VertexType fromVertex,
									VertexType toVertex, int weight){
	int row;
	int column;
	row = IndexIs(vertices, fromVertex);
	col = IndexIs(vertices, toVertex);
	edges[row][col] = weight;
}
 
template<class VertexType>
int IndexIs(VertexType* vertices, VertexType vertex)
{
    int index = 0;
    while (!(vertex == vertices[index]))
        index++;
    return index;
}
 
template<class VertexType>
int GraphType<VertexType>::WeightIs(VertexType fromVertex,
									VertexType toVertex){
	int row;
	int column;
	row = IndexIs(vertices, fromVertex);
	col = IndexIs(vertices, toVertex);
	return edges[row][col];
}

Searching

  • DFS(Depth First Search) - 깊이 μš°μ„  탐색. μŠ€νƒμœΌλ‘œ κ΅¬ν˜„λœλ‹€.
template<class VertexType>
void GraphType<VertexType>::GetAdjacents(VertexType vertex, 
										QueTye<VertexType>& adjvertexQ){
	int fromIndex;
	int toIndex;
	fromIndex = IndexIs(vertices, vertex);
	for(toIndex = 0; toIndex < numVertices; toIndex++)
		if(edges[fromIndex][toIndex] != NULL_EDGE)
			adjvertexQ.Enqueue(vertices[toIndex]);
}
 
template <class ItemType>
void DepthFirstSearch(GraphType<VertexType> graph,
VertexType startVertex, VertexType endVertex)
{
	StackType<VertexType> stack;
	QueType<VertexType> vertexQ;
	bool found = false;
	VertexType vertex;
	VertexType item;
	graph.ClearMarks();
	stack.Push(startVertex);
	do {
		stack.Pop(vertex);
		if(vertex == endVertex)
			found = true;
		else {
			if(!graph.IsMarked(vertex)) {
				graph.MarkVertex(vertex);
				graph.GetAdjacents(vertex, vertexQ);
 
				while(!vertexQ.IsEmpty()) {
					vertexQ.Dequeue(item);
					if(!graph.IsMarked(item))
						stack.Push(item);
			}
		}
	} while(!stack.IsEmpty() && !found);
 
	if(!found)
	cout << "Path not found" << endl;
}
  • BFS(Breadth First Search) - λ„ˆλΉ„ μš°μ„  탐색. 큐둜 κ΅¬ν˜„λœλ‹€.
template<class VertexType>
void BreadthFirtsSearch(GraphType<VertexType> graph, 
					VertexType startVertex, VertexType endVertex);{
	QueType<VertexType> queue;
	QueType<VertexType> vertexQ;//
	bool found = false;
	VertexType vertex;
	VertexType item;
	graph.ClearMarks();
	queue.Enqueue(startVertex);
	do {
		queue.Dequeue(vertex);
		if(vertex == endVertex)
			found = true;
		else {
			if(!graph.IsMarked(vertex)) {
				graph.MarkVertex(vertex);
				graph.GetAdjacents(vertex, vertexQ);
 
				while(!vertxQ.IsEmpty()) {
					vertexQ.Dequeue(item);
					if(!graph.IsMarked(item))
						queue.Enqueue(item);
				}
			}
		}
	} while (!queue.IsEmpty() && !found);
	if(!found)
	cout << "Path not found" << endl;
}