언어 자료구조 알고리즘/디딤돌 알고리즘 (C언어)

[C언어 알고리즘] 6.2.8 깊이우선탐색(DFS) 알고리즘 소스 코드

언제나휴일 2016. 12. 1. 15:58
반응형

[C언어 알고리즘] 6.2.8 깊이우선탐색(DFS) 알고리즘 소스 코드


//common.h

#pragma once //헤더 파일을 한 번만 포함해서 컴파일

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <string.h>

#include <malloc.h>

#include <memory.h>

#include <time.h>

#pragma warning(disable:4996) //4996컴파일 경고 메시지 출력 해제

 



//Array.h

#pragma once

typedef void * Element;

typedef struct _Array Array;

struct _Array

{

        Element *base;

        int capacity;

        int usage;

};

typedef Element *Iterator;

 

Array *New_Array();

void Delete_Array(Array *arr);

void Array_SetSize(Array *arr,int capacity,Element data);

void Array_PushBack(Array *arr,Element data);

void Array_Insert(Array *arr,Iterator pos,Element data);

void Array_SetAt(Array *arr,int index,Element data);

Element Array_GetAt(Array *arr,int index);

Iterator Array_Begin(Array *arr);

Iterator Array_End(Array *arr);

void Array_Erase(Array *arr,Iterator pos);

 



//Array.c

#include "Array.h"

#include <malloc.h>

#include <memory.h>

Array *New_Array()

{

        Array *arr = 0;

        arr = (Array *)malloc(sizeof(Array));

        arr->base = 0;

        arr->capacity = arr->usage = 0;

        return arr;

}

void Delete_Array(Array *arr)

{

        if(arr->base)

        {

               free(arr->base);

        }

        free(arr);

}

void Array_SetSize(Array *arr,int capacity,Element data)

{             

        arr->capacity = capacity;

        arr->base = (Element *)realloc(arr->base,sizeof(Element)*arr->capacity);

        for(    ;arr->usage<arr->capacity; arr->usage++)

        {

               arr->base[arr->usage] = data;

        }

}

void Array_PushBack(Array *arr,Element data)

{

        Iterator at = Array_End(arr);

        Array_Insert(arr,at,data);

}

void Array_Insert(Array *arr,Iterator pos,Element data)

{

        int index = pos - arr->base;

        int mcount = arr->usage - index;

        if(arr->capacity == arr->usage)

        {

               if(arr->capacity)

               {

                       arr->capacity*=2;

               }

               else

               {

                       arr->capacity = 1;

               }

               arr->base = (Element *)realloc(arr->base,sizeof(Element)*arr->capacity);

        }

        memcpy(arr->base+index+1,arr->base+index,sizeof(Element)*mcount);

        arr->base[index] = data;

        arr->usage++;

}

void Array_SetAt(Array *arr,int index,Element data)

{

        if((index>=0)&&(index<arr->usage))

        {

               arr->base[index] = data;

        }

}

Element Array_GetAt(Array *arr,int index)

{

        if((index>=0)&&(index<arr->usage))

        {

               return arr->base[index];

        }

        return 0;

}

Iterator Array_Begin(Array *arr)

{

        return arr->base;

}

Iterator Array_End(Array *arr)

{

        return arr->base+arr->usage;

}

void Array_Erase(Array *arr,Iterator pos)

{

        int index = pos - arr->base;

        int mcount = arr->usage - index -1;

        memcpy(pos,pos+1,sizeof(Element)*mcount);

        arr->usage--;

}

 



//LinkedList.h

#pragma once

typedef void * Element;

typedef struct _Node Node;

typedef Node *Link;

struct _Node

{

        Link next;

        Link prev;

        Element data;

};

 

typedef struct _LinkedList LinkedList;

struct _LinkedList

{

        Link head;

        Link tail;

        int usage;

};

 

 

LinkedList *New_LinkedList();

void Delete_LinkedList(LinkedList *linkedlist);

void LinkedList_PushBack(LinkedList *linkedlist,Element data);

void LinkedList_Insert(LinkedList *linkedlist,Link pos,Element data);

Link LinkedList_Begin(LinkedList *linkedlist);

Link LinkedList_End(LinkedList *linkedlist);

void LinkedList_Erase(LinkedList *linkedlist,Link pos);

 



//LinkedList.c

#include "LinkedList.h"

#include <malloc.h>

#include <memory.h>

Link New_Node(Element data)

{

        Link link = (Link)malloc(sizeof(Node));

        link->data = data;

        link->next = link->prev = 0;

        return link;

}

void HangNode(Link link,Link pos)

{

        link->prev = pos->prev;

        link->next = pos;

        pos->prev->next = link;

        pos->prev = link;

}

void DisconnectNode(Link pos)

{

        pos->prev->next = pos->next;

        pos->next->prev = pos->prev;

}

LinkedList *New_LinkedList()

{

        LinkedList *linkedlist = 0;

        linkedlist = (LinkedList *)malloc(sizeof(LinkedList));

        linkedlist->head = New_Node(0);

        linkedlist->tail = New_Node(0);

        linkedlist->head->next = linkedlist->tail;

        linkedlist->tail->prev = linkedlist->head;

        linkedlist->usage = 0;

        return linkedlist;

}

void Delete_LinkedList(LinkedList *linkedlist)

{

        Link seek = linkedlist->head;

       

        while( seek != linkedlist->tail)

        {

               seek = seek->next;

               free(seek->prev);

        }

        free(linkedlist->tail);

        free(linkedlist);

}

void LinkedList_PushBack(LinkedList *linkedlist,Element data)

{

        LinkedList_Insert(linkedlist,linkedlist->tail,data);

}

void LinkedList_Insert(LinkedList *linkedlist,Link pos,Element data)

{

        Link link = New_Node(data);

        HangNode(link,pos);

        linkedlist->usage++;

}

Link LinkedList_Begin(LinkedList *linkedlist)

{

        return linkedlist->head->next;

}

Link LinkedList_End(LinkedList *linkedlist)

{

        return linkedlist->tail;

}

void LinkedList_Erase(LinkedList *linkedlist,Link pos)

{

        DisconnectNode(pos);

        linkedlist->usage--;

}

 



//EHStack.h

#pragma once

#include "LinkedList.h"

 

typedef LinkedList EHStack;

 

EHStack *New_EHStack();

void Delete_EHStack(EHStack *ehs);

void EHStack_Push(EHStack *ehs, Element data);

Element EHStack_Pop(EHStack *ehs);

int EHStack_IsEmpty(EHStack *ehs);

 



//EHStack.c

#include "EHStack.h"

#include <malloc.h>

#include <memory.h>

EHStack *New_EHStack()

{

        return New_LinkedList();

}

void Delete_EHStack(EHStack *ehs)

{

        Delete_LinkedList(ehs); 

}

void EHStack_Push(EHStack *ehs, Element data)

{

        LinkedList_PushBack(ehs,data);

}

Element EHStack_Pop(EHStack *ehs)

{

        Element element = 0;

        if( ! EHStack_IsEmpty(ehs))

        {

               Link last = LinkedList_End(ehs);

               last = last->prev;

               element = last->data;

               LinkedList_Erase(ehs,last);

        }

        return element;

}

int EHStack_IsEmpty(EHStack *ehs)

{

        return ehs->usage == 0;

}

 



//Graph.h

#pragma once

#include "Array.h"

typedef const char * Vertex;

typedef struct _Edge Edge;

struct _Edge

{

        Vertex ep1;

        Vertex ep2;

        int weight;

};

 

typedef struct _Graph Graph;

struct _Graph

{

        Array *vertexs;

        Array *edges;

};

 

Graph *New_Graph();

void Delete_Graph(Graph *graph);

int Graph_AddVertex(Graph *graph,Vertex pt);

int Graph_AddEdge(Graph *graph,Vertex ep1, Vertex ep2, int weight);

int Graph_ExistVertex(Graph *graph,Vertex pt);

int Graph_ExistEdge(Graph *graph,Vertex ep1, Vertex ep2);

void Graph_View(Graph *graph);

void Graph_ViewVertexs(Graph *graph);

void Graph_ViewEdges(Graph *graph);

void Graph_FindNeighvor(Graph *graph,Vertex ep, Array *neighvor);

int Graph_GetWeight(Graph *graph,Vertex ep1, Vertex ep2);

 



//Graph.c

#include "Graph.h"

#include <malloc.h>

#include <string.h>

#include <stdio.h>

Edge *New_Edge(Vertex ep1, Vertex ep2, int weight)

{

        Edge *edge = 0;

        edge = (Edge *)malloc(sizeof(Edge));

        edge->ep1 = ep1;

        edge->ep2 = ep2;

        edge->weight = weight;

        return edge;

}

Vertex Edge_AnOther(Edge *edge,Vertex pt)

{

        if(strcmp(edge->ep1,pt)==0)

        {

               return edge->ep2;

        }

        if(strcmp(edge->ep2,pt)==0)

        {

               return edge->ep1;

        }

        return "";

}

int Edge_Include(Edge *edge,Vertex pt)

{

        return (strcmp(edge->ep1,pt)==0)||(strcmp(edge->ep2,pt)==0);

}

Graph *New_Graph()

{

        Graph *graph = 0;

        graph = (Graph *)malloc(sizeof(Graph));

        graph->vertexs = New_Array();

        graph->edges = New_Array();

        return graph;

}

void Delete_Graph(Graph *graph)

{

        Iterator seek = 0, end = 0;

        Edge *edge = 0;

        seek = Array_Begin(graph->edges);

        end = Array_End(graph->edges);

        for(seek = seek; seek != end; ++seek)

        {

               edge = (Edge *)(*seek);

               free(edge);

        }

        Delete_Array(graph->vertexs);

        Delete_Array(graph->edges);

        free(graph);

}

int Graph_AddVertex(Graph *graph,Vertex pt)

{

        if(Graph_ExistVertex(graph,pt))

        {

               return 0;

        }

        Array_PushBack(graph->vertexs,(Element)pt);

        return 1;

}

int Graph_AddEdge(Graph *graph,Vertex ep1, Vertex ep2, int weight)

{

        if(Graph_ExistVertex(graph,ep1) && Graph_ExistVertex(graph,ep2))

        {

               Edge *edge = 0;

               if(Graph_ExistEdge(graph,ep1,ep2))

               {

                       return 0;

               }

               edge = New_Edge(ep1,ep2,weight);

               Array_PushBack(graph->edges,edge);

               return 1;

        }

        return 0;

}

int Graph_ExistVertex(Graph *graph,Vertex pt)

{

        Iterator seek = 0, end = 0;

        Vertex stored_pt = 0;

        seek = Array_Begin(graph->vertexs);

        end = Array_End(graph->vertexs);

        for(seek = seek; seek != end; ++seek)

        {

               stored_pt = (Vertex)(*seek);

               if(strcmp(stored_pt,pt)==0)

               {

                       return 1;

               }

        }

        return 0;

}

int Graph_ExistEdge(Graph *graph,Vertex ep1, Vertex ep2)

{

        Iterator seek = 0, end = 0;

        Edge *stored_eg = 0;

        seek = Array_Begin(graph->edges);

        end = Array_End(graph->edges);

        for(seek = seek; seek != end; ++seek)

        {

               stored_eg = (Edge *)(*seek);

               if(Edge_Include(stored_eg,ep1)&&Edge_Include(stored_eg,ep2))

               {

                       return 1;

               }

        }

        return 0;      

}

void Graph_View(Graph *graph)

{

        Graph_ViewVertexs(graph);

        Graph_ViewEdges(graph);

}

void Graph_ViewVertexs(Graph *graph)

{

        Iterator seek = 0, end = 0;

        Vertex pt = 0;

        printf("정점 개수:%d\n",graph->vertexs->usage);

        seek = Array_Begin(graph->vertexs);

        end = Array_End(graph->vertexs);

        for(seek = seek; seek != end; ++seek)

        {

               pt = (Vertex)(*seek);

               printf("%s\n",pt);

        }      

}

void Graph_ViewEdges(Graph *graph)

{

        Iterator seek = 0, end = 0;

        Edge *edge = 0;

        printf("간선 개수:%d\n",graph->edges->usage);

        seek = Array_Begin(graph->edges);

        end = Array_End(graph->edges);

        for(seek = seek; seek != end; ++seek)

        {

               edge = (Edge *)(*seek);

               printf("(%s ,%s):%d\n",edge->ep1,edge->ep2,edge->weight);

        }      

}

void Graph_FindNeighvor(Graph *graph,Vertex ep, Array *neighvor)

{

        Iterator seek = 0, end = 0;

        Edge *edge = 0;

       

        seek = Array_Begin(graph->edges);

        end = Array_End(graph->edges);

        for(seek = seek; seek != end; ++seek)

        {

               edge = (Edge *)(*seek);

               if(Edge_Include(edge,ep))

               {

                       Vertex opt;

                       opt = Edge_AnOther(edge,ep);

                       Array_PushBack(neighvor,(Element)opt);

               }

        }      

}

int Graph_GetWeight(Graph *graph,Vertex ep1, Vertex ep2)

{

        Iterator seek = 0, end = 0;

        Edge *edge = 0;

       

        seek = Array_Begin(graph->edges);

        end = Array_End(graph->edges);

        for(seek = seek; seek != end; ++seek)

        {

               edge = (Edge *)(*seek);

               if(Edge_Include(edge,ep1)&&Edge_Include(edge,ep2))

               {

                       return edge->weight;

               }

        }      

        return -1;

}

 



//Heuristic.h

#pragma once

#include "Array.h"

#include "Graph.h"

typedef struct _Heuristic Heuristic;

struct _Heuristic

{

    Array *exprs;

    Graph *graph;

    Vertex start;

    Vertex goal;

    int total_weight;

};

 

Heuristic *MakeInitHeuristic(Graph *graph,Vertex start,Vertex goal);

void DeleteHeuristic(Heuristic *now);

void FindNextHeuristics(Heuristic *now, Array *next_heus);

Vertex GetLastVertex(Heuristic *now);

int IsGoal(Heuristic *now);

void ViewHeuristic(Heuristic *now);

 



//Heuristic.c

#include "Heuristic.h"

#include <malloc.h>

#include <string.h>

#include <stdio.h>

 

int IsExistVertex(Heuristic *now, Vertex vt)

{

    Iterator seek=0, end=0;

    Vertex expr_vt;

    seek = Array_Begin(now->exprs);

    end = Array_End(now->exprs);

    for(seek = seek; seek != end; ++seek)

    {

        expr_vt = (Vertex)(*seek);

        if(strcmp(expr_vt,vt)==0)

        {

            return 1;

        }

    }

    return 0;

}

Heuristic *MakeNextHeu(Heuristic *now,Vertex vt)

{

    Heuristic *heu = 0;

    Iterator seek=0, end=0;

    Vertex expr_vt;

   

    heu = MakeInitHeuristic(now->graph,now->start,now->goal);

    seek = Array_Begin(now->exprs);

    end = Array_End(now->exprs);

    expr_vt = (Vertex)(*seek);

    for(seek++; seek != end; ++seek)

    {

        expr_vt = (Vertex)(*seek);

        Array_PushBack(heu->exprs,(Element)expr_vt);     

    }

    heu->total_weight = now->total_weight;

    heu->total_weight += Graph_GetWeight(heu->graph,expr_vt,vt);

    Array_PushBack(heu->exprs,(Element)vt);     

    return heu;

}

Heuristic *MakeInitHeuristic(Graph *graph,Vertex start,Vertex goal)

{

    Heuristic *heu = 0;

    heu = (Heuristic *)malloc(sizeof(Heuristic));

    heu->exprs = New_Array();

    heu->graph = graph;

    heu->start = start;

    heu->goal = goal;

    Array_PushBack(heu->exprs,(Element)start);

    heu->total_weight = 0;

    return heu;

}

void DeleteHeuristic(Heuristic *now)

{

    Delete_Array(now->exprs);

    free(now);

}

 

void FindNextHeuristics(Heuristic *now, Array *next_heus)

{

    Array *next_vts = 0;

    Iterator seek=0, end=0;

    Vertex next_vt;

    Heuristic *next;

   

    next_vts = New_Array();            

    Graph_FindNeighvor(now->graph,GetLastVertex(now),next_vts);

   

    seek = Array_Begin(next_vts);

    end = Array_End(next_vts);

    for(seek = seek; seek != end; ++seek)

    {

        next_vt = (Vertex)(*seek);

        if( !IsExistVertex(now,next_vt) )

        {

            next = MakeNextHeu(now,next_vt);

            Array_PushBack(next_heus,next);

        }              

    }

}

Vertex GetLastVertex(Heuristic *now)

{      

    Iterator end = Array_End(now->exprs);

    --end;

    return  (Vertex)(*end);     

}

int IsGoal(Heuristic *now)

{      

    return strcmp(now->goal,GetLastVertex(now))==0;

}

void ViewHeuristic(Heuristic *now)

{

    Iterator seek=0, end=0;

    printf("총 거리:%d ",now->total_weight);

    seek = Array_Begin(now->exprs);

    end = Array_End(now->exprs);

    for(seek = seek; seek != end; ++seek)

    {

        printf("%s ",(Vertex)*seek);

    }  

    printf("\n");

}

 



//Program.c

#include "Graph.h"

#include "EHStack.h"

#include "Heuristic.h"

Graph * InitSimulation()

{

    Graph *graph = New_Graph();         

    Graph_AddVertex(graph,"A");

    Graph_AddVertex(graph,"B");

    Graph_AddVertex(graph,"C");

    Graph_AddVertex(graph,"D");

    Graph_AddVertex(graph,"E");

    Graph_AddVertex(graph,"F");

    Graph_AddVertex(graph,"G");

    Graph_AddVertex(graph,"H");

   

    Graph_AddEdge(graph,"A","B",5);

    Graph_AddEdge(graph,"A","D",4);

    Graph_AddEdge(graph,"A","E",4);

    Graph_AddEdge(graph,"B","D",4);

    Graph_AddEdge(graph,"B","H",2);

    Graph_AddEdge(graph,"C","D",2);

    Graph_AddEdge(graph,"C","G",3);

    Graph_AddEdge(graph,"D","H",5);

    Graph_AddEdge(graph,"D","E",3);

    Graph_AddEdge(graph,"D","F",3);

    Graph_AddEdge(graph,"E","F",3);

    Graph_AddEdge(graph,"F","G",6);

    Graph_AddEdge(graph,"G","H",3);

   

    Graph_View(graph);

    return graph;              

}

int main()

{

    EHStack *ehs = 0;

    Heuristic *heu = 0;

    Graph *graph = 0;

    Array *next_heus = 0;

    Iterator seek=0, end=0;

   

    graph = InitSimulation();

    ehs = New_EHStack();

    heu = MakeInitHeuristic(graph,"A","H");

    EHStack_Push(ehs,heu);

    while( ! EHStack_IsEmpty(ehs) )

    {

        heu = (Heuristic *)EHStack_Pop(ehs);

        next_heus = New_Array();

        FindNextHeuristics(heu,next_heus);

        seek = Array_Begin(next_heus);

        end = Array_End(next_heus);

        for(seek=seek; seek != end; ++seek)

        {

            heu = (Heuristic *)(*seek);

            if(IsGoal(heu))

            {

                ViewHeuristic(heu);

                DeleteHeuristic(heu);

            }

            else

            {

                EHStack_Push(ehs,heu);

            }

        }

        Delete_Array(next_heus);

    }

   

    Delete_Graph(graph);

    Delete_EHStack(ehs);

    return 0;

}

반응형