263 lines
6.2 KiB
C
263 lines
6.2 KiB
C
|
/* vim: set sw=4 ts=4 si et: */
|
|||
|
|
|||
|
#include "connexcomponent.h"
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
*
|
|||
|
* LIST OPERATIONS
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
#define DEBUG_APPEND 0
|
|||
|
#define DEBUG_INSERT 0
|
|||
|
#define DEBUG (DEBUG_APPEND | DEBUG_INSERT)
|
|||
|
|
|||
|
ConnexComponentList_t connexcomponentlist_create(){
|
|||
|
ConnexComponentList_t result = NULL;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
void connexcomponentlist_destroy(ConnexComponentList_t * list){
|
|||
|
ConnexComponentItem_t * ptr = *list;
|
|||
|
if (ptr != NULL){
|
|||
|
if (ptr->next != NULL){
|
|||
|
connexcomponentlist_destroy(&(ptr->next));
|
|||
|
ptr->next = NULL;
|
|||
|
}
|
|||
|
connexcomponentitem_destroy(ptr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentItem_t * connexcomponentlist_find_item_with_node(
|
|||
|
ConnexComponentList_t list,
|
|||
|
nodeindex_t nodeidx)
|
|||
|
{
|
|||
|
ConnexComponentItem_t * result = NULL;
|
|||
|
|
|||
|
ConnexComponentItem_t * curptr = list;
|
|||
|
while(curptr != NULL){
|
|||
|
if (connexcomponentitem_contains_node(curptr, nodeidx)){
|
|||
|
result = curptr;
|
|||
|
break;
|
|||
|
}
|
|||
|
curptr = curptr -> next;
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentList_t connexcomponentlist_insert_edge(
|
|||
|
ConnexComponentList_t list,
|
|||
|
nodeindex_t node_one,
|
|||
|
nodeindex_t node_two)
|
|||
|
{
|
|||
|
bool one_created = false;
|
|||
|
bool two_created = false;
|
|||
|
ConnexComponentList_t result = list;
|
|||
|
|
|||
|
ConnexComponentItem_t * cci_one =
|
|||
|
connexcomponentlist_find_item_with_node(list, node_one);
|
|||
|
if (NULL == cci_one){
|
|||
|
one_created = true;
|
|||
|
/* on ajoute le premier noeud de l'edge
|
|||
|
* dans la liste des composantes connexes
|
|||
|
*/
|
|||
|
/* on fait pointer cci_one vers la composante en question */
|
|||
|
pDEBUG("Node %ld not found in existing component\n", node_one);
|
|||
|
cci_one = connexcomponentitem_create_from_node(node_one);
|
|||
|
if (DEBUG_INSERT) {
|
|||
|
pDEBUG("Created component:\n");
|
|||
|
connexcomponentitem_display(cci_one);
|
|||
|
}
|
|||
|
|
|||
|
// result = connexcomponentlist_append_component(
|
|||
|
// result,
|
|||
|
// cci_one);
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentItem_t * cci_two =
|
|||
|
connexcomponentlist_find_item_with_node(list, node_two);
|
|||
|
if (NULL == cci_two){
|
|||
|
two_created = true;
|
|||
|
/* on ajoute le premier noeud de l'edge
|
|||
|
* dans la liste des composantes connexes
|
|||
|
*/
|
|||
|
/* on fait pointer cci_one vers la composante en question */
|
|||
|
pDEBUG("Node %ld not found in existing component\n", node_two);
|
|||
|
cci_two = connexcomponentitem_create_from_node(node_two);
|
|||
|
if (DEBUG_INSERT) {
|
|||
|
pDEBUG("Created component:\n");
|
|||
|
connexcomponentitem_display(cci_one); }
|
|||
|
|
|||
|
// result = connexcomponentlist_append_component(
|
|||
|
// result,
|
|||
|
// cci_two);
|
|||
|
}
|
|||
|
|
|||
|
if (cci_one != cci_two) {
|
|||
|
ConnexComponentItem_t * cci_merge = connexcomponentitem_create_from_merge(cci_one, cci_two);
|
|||
|
|
|||
|
/* on efface les deux pr<70>c<EFBFBD>dents */
|
|||
|
if (!one_created) { result = connexcomponentlist_remove_component(result, cci_one); }
|
|||
|
if (!two_created) { result = connexcomponentlist_remove_component(result, cci_two); }
|
|||
|
|
|||
|
/* on ajoute le nouveau */
|
|||
|
result = connexcomponentlist_append_component(result, cci_merge);
|
|||
|
|
|||
|
if (cci_one) { connexcomponentitem_destroy(cci_one); cci_one = NULL; }
|
|||
|
if (cci_two) { connexcomponentitem_destroy(cci_two); cci_two = NULL; }
|
|||
|
} else {
|
|||
|
/* les deux sont egales */
|
|||
|
if (cci_one) { connexcomponentitem_destroy(cci_one); cci_one = NULL; }
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentList_t connexcomponentlist_append_component(
|
|||
|
ConnexComponentList_t list,
|
|||
|
ConnexComponentItem_t * item
|
|||
|
)
|
|||
|
{
|
|||
|
ConnexComponentList_t head = list;
|
|||
|
|
|||
|
if (DEBUG_APPEND) {
|
|||
|
pDEBUG("PRE-append\n");
|
|||
|
connexcomponentlist_display(head);
|
|||
|
}
|
|||
|
|
|||
|
item->next = NULL;
|
|||
|
item->prev = NULL;
|
|||
|
|
|||
|
if (head == NULL){
|
|||
|
head = item;
|
|||
|
} else {
|
|||
|
item->next = head;
|
|||
|
head->prev = item;
|
|||
|
head = item;
|
|||
|
}
|
|||
|
|
|||
|
if (DEBUG_APPEND){
|
|||
|
pDEBUG("POST-append\n");
|
|||
|
connexcomponentlist_display(head);
|
|||
|
}
|
|||
|
|
|||
|
return head;
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentList_t connexcomponentlist_remove_component(
|
|||
|
ConnexComponentList_t list,
|
|||
|
ConnexComponentItem_t * item
|
|||
|
)
|
|||
|
{
|
|||
|
ConnexComponentList_t head = list;
|
|||
|
ConnexComponentItem_t * previtem = item->prev;
|
|||
|
ConnexComponentItem_t * nextitem = item->next;
|
|||
|
|
|||
|
if (NULL != nextitem) { nextitem->prev = NULL; }
|
|||
|
if (NULL != previtem){ previtem->next = NULL; }
|
|||
|
|
|||
|
if (NULL == previtem){
|
|||
|
/* si en tete de liste */
|
|||
|
/* on coupe les liens */
|
|||
|
/* on re-link la tete */
|
|||
|
head = nextitem;
|
|||
|
} else if (NULL == nextitem){
|
|||
|
/* sinon si en fin de liste */
|
|||
|
/* on coupe les liens */
|
|||
|
} else {
|
|||
|
/* sinon cas normal */
|
|||
|
previtem->next = NULL;
|
|||
|
nextitem->prev = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* on coupe les liens */
|
|||
|
item->next = NULL;
|
|||
|
item->prev = NULL;
|
|||
|
|
|||
|
return head;
|
|||
|
}
|
|||
|
|
|||
|
void connexcomponentlist_display(ConnexComponentList_t list)
|
|||
|
{
|
|||
|
ConnexComponentItem_t * curptr = list;
|
|||
|
|
|||
|
printf("All connex components follow:\n");
|
|||
|
while (curptr != NULL){
|
|||
|
connexcomponentitem_display(curptr);
|
|||
|
curptr = curptr->next;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
*
|
|||
|
* ITERM OPERATIONS
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
ConnexComponentItem_t * connexcomponentitem_create()
|
|||
|
{
|
|||
|
ConnexComponentItem_t * result =
|
|||
|
(ConnexComponentItem_t *) malloc (sizeof(ConnexComponentItem_t));
|
|||
|
result->list = nodesetlist_create();
|
|||
|
result->prev = NULL;
|
|||
|
result->next = NULL;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentItem_t * connexcomponentitem_create_from_node(
|
|||
|
nodeindex_t node_idx
|
|||
|
)
|
|||
|
{
|
|||
|
ConnexComponentItem_t * result = connexcomponentitem_create();
|
|||
|
result->list = nodesetlist_create();
|
|||
|
result->list = nodesetlist_insert_node(result->list, node_idx);
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
ConnexComponentItem_t * connexcomponentitem_create_from_merge(
|
|||
|
ConnexComponentItem_t * item_one,
|
|||
|
ConnexComponentItem_t * item_two
|
|||
|
)
|
|||
|
{
|
|||
|
ConnexComponentItem_t * result = connexcomponentitem_create();
|
|||
|
|
|||
|
// copy data from item_one
|
|||
|
result->list = nodesetlist_merge (result->list, item_one->list);
|
|||
|
// copy data from item_two
|
|||
|
result->list = nodesetlist_merge (result->list, item_two->list);
|
|||
|
|
|||
|
/*
|
|||
|
printf("connexcomponentitem_create_from_merge -- MERGING COMPONENT-ITEMS\n");
|
|||
|
connexcomponentitem_display(item_one);
|
|||
|
printf("connexcomponentitem_create_from_merge -- AND\n");
|
|||
|
connexcomponentitem_display(item_two);
|
|||
|
printf("connexcomponentitem_create_from_merge -- GIVES\n");
|
|||
|
connexcomponentitem_display(result);
|
|||
|
*/
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
void connexcomponentitem_destroy(ConnexComponentItem_t * item)
|
|||
|
{
|
|||
|
nodesetlist_destroy(&(item->list));
|
|||
|
item->list = NULL;
|
|||
|
free(item);
|
|||
|
}
|
|||
|
|
|||
|
bool connexcomponentitem_contains_node(
|
|||
|
ConnexComponentItem_t * item,
|
|||
|
nodeindex_t node_idx)
|
|||
|
{
|
|||
|
return nodesetlist_contains_node (item->list, node_idx);
|
|||
|
}
|
|||
|
|
|||
|
void connexcomponentitem_display(ConnexComponentItem_t * item){
|
|||
|
nodesetlist_display (item->list);
|
|||
|
}
|
|||
|
|
|||
|
#undef DEBUG_APPEND
|
|||
|
#undef DEBUG_INSERT
|
|||
|
#undef DEBUG
|