Skip to content

Commit

Permalink
Clone graph
Browse files Browse the repository at this point in the history
Signed-off-by: begeekmyfriend <[email protected]>
  • Loading branch information
begeekmyfriend committed Oct 31, 2017
1 parent 06f42e8 commit a576021
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
2 changes: 2 additions & 0 deletions 133_clone_graph/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
gcc -O2 -o test clone_graph.c
139 changes: 139 additions & 0 deletions 133_clone_graph/clone_graph.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <stdio.h>
#include <stdlib.h>

struct hlist_node;

struct hlist_head {
struct hlist_node *first;
};

struct hlist_node {
struct hlist_node *next, **pprev;
};

static inline void INIT_HLIST_HEAD(struct hlist_head *h) {
h->first = NULL;
}

static inline void INIT_HLIST_NODE(struct hlist_node *n) {
n->next = NULL;
n->pprev = NULL;
}

static inline int hlist_empty(struct hlist_head *h) {
return !h->first;
}

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
if (h->first != NULL) {
h->first->pprev = &n->next;
}
n->next = h->first;
n->pprev = &h->first;
h->first = n;
}

static inline void hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next != NULL) {
next->pprev = pprev;
}
}

#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))

#define list_entry(ptr, type, member) \
container_of(ptr, type, member)

#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos; pos = pos->next)

#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n)

#define NEIGHBORS_MAX_SIZE 100

struct UndirectedGraphNode {
int label;
struct UndirectedGraphNode *neighbors[NEIGHBORS_MAX_SIZE];
int neighborsCount;
};

struct label_node {
struct UndirectedGraphNode *gn;
struct hlist_node node;
};

static struct UndirectedGraphNode *find(int label, int size, struct hlist_head *heads)
{
int hash = (label < 0 ? -label : label) % size;
struct hlist_node *p;
hlist_for_each(p, &heads[hash]) {
struct label_node *ln = list_entry(p, struct label_node, node);
if (ln->gn->label == label) {
return ln->gn;
}
}
return NULL;
}

static struct UndirectedGraphNode *recursive_clone(struct UndirectedGraphNode *graph, struct hlist_head *heads, int size)
{
if (graph == NULL) {
return NULL;
}

struct UndirectedGraphNode *node = find(graph->label, size, heads);
if (node != NULL) {
return node;
}

node = malloc(sizeof(*node));
node->label = graph->label;
node->neighborsCount = graph->neighborsCount;
struct label_node *ln = malloc(sizeof(*ln));
ln->gn = node;
int hash = (node->label < 0 ? -node->label : node->label) % size;
hlist_add_head(&ln->node, &heads[hash]);

int i;
for (i = 0; i < node->neighborsCount; i++) {
node->neighbors[i] = recursive_clone(graph->neighbors[i], heads, size);
}

return node;
}

static struct UndirectedGraphNode *cloneGraph(struct UndirectedGraphNode *graph)
{
int i, cap = 1000;
struct hlist_head *heads = malloc(cap * sizeof(*heads));
for (i = 0; i < cap; i++) {
INIT_HLIST_HEAD(&heads[i]);
}

return recursive_clone(graph, heads, cap);
}

int main(void)
{
struct UndirectedGraphNode n0, n1, n2;
n0.label = 0;
n1.label = 1;
n2.label = 2;
n0.neighborsCount = 2;
n1.neighborsCount = 1;
n2.neighborsCount = 1;
n0.neighbors[0] = &n1;
n0.neighbors[1] = &n2;
n1.neighbors[0] = &n2;
n2.neighbors[0] = &n2;

struct UndirectedGraphNode *res = cloneGraph(&n0);
return 0;
}
2 changes: 2 additions & 0 deletions 134_gas_station/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
gcc -O2 -o test gas_station.c
35 changes: 35 additions & 0 deletions 134_gas_station/gas_station.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>

static int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize)
{
int i, j, store = 0, start = -1;
for (i = 0; i < gasSize; i++) {
if (start < 0) {
start = i;
}
store += gas[i] - cost[i];
if (store < 0) {
store = 0;
start = -1;
}
}
if (start > 0) {
for (i = 0; i < start; i++) {
store += gas[i] - cost[i];
if (store < 0) {
return -1;
}
}
}
return start;
}

int main(void)
{
int gas[] = { 4 };
int cost[] = { 5 };
int count = sizeof(gas) / sizeof(*gas);
printf("%d\n", canCompleteCircuit(gas, count, cost, count));
return 0;
}

0 comments on commit a576021

Please sign in to comment.