2024-03-19 02:45:09 +08:00

160 lines
3.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MIN(a, b) a > b ? b : a
#define bool char
#define false 0
#define true 1
typedef struct trie *trieNode;
typedef struct trie Trie;
// 有bug的trie压缩树
struct trie
{
char *path; //节点路径
int data; //节点存放数据
trieNode brother; //兄弟节点
trieNode next; //下面的节点
};
trieNode tree;
trieNode newNode()
{
trieNode tmp = malloc(sizeof(Trie));
memset(tmp, 0, sizeof(Trie));
tmp->path = "";
return tmp;
}
//插入数据
void insert(trieNode tree, char *path, int data)
{
//判断节点路径
if (tree->path == "")
{
//空路径直接插入
tree->path = path;
tree->data = data;
return;
}
//判断路径耦合,path大于节点路径,往next节点查找
//节点路径大于path,往brother找 (大小指相等的长度)
bool isPath = false; //表示path长度大于tree->path
int minLen = strlen(path);
if (strlen(path) > strlen(tree->path))
{
isPath = true;
minLen = strlen(tree->path);
}
int pathPos = 0;
for (pathPos = 0; pathPos < minLen; pathPos++)
{
if (path[pathPos] != tree->path[pathPos])
{
break;
}
}
if (pathPos == 0) //为0是全部不等,继续向下一个兄弟节点查询,除非下一个兄弟节点为null,直接插入
{
if (tree->brother == NULL)
{
trieNode tmp = newNode();
tmp->data = data;
tmp->path = path;
tree->brother = tmp;
}
else
{
insert(tree->brother, path, data);
}
}
else if (pathPos != minLen) //没有全部的相等
{
if (tree->next == NULL)
{
tree->next = newNode();
}
insert(tree->next, &path[pathPos], data);
insert(tree->next, &tree->path[pathPos], tree->data);
char *tmp = malloc(pathPos + 1);
memcpy(tmp, tree->path, pathPos);
tree->path = tmp;
tree->data = 0;
}
else //全部的相等
{
if (isPath) //全等,并且path大,继续往next节点查找
{
insert(tree->next, &path[pathPos], data);
}
else //全等,node->path大,
{
//空节点
if (tree->next == NULL)
{
tree->next = newNode();
}
char *tmp = malloc(pathPos + 1);
memcpy(tmp, tree->path, pathPos);
insert(tree->next, &tree->path[pathPos], tree->data);
tree->path = tmp;
tree->data = data;
}
}
}
trieNode search(trieNode tree, char *path)
{
if (tree == NULL)
{
return NULL;
}
int pos1 = 0, pos2 = 0;
for (; pos2 < strlen(path); pos2++, pos1++)
{
if (tree->path[pos1] != path[pos2])
{
if (pos1 == 0) //为0则表示一个都不相等,往兄弟节点查询
{
pos1 = -1;
pos2 -= 1;
tree = tree->brother;
}
else
{
//否则没了
return NULL;
}
}
else if (pos1 == strlen(tree->path) - 1) //如果全部相等,node->path查找完毕,继续判断pos2是不是相等
{
if (pos2 == strlen(path) - 1) //传入的path也全部扫描完毕,则当前节点就是搜索到的节点
{
return tree;
}
else //否则,pos1重置为0,从下一个节点继续查找
{
pos1 = -1;
tree = tree->next;
}
}
}
return NULL;
}
int main()
{
tree = newNode();
insert(tree, "/user/login", 111);
insert(tree, "/user/register", 222);
insert(tree, "/user/logout", 333);
insert(tree, "/user/message", 444);
insert(tree, "/user/mess", 555);
trieNode tmp = search(tree, "/user/mess");
}