开始设计
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
#include <c_QuickFindUF.h>
|
||||
#include <c_Memory.h>
|
||||
|
||||
|
||||
c_err_t c_QuickFindUF_Init(c_QuickFindUF_t* self, c_size_t n) {
|
||||
if (!self || n==0) return C_ERR_PARAM;
|
||||
self->count = n;
|
||||
self->id_len = n;
|
||||
self->id = C_ALLOC(sizeof(c_size_t) * n);
|
||||
if (!self->id) {
|
||||
return C_ERR_NOMEM;
|
||||
}
|
||||
for (c_size_t i=0; i<self->id_len; i++) {
|
||||
self->id[i] = i;
|
||||
}
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
void c_QuickFindUF_Destroy(c_QuickFindUF_t* self) {
|
||||
C_FREE(self->id);
|
||||
self->count = 0;
|
||||
self->id_len = 0;
|
||||
}
|
||||
|
||||
c_size_t c_QuickFindUF_Find(c_QuickFindUF_t* self, c_size_t index) {
|
||||
if (!self || self->id==NULL || index>=self->id_len) {
|
||||
return (c_size_t)-1;
|
||||
}
|
||||
return self->id[index];
|
||||
}
|
||||
|
||||
c_err_t c_QuickFindUF_Union(c_QuickFindUF_t* self, c_size_t p, c_size_t q) {
|
||||
if (self == NULL || self->id == NULL) return C_ERR_PARAM;
|
||||
if (p >= self->id_len || q >= self->id_len) return C_ERR_PARAM;
|
||||
|
||||
c_size_t pID = self->id[p];
|
||||
c_size_t qID = self->id[q];
|
||||
if (pID==qID) return C_ERR_OK;
|
||||
for (c_size_t i=0; i<self->id_len; i++) {
|
||||
if (self->id[i] == pID) self->id[i] = qID;
|
||||
}
|
||||
self->count--;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef INCLUDED_C_QUICKFINDUF_H
|
||||
#define INCLUDED_C_QUICKFINDUF_H
|
||||
|
||||
#ifndef INCLUDED_C_BASE_H
|
||||
#include <c_Base.h>
|
||||
#endif /*INCLUDED_C_BASE_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
typedef struct {
|
||||
c_size_t* id;
|
||||
c_size_t id_len;
|
||||
c_size_t count;
|
||||
}c_QuickFindUF_t;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
c_err_t c_QuickFindUF_Init(c_QuickFindUF_t* self, c_size_t count);
|
||||
|
||||
void c_QuickFindUF_Destroy(c_QuickFindUF_t* self);
|
||||
|
||||
c_size_t c_QuickFindUF_Find(c_QuickFindUF_t* self, c_size_t index);
|
||||
|
||||
c_err_t c_QuickFindUF_Union(c_QuickFindUF_t* self, c_size_t p, c_size_t q);
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_bool_t c_QuickFindUF_IsConnected(c_QuickFindUF_t* self, c_size_t p, c_size_t q) {
|
||||
if (!self || !self->id || p>=self->id_len || q>=self->id_len) return C_FALSE;
|
||||
return self->id[q] == self->id[p];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /*INCLUDED_C_QUICKFINDUF_H*/
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "c_QuickFindUF.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Your updated line tracing diagnostic macro
|
||||
#define EXPECT_EQ(actual, expected, msg) \
|
||||
do { \
|
||||
if ((actual) != (expected)) { \
|
||||
printf(" [X] Assert Failed: %s (Expected %d, got %d) %s:%d\n", msg, (int)(expected), (int)(actual), __FILE__, __LINE__); \
|
||||
return C_FALSE; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
c_bool_t test_quick_find_disjoint_set(void) {
|
||||
c_QuickFindUF_t uf;
|
||||
c_size_t sites = 10; // Track 10 independent connectivity components (0 to 9)
|
||||
|
||||
// Test Case 1: Parameter Enforcement & Initial Set Boundaries
|
||||
EXPECT_EQ(c_QuickFindUF_Init(NULL, sites), C_ERR_PARAM, "NULL pointer initialization guard missed");
|
||||
EXPECT_EQ(c_QuickFindUF_Init(&uf, sites), C_ERR_OK, "Quick-Find context initialization failed");
|
||||
EXPECT_EQ(uf.count, 10, "Initial disjoint independent components size tracking incorrect");
|
||||
|
||||
// On entry, every site must resolve to itself as its own root identifier
|
||||
EXPECT_EQ(c_QuickFindUF_Find(&uf, 4), 4, "Site component lookup failed to resolve to identity baseline");
|
||||
EXPECT_EQ(c_QuickFindUF_IsConnected(&uf, 4, 3), C_FALSE, "Unconnected distinct sites reported true connectivity on entry");
|
||||
|
||||
// Test Case 2: Link Cluster Merging Sequence (Union Processing)
|
||||
// Connect pairs sequentially: (4, 3), (3, 8), (6, 5)
|
||||
printf(" [LOG] Grouping element nodes into connected sub-clusters...\n");
|
||||
EXPECT_EQ(c_QuickFindUF_Union(&uf, 4, 3), C_ERR_OK, "Union operation for (4, 3) failed");
|
||||
EXPECT_EQ(c_QuickFindUF_Union(&uf, 3, 8), C_ERR_OK, "Union operation for (3, 8) failed");
|
||||
EXPECT_EQ(c_QuickFindUF_Union(&uf, 6, 5), C_ERR_OK, "Union operation for (6, 5) failed");
|
||||
|
||||
// Component size count should decrement cleanly: 10 - 3 merges = 7 clusters left
|
||||
EXPECT_EQ(uf.count, 7, "Connected clusters total reduction tracking variable miscalculated");
|
||||
|
||||
// Test Case 3: Connectivity Matrix Validation Checkpoints
|
||||
// Because 4 connected to 3, and 3 connected to 8, 4 should now be transitively connected to 8
|
||||
EXPECT_EQ(c_QuickFindUF_IsConnected(&uf, 4, 8), C_TRUE, "Transitive path connection check missed targeting");
|
||||
EXPECT_EQ(c_QuickFindUF_IsConnected(&uf, 4, 5), C_FALSE, "Isolated component branches reported false positive connection layout");
|
||||
|
||||
// O(1) Lookups must verify identical component cluster ID mapping matches
|
||||
EXPECT_EQ(c_QuickFindUF_Find(&uf, 4) == c_QuickFindUF_Find(&uf, 8), C_TRUE, "Quick-Find IDs out of sync for linked nodes");
|
||||
printf(" [STAT] Component connection verified. Site 4 Component ID: %zu, Site 8 Component ID: %zu\n", c_QuickFindUF_Find(&uf, 4), c_QuickFindUF_Find(&uf, 8));
|
||||
|
||||
// Test Case 4: Redundant Merge Operations Guard Checks
|
||||
// Merging already connected items should exit early without decrementing the active cluster pool counts
|
||||
EXPECT_EQ(c_QuickFindUF_Union(&uf, 8, 4), C_ERR_OK, "Redundant union call threw an unexpected exception");
|
||||
EXPECT_EQ(uf.count, 7, "Redundant component merge tracking decremented size array pools erroneously");
|
||||
|
||||
// Test Case 5: Out of Bound Safety Guards Exception Escapes
|
||||
EXPECT_EQ(c_QuickFindUF_Union(&uf, 12, 4), C_ERR_PARAM, "Out of bounds parameter index skipped param check filtering");
|
||||
EXPECT_EQ(c_QuickFindUF_IsConnected(&uf, 4, 99), C_FALSE, "OOB connection index check failed to drop safe negative response");
|
||||
EXPECT_EQ(c_QuickFindUF_Find(&uf, 99), (c_size_t)-1, "OOB lookup index failed to surface default error sentinel");
|
||||
|
||||
c_QuickFindUF_Destroy(&uf);
|
||||
return C_TRUE;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("=== Starting Framework Verification: c_QuickFindUF ===\n");
|
||||
if (test_quick_find_disjoint_set()) {
|
||||
printf(" [PASS] Quick-Find Disjoint Set Operations and Component Merges Verified Successfully.\n");
|
||||
} else {
|
||||
printf(" [FAIL] Disjoint Set Pipeline Structural Logic Failures Detected.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user