Skip to content

Instantly share code, notes, and snippets.

@samloeschen
Last active April 2, 2020 17:44
Show Gist options
  • Save samloeschen/111f3ad57d6824ecbd1973316a69ef76 to your computer and use it in GitHub Desktop.
Save samloeschen/111f3ad57d6824ecbd1973316a69ef76 to your computer and use it in GitHub Desktop.
simple implementation of a Sparse Set in C
#include <stdlib.h>
#include <stdio.h>
#include "sparseset.h"
int min(int a, int b) {
return a < b ? a : b;
}
int max(int a, int b) {
return a > b ? a : b;
}
void makeSparseSet(int maxValue, int capacity, SparseSet *set) {
set->sparse = calloc(maxValue + 1, sizeof(int));
set->dense = calloc(capacity, sizeof(int));
set->count = 0;
set->capacity = capacity;
set->maxValue = maxValue;
}
int setContains(int x, SparseSet *set) {
if (x > set->maxValue) {
return -1;
}
int *dense = set->dense;
int *sparse = set->sparse;
int count = set->count;
if (sparse[x] < count && dense[sparse[x]] == x) {
return sparse[x];
}
return -1; //not found
}
int setAdd(int x, SparseSet *set) {
if (x > set->maxValue) {
return -1;
}
if (set->count >= set->capacity) {
return -1; // set would overflow
}
if (setContains(x, set) != -1) { // set already contains value
return -1;
}
int *dense = set->dense;
int *sparse = set->sparse;
int count = set->count;
dense[count] = x;
sparse[x] = count;
set->count++;
return 0;
}
int setRemove(int x, SparseSet *set) {
if (setContains(x, set)) {
return -1;
}
int count = set->count;
int *dense = set->dense;
int *sparse = set->sparse;
int temp = dense[count - 1];
dense[sparse[x]] = temp;
sparse[temp] = sparse[x];
set->count--;
return 0;
}
void setIntersection(SparseSet *a, SparseSet *b, SparseSet *result) {
int capacity = min(a->capacity, b->capacity);
int maxValue = max(a->maxValue, b->maxValue);
makeSparseSet(maxValue, capacity, result);
int *dense;
int count;
SparseSet *targetSet;
if (a->count < b->count) {
dense = a->dense;
count = a->count;
targetSet = b;
} else {
dense = b->dense;
count = b->count;
targetSet = a;
}
for (int i = 0; i < count; i++) {
if (setContains(dense[i], targetSet) != -1) {
setAdd(dense[i], result);
}
}
}
void setUnion(SparseSet *a, SparseSet *b, SparseSet *result) {
int capacity = a->count + b->count;
int maxValue = max(a->maxValue, b->maxValue);
makeSparseSet(maxValue, capacity, result);
for (int i = 0; i < a->count; i++) {
setAdd(a->dense[i], result);
}
for (int i = 0; i < b->count; i++) {
setAdd(b->dense[i], result);
}
}
#ifndef SPARSE_SET_H
#define SPARSE_SET_H
typedef struct SparseSet {
int *sparse;
int *dense;
int count;
int capacity;
int maxValue;
} SparseSet;
void makeSparseSet(int maxValue, int capacity, SparseSet *set);
void setIntersection(SparseSet *a, SparseSet *b, SparseSet *result);
void setUnion(SparseSet *a, SparseSet *b, SparseSet *result);
int setContains(int x, SparseSet *set);
int setAdd(int x, SparseSet *set);
int setRemove(int x, SparseSet *set);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment