init commit

This commit is contained in:
2024-03-19 01:05:51 +08:00
commit 199bbf2628
393 changed files with 34883 additions and 0 deletions

View File

@ -0,0 +1,103 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#define TABLE_SIZE 41
#define MAX_FIND 4
//利用平方探测法创建散列
typedef struct _hash *HASH_TABLE;
struct _hash
{
char *key;
int value;
};
HASH_TABLE hash_create()
{
//创建一个大小为size的表
//也就是申请size大小的内存空间
HASH_TABLE ret = (HASH_TABLE)malloc(TABLE_SIZE * sizeof(struct _hash));
memset(ret, 0, sizeof(struct _hash) * TABLE_SIZE);
return ret;
}
int hash(const char *key)
{
//散列函数,P113
unsigned int hash_value = 0;
while (*key != '\0')
{
hash_value = (hash_value << 5) + *key++;
}
return hash_value % TABLE_SIZE;
}
int hash_insert(HASH_TABLE hash_table, const char *key, int value)
{
//插入一个值到hash表中
//先计算hash值
int sub = hash(key);
//判断是否有碰撞
if ((int)hash_table[sub].key != 0)
{
//值不是空的,利用平方的方法,探测空的地方
int tmp_sub = 0;
for (int i = 0; i < MAX_FIND; i++)
{
tmp_sub = sub + i * i;
if (tmp_sub >= TABLE_SIZE)
{
tmp_sub -= TABLE_SIZE;
}
if ((int)hash_table[tmp_sub].key == 0 || strcmp(hash_table[tmp_sub].key, key) == 0)
{
//找到了空的位置,赋值,跳出循环
break;
}
//如果继续碰撞,继续往后计算
}
if (hash_table[tmp_sub].value != value)
{
//没有找到空位,返回-1,提示失败
return -1;
}
sub = tmp_sub;
}
hash_table[sub].key = (char *)malloc(strlen(key)+1);
memset(hash_table[sub].key,0,strlen(key)+1);
memcpy(hash_table[sub].key, key, strlen(key));
hash_table[sub].value = value;
return sub;
}
int hash_find(HASH_TABLE hash_table, const char *key, int value)
{
}
#ifndef MAIN_FUNC
int main()
{
HASH_TABLE hash_table = hash_create();
hash_insert(hash_table, "one", 1);
hash_insert(hash_table, "t", 2);
hash_insert(hash_table, "e", 3);
hash_insert(hash_table, "q", 4);
hash_insert(hash_table, "while", 5);
hash_insert(hash_table, "z", 6);
hash_insert(hash_table, "f", 7);
//遍历表
for (int i = 0; i < TABLE_SIZE; i++)
{
if ((int)hash_table[i].key == 0)
{
continue;
}
printf("%s=>%d\n", hash_table[i].key, hash_table[i].value);
}
return 0;
}
#endif

View File

@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* 数据结构,队列 感觉和栈差不多吧,一个先进后出,一个先进先出
* 用双向链表的速度将快一些,本例采用双向链表,就不需要再检索倒数第二个节点,记录最后一个节点即可
*/
struct queue;
typedef struct queue *prt_queue;
//3->2->1->3
struct queue
{
int data;
prt_queue last; //上一个
prt_queue next; //下一个
};
//3<=>2<=>1
//3<=>2
//3
/**
* 出队列
*/
int pop(prt_queue *end)
{
if (*end == NULL)
{
return 0;
}
int ret_data = (*end)->data;
prt_queue *tmp = end;
*end = (*end)->last;
if ((*end) != NULL)
{
(*end)->next = NULL;
}
free(tmp);
return ret_data;
}
//1
//2<=>1
//3<=>2<=>1
/**
* 进入队列
*/
prt_queue push(int data, prt_queue *h)
{
prt_queue tmp_node = malloc(sizeof(struct queue));
(*h)->last = tmp_node;
memset(tmp_node, 0, sizeof(struct queue));
tmp_node->data = data;
tmp_node->next = *h;
*h = tmp_node;
return tmp_node;
}
/**
* 创建栈
*/
prt_queue create_queue(int data)
{
prt_queue header = malloc(sizeof(struct queue));
memset(header, 0, sizeof(struct queue));
header->data = data;
return header;
}
void print_queue(prt_queue *end)
{
int data = 0;
while ((data = pop(end)) != 0)
{
printf("%d\t", data);
}
}
#ifndef MAIN_FUNC
int main()
{
prt_queue queue = create_queue(1);
prt_queue end_node = queue;
push(23, &queue);
push(15, &queue);
push(123, &queue);
push(36, &queue);
push(89, &queue);
push(16, &queue);
push(324, &queue);
push(526, &queue);
push(166, &queue);
push(984, &queue);
push(85, &queue);
pop(&end_node);
pop(&end_node);
print_queue(&end_node);
getchar();
return 0;
}
#endif

View File

@ -0,0 +1,86 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* 数据结构,栈
*/
struct stack;
typedef struct stack *prt_stack;
struct stack
{
int data;
prt_stack last;
};
//1<-2 header=2 header->last=1
//1 header=1 header->last=null
/**
* 出栈
*/
int pop(prt_stack *h)
{
if (*h == NULL)
{
return 0;
}
int ret_data = (*h)->data;
prt_stack *tmp = h;
*h = (*h)->last;
free(tmp);
return ret_data;
}
//1 header=1 header->last=null
//1<-2 header=2 header->last=1
/**
* 入栈
*/
prt_stack push(int data, prt_stack *h)
{
prt_stack tmp_node = malloc(sizeof(struct stack));
memset(tmp_node, 0, sizeof(struct stack));
tmp_node->data = data;
tmp_node->last = *h;
*h = tmp_node;
return tmp_node;
}
/**
* 创建栈
*/
prt_stack create_stack(int data)
{
prt_stack header = malloc(sizeof(struct stack));
memset(header, 0, sizeof(struct stack));
header->data = data;
return header;
}
void print_stack(prt_stack *h)
{
int data = 0;
while ((data = pop(h)) != 0)
{
printf("%d\t", data);
}
}
#ifndef MAIN_FUNC
int main()
{
prt_stack stack = create_stack(1);
push(23, &stack);
push(15, &stack);
push(123, &stack);
push(36, &stack);
push(89, &stack);
push(16, &stack);
push(324, &stack);
push(526, &stack);
push(166, &stack);
push(984, &stack);
push(85, &stack);
pop(&stack);
print_stack(&stack);
getchar();
return 0;
}
#endif

View File

@ -0,0 +1,109 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* 单向链表 增,删,查,改
*/
struct node;
typedef struct node *prt_node;
prt_node insert(int, int, prt_node);
prt_node find_node(int, prt_node);
void print_list(prt_node);
prt_node after_node(prt_node);
void del(int, prt_node);
void modify(int, int, prt_node);
struct node
{
int data;
prt_node next;
};
/**
* 在n位置后面插入一个数据,n为-1时插入到最后
*/
prt_node insert(int n, int data, prt_node h)
{
prt_node tmp_node;
prt_node last_node = n == -1 ? after_node(h) : find_node(n, h); //取得前一个节点
tmp_node = last_node->next;
last_node->next = malloc(sizeof(struct node));
last_node->next->next = tmp_node;
last_node->next->data = data;
tmp_node = last_node->next;
return tmp_node; //返回插入的节点
}
/**
* 寻找前一个节点,n为-1时查找最后节点
*/
prt_node find_node(int n, prt_node h)
{
prt_node ret = h;
for (int i = 0; i < n; i++)
{
if (ret->next == NULL)
{
break;
}
ret = ret->next;
}
return ret;
}
/**
* 最后一个
*/
prt_node after_node(prt_node h)
{
while (h->next != NULL)
h = h->next;
return h;
}
/**
* 删除数据
*/
void del(int n, prt_node h)
{
h = find_node(n, h);
prt_node tmp_node = h->next;
h->next = tmp_node->next;
free(tmp_node);
}
/**
* 修改数据
*/
void modify(int n, int data, prt_node h)
{
prt_node tmp_node = find_node(n, h)->next;
tmp_node->data = data;
}
/**
* 输出链表
*/
void print_list(prt_node h)
{
while ((h = h->next) != NULL)
{
printf("%d\t", h->data);
}
printf("\n");
}
int main()
{
prt_node header = memset(malloc(sizeof(struct node)), 0, sizeof(struct node));
//添加
insert(-1, 153, header);
insert(-1, 2343, header);
insert(-1, 323, header);
insert(-1, 564, header);
//删除
del(2, header);
//插入
insert(2, 23333, header);
insert(4, 312, header);
//修改
modify(0, 888, header);
print_list(header);
getchar();
return 0;
}

View File

@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* 单向链表头文件
*/
/**
* 单向链表 增,删,查,改
*/
struct node;
typedef struct node *prt_node;
prt_node insert(int, int, prt_node);
prt_node find_node(int, prt_node);
void print_list(prt_node);
prt_node after_node(prt_node);
void del(int, prt_node);
void modify(int, int, prt_node);
struct node
{
int data;
prt_node next;
};
/**
* 在n位置后面插入一个数据,n为-1时插入到最后
*/
prt_node insert(int n, int data, prt_node h)
{
prt_node tmp_node;
prt_node last_node = n == -1 ? after_node(h) : find_node(n, h); //取得前一个节点
tmp_node = last_node->next;
last_node->next = (prt_node)malloc(sizeof(struct node));
last_node->next->next = tmp_node;
last_node->next->data = data;
tmp_node = last_node->next;
return tmp_node; //返回插入的节点
}
/**
* 寻找前一个节点,n为-1时查找最后节点
*/
prt_node find_node(int n, prt_node h)
{
prt_node ret = h;
for (int i = 0; i < n; i++)
{
if (ret->next == NULL)
{
break;
}
ret = ret->next;
}
return ret;
}
/**
* 最后一个
*/
prt_node after_node(prt_node h)
{
while (h->next != NULL)
h = h->next;
return h;
}
/**
* 删除数据
*/
void del(int n, prt_node h)
{
h = find_node(n, h);
prt_node tmp_node = h->next;
h->next = tmp_node->next;
free(tmp_node);
}
/**
* 修改数据
*/
void modify(int n, int data, prt_node h)
{
prt_node tmp_node = find_node(n, h)->next;
tmp_node->data = data;
}
/**
* 输出链表
*/
void print_list(prt_node h)
{
while ((h = h->next) != NULL)
{
printf("%d\t", h->data);
}
printf("\n");
}

View File

@ -0,0 +1,149 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* AVL树
*/
struct tree;
typedef struct tree *prt_tree;
#define bool int
#define false 0
#define true 1
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
struct tree
{
int data; //数据
int height; //树深度
prt_tree lt; //左节点
prt_tree rt; //右节点
};
/**
* 创建一个节点
*/
prt_tree create_tree(int data)
{
prt_tree tmp = malloc(sizeof(struct tree));
memset(tmp, 0, sizeof(struct tree));
tmp->data = data;
return tmp;
}
int height(prt_tree tree)
{
if (tree != NULL)
{
return tree->height;
}
return 0;
}
/**
* 右单旋
*/
prt_tree rightSingleRotation(prt_tree root)
{
//1->2->3 交换1 2,也就是1 2 旋转
prt_tree tmp = root->rt; //root=1 tmp=2
root->rt = tmp->lt; //root->rt=tmp->lt 吧2的右节点接到1的左节点
tmp->lt = root; //1的左节点为2节点
// tmp->lt=
root->height = (height(root->lt) > height(root->rt) ? height(root->lt) : height(root->rt)) + 1;
tmp->height = (height(tmp->lt) > height(tmp->rt) ? height(tmp->lt) : height(tmp->rt)) + 1;
return tmp;
}
/**
* 左单旋
*/
prt_tree leftSingleRotation(prt_tree root)
{
//1->2->3 交换1 2,也就是1 2 旋转
prt_tree tmp = root->lt; //root=1 tmp=2
root->lt = tmp->rt; //root->lt=tmp->rt 吧2的右节点接到1的左节点
tmp->rt = root; //1的左节点为2节点
// tmp->rt=
root->height = (height(root->rt) > height(root->lt) ? height(root->rt) : height(root->lt)) + 1;
tmp->height = (height(tmp->rt) > height(tmp->lt) ? height(tmp->rt) : height(tmp->lt)) + 1;
return tmp;
}
/**
* 左双旋
*/
prt_tree leftDoubleRotation(prt_tree root)
{
root->lt = rightSingleRotation(root->lt);
return leftSingleRotation(root);
}
/**
* 右双旋
*/
prt_tree rightDoubleRotation(prt_tree root)
{
root->rt = leftSingleRotation(root->rt);
return rightSingleRotation(root);
}
/**
* 插入树
*/
prt_tree insert(int data, prt_tree root)
{
if (root == NULL) //如果节点为空,则认为将插入到该点
{
root = create_tree(data);
}
else if (root->data > data) // 判断往哪个方向节点插入,数据比当前小,往左
{
root->lt = insert(data, root->lt);
if (height(root->lt) - height(root->rt) == 2) //重新平衡
{
if (data < root->lt->data)
{
root = leftSingleRotation(root);
}
else
{
root = leftDoubleRotation(root);
}
}
}
else if (root->data < data) //数据比当前大,往右
{
root->rt = insert(data, root->rt);
if (height(root->rt) - height(root->lt) == 2) //重新平衡
{
if (data > root->rt->data)
{
root = rightSingleRotation(root);
}
else
{
root = rightDoubleRotation(root);
}
}
}
root->height = max(height(root->lt), height(root->rt)) + 1;
return root;
}
void print_tree(prt_tree root) //中序输出就是排序啦
{
if (root == NULL)
{
return;
}
print_tree(root->lt);
printf("%d\t", root->data);
print_tree(root->rt);
}
int main()
{
prt_tree root = insert(201, NULL);
for (int i = 0; i < 20; i++)
{
root = insert(rand(), root);
}
print_tree(root);
getchar();
return 0;
}

View File

@ -0,0 +1,186 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#define M 3
typedef struct tree *prt_tree;
struct tree
{
int data; //存储的数据
prt_tree left; //左子节点
prt_tree right; //右子节点
prt_tree brother; //兄弟节点
};
prt_tree create_node(int data)
{
prt_tree tree = malloc(sizeof(struct tree));
memset(tree, 0, sizeof(struct tree));
tree->data = data;
return tree;
}
prt_tree insert(int data, prt_tree root, prt_tree father)
{
if (root == NULL)
{
root = create_node(data);
return root;
}
//在兄弟节点进行搜索,直到data夹在两个兄弟节点之中,或者相等,或者为空
//如果相等不进行处理,直接返回
//如果比最小的还小,插入节点后,与第一个交换返回
//如果是夹在兄弟中,就进入第一个的右,或者第二个左节点
//如果等于NULL的话,证明这是叶子节点,就直接在中间插入,否则进行插入操作,回到第一行
//如果是空就插入在最后一个兄弟节点
//插入之后继续进行循环,得到n来判断这个节点数量有没有大于m
prt_tree tmp = root;
int n = 0;
while (tmp != NULL)
{
n += 1;
if (data == tmp->data)
{
//相等的情况
break;
}
else if (data < tmp->data)
{
//比最小还小的情况(也就是最小),往左边插入,先判断left节点是不是NULL
//为NULL则认为是叶子节点,数量+1,然后跳出循环,新节点变为老节点
//否则递归调用insert,往left节点继续搜索
if (tmp->left == NULL)
{
prt_tree new_tree = create_node(data);
new_tree->brother = tmp;
n += 1;
root = new_tree;
break;
}
else
{
//往左节点继续搜索
insert(data, tmp->left, tmp);
}
}
else if (tmp->brother == NULL)
{
//等于空的情况(也就是最大的情况),往右插入,先判断right节点是不是NULL
//为NULL则认为是叶子节点,新节点加入兄弟节点后,tmp指向兄弟节点,跳出循环
//否则递归调用insert,往right节点继续搜索
if (tmp->right == NULL)
{
prt_tree new_tree = create_node(data);
tmp->brother = new_tree;
tmp = tmp->brother;
break;
}
else
{
insert(data, tmp->right, tmp);
}
}
else if (data > tmp->data && data < tmp->brother->data)
{
//夹在中间的情况,如果right为空的就认为是叶子节点,插入在中间
if (tmp->right == NULL)
{
//插入在中间,新建立一个新的节点,然后将节点插入到中间
prt_tree new_tree = create_node(data);
prt_tree tmpPrtTree = tmp->brother;
tmp->brother = new_tree;
new_tree->brother = tmpPrtTree;
tmp = tmp->brother;
break;
}
else
{
//往父的right插入
insert(data, tmp->right, tmp);
}
}
tmp = tmp->brother;
}
//接着tmp继续循环,遍历这个节点有没有超过m
while (tmp != NULL)
{
tmp = tmp->brother;
n += 1;
}
//判断是否超过M
if (n > M)
{
//超过m,取出中间的前一个节点
prt_tree mid_before_tree = root;
prt_tree mid_tree = NULL;
int sub = ceil(M / 2);
for (int i = 0; i < sub; i++)
{
mid_before_tree = mid_before_tree->brother;
}
mid_tree = mid_before_tree->brother;
//取出中间的后,判断父节点,是不是等于当前,如果是等于当前root节点
//将这一整个块从mid_tree分开,中间节点提取到上一节点
mid_before_tree->brother = NULL;
mid_tree->left = root;
mid_tree->right = mid_tree->brother;
mid_tree->brother = NULL;
//则认为这是在操作根节点,操作的是根节点的话
//就要将现在的这个节点变为根节点
if (root == father)
{
root = mid_tree;
}
else
{
//然后判断比父节点大还是小
//比父大就是直接插入到父的兄弟节点
//然后父的兄弟的left为空
//比父小就进行交换,插入
//父right为空
if (father->data > data)
{
prt_tree tmp_node = father->brother;
father->brother = mid_tree;
mid_tree->brother = tmp_node;
}
else
{
//连接兄弟节点
mid_tree->brother = father->brother;
father->brother = mid_tree;
}
}
}
printf("data:%d\tn:%d\n", data, n);
return root;
}
//排序输出
void print_tree(prt_tree root)
{
if (root == NULL)
return;
print_tree(root->left);
printf("%d\t", root->data);
print_tree(root->brother);
if (root->brother == NULL)
{
print_tree(root->right);
}
}
int main()
{
prt_tree root = NULL;
root = insert(1, root, root);
root = insert(6, root, root);
root = insert(8, root, root);
root = insert(11, root, root);
root = insert(15, root, root);
root = insert(16, root, root);
root = insert(18, root, root);
print_tree(root);
return 0;
}

View File

@ -0,0 +1,139 @@
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct tree tree;
struct tree {
tree* left;
tree* right;
int val;
};
tree* new_tree() {
tree* t = malloc(sizeof(tree));
memset(t, 0, sizeof(tree));
return t;
}
int add_tree(tree* root) {
int val = 0;
printf("value:");
scanf("%d", &val);
root->val = val;
int flag = 0;
while (1) {
printf("left(1) or right(2) or upper(3) or quit(any):");
scanf("%d", &flag);
if (flag == 1) {
if (root->left == NULL) {
root->left = new_tree();
}
if (!add_tree(root->left)) break;
} else if (flag == 2) {
if (root->right == NULL) {
root->right = new_tree();
}
if (!add_tree(root->right)) break;
} else if (flag == 3) {
return 1;
} else {
break;
}
}
return 0;
}
//前;中;后序遍历 dfs
void print_tree_before(tree* root) {
if (root == NULL) {
return;
}
printf("%d\t", root->val);
print_tree_before(root->left);
print_tree_before(root->right);
}
void print_tree_stack(tree* root) {
//使用栈来实现前序(不是递归)
tree* stack[100] = {NULL};
int start = 0, end = 0;
stack[0] = root;
while (end >= 0) {
//弹出栈顶
int top = end--;
tree * tmp=stack[top];
printf("%d\t", tmp->val);
//右入
if (tmp->right != NULL) {
stack[++end] = tmp->right;
}
//左入
if (tmp->left != NULL) {
stack[++end] = tmp->left;
}
}
}
void print_tree_mid(tree* root) {
if (root == NULL) {
return;
}
print_tree_mid(root->left);
printf("%d\t", root->val);
print_tree_mid(root->right);
}
void print_tree_after(tree* root) {
if (root == NULL) {
return;
}
print_tree_after(root->left);
print_tree_after(root->right);
printf("%d\t", root->val);
}
//层次遍历 bfs
void print_tree_cengci(tree* root) {
tree* queue[100] = {NULL};
int pos = 0; //队首
int end = 0; //队尾
queue[0] = root;
while (queue[pos] != NULL) {
if (queue[pos]->left != NULL) {
//入队
queue[++end] = queue[pos]->left;
}
if (queue[pos] != NULL) {
queue[++end] = queue[pos]->right;
}
//输出(出队)
printf("%d\t", queue[pos++]->val);
}
}
int main() {
tree* root = new_tree();
root->left = new_tree();
root->right = new_tree();
root->left->left = new_tree();
root->left->right = new_tree();
root->left->left->val = 4;
root->left->right->val = 5;
root->val = 1;
root->left->val = 2;
root->right->val = 3;
// add_tree(root);
print_tree_before(root);
printf("\n");
print_tree_mid(root);
printf("\n");
print_tree_after(root);
printf("\n");
print_tree_cengci(root);
printf("\n");
print_tree_stack(root);
printf("\n");
system("pause");
return 0;
}

View File

@ -0,0 +1,65 @@
## B树
感觉B树是有点从下往上伸展的感觉,而不是像val树伸展树那些插入一个数据后旋转达到平衡,所以**所有的树叶都在相同的深度上**
* 树中每个结点最多含有m个孩子
* 除根结点和叶子结点外,其它每个结点至少有[ceil(m / 2)]个孩子 **(就是其他节点至少有 ceil(m/2) 个子节点咯)**
* 若根结点不是叶子结点则至少有2个孩子
* 所有叶子结点都出现在同一层 **(也就是高度相同吧)**
《数据结构与算法分析》上描述的b树(p97)所有数据都在树叶上,但是又没指向下一根的树叶,所以又不是b+树...应该是是另外一种形式吧....所以我还是按照往上那些比较详细的教程来理解吧
插入 1 2 3 4 5 6 7 8 9 10到一个3阶的b树下
插入1
```graphviz
digraph{
node[shape=record width=0.2 height=0.2]
1[label="|1|"]
}
```
```graphviz
digraph{
rankdir=LR
node[shape=record width=0.2 height=0.2]
1[label="{|1|}"]
2[label="{|2|}"]
1->2
}
```
```graphviz
digraph{
rankdir=LR
node[shape=record width=0.2 height=0.2]
1[label="{|1|}"]
2[label="{|2|}"]
3[label="{|3|}"]
1->2->3
}
```
当插入第四个的时候就需要进行处理了,因为我们设置的是三阶的B树
```graphviz
digraph{
rankdir=LR
node[shape=record width=.2 height=.1]
1[label="{|1|}"]
2[label="{|2|}"]
3[label="{|3|}"]
4[label="{|4|}" style="dashed"]
1->2->3->4
}
```
需要将中间的一个移动到上方,拆分成两个子节点(vscode绘图插件貌似语法不是很支持,直接换图了....而且确实是有些毛病)
![](img/graph1.png)
![](img/graph2.png)
然后插入5,6,7,8,9什么的直接略过吧,来看看当上一行也满了怎么办
这差不多是一个饱和的状态了,再插入一个10就会,往上增加一个,但是上一行也满了,操作也一样
![](img/graph3.png)

View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct hfm *HaffmanTree;
struct hfm
{
HaffmanTree node;
int val;
int priority;
};
int hashQ[26]; //权
HaffmanTree tree;
//构建列表
HaffmanTree buildList(char *str)
{
//先计算权
for (int i = 0; i < strlen(str); i++)
{
hashQ[str[i] - 'a']++;
}
return NULL;
}
int main()
{
tree = malloc(hfm) char str[] = "athisteststring";
buildList(str);
return 0;
}

View File

@ -0,0 +1,11 @@
digraph{
node[shape=record width=.2 height=.1]
1[label="|1|"]
2[label="|2|"]
node3[label="|3|"]
node4[label="|4|"]
node3->1
1->2
node3->node4
{rank=same; 1, 2}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,16 @@
digraph{
node[shape=record width=.2 height=.1]
1[label="<f0> |<f1>1|<f2>"]
2[label="<f0>|<f1>2|<f2>"]
3[label="<f0> |<f1>3|<f2>"]
4[label="<f0> |<f1>4|<f2>"]
5[label="<f0> |<f1>5|<f2>"]
6[label="<f0> |<f1>6|<f2>"]
3:f0->1:f1
1->2
3:f2->4
4->5->6
{rank=same; 1, 2}
{rank=same; 4, 5, 6}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -0,0 +1,32 @@
digraph{
node[shape=record width=.2 height=.1]
1[label="<f0> |<f1>1|<f2>"]
2[label="<f0>|<f1>2|<f2>"]
3[label="<f0> |<f1>3|<f2>"]
4[label="<f0> |<f1>4|<f2>"]
5[label="<f0> |<f1>5|<f2>"]
6[label="<f0> |<f1>6|<f2>"]
7[label="<f0> |<f1>7|<f2>"]
8[label="<f0> |<f1>8|<f2>"]
9[label="<f0> |<f1>9|<f2>"]
3->6->9
3:f0->1:f1
1->2
3:f2->4:f1
4->5
6:f0->4:f1
6:f2->7:f1
7->8
9:f0->7:f1
{rank=same; 3, 6, 9}
{rank=same; 1, 2}
{rank=same; 4, 5}
{rank=same; 7, 8}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,150 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* 二叉伸展树
* https://blog.csdn.net/u014634338/article/details/49586689
*/
struct tree;
#define bool int
#define false 0
#define true 1
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
typedef struct tree *prt_tree;
struct tree
{
int data; //数据
int height; //树深度
prt_tree lt; //左节点
prt_tree rt; //右节点
};
prt_tree create_tree(int data)
{
prt_tree tmp = malloc(sizeof(struct tree));
memset(tmp, 0, sizeof(struct tree));
tmp->data = data;
return tmp;
}
prt_tree add_tree(int data, prt_tree root)
{
if (root == NULL)
{
prt_tree tmp = create_tree(data);
return tmp;
}
if (root->data > data)
{
root->lt = add_tree(data, root->lt);
}
else if (root->data < data)
{
root->rt = add_tree(data, root->rt);
}
return root;
}
void splay_tree(prt_tree root, prt_tree tree);
prt_tree find_tree(prt_tree root, int val)
{
if (root == NULL)
{
return NULL;
}
prt_tree tmp = NULL;
if (root->data > val)
{
tmp = find_tree(root->lt, val);
}
else if (root->data < val)
{
tmp = find_tree(root->rt, val);
}
if (tmp != NULL)
{
splay_tree(root, tmp);
}
return root;
}
void l_rotate(prt_tree a, prt_tree b);
void r_rotate(prt_tree a, prt_tree b);
void splay_tree(prt_tree root, prt_tree tree)
{
if (tree == NULL)
{
return;
}
if (root->lt == tree)
{
l_rotate(root, tree);
}
else if (root->rt == tree)
{
r_rotate(root, tree);
}
}
void l_rotate(prt_tree a, prt_tree b)
{
int tmp = a->data;
a->data = b->data; //交换ab数据
b->data = tmp;
prt_tree tmpNode = a->rt;
a->rt = b;
a->lt = b->lt;
b->lt = b->rt;
b->rt = tmpNode;
}
void r_rotate(prt_tree a, prt_tree b)
{
int tmp = a->data;
a->data = b->data;
b->data = tmp; //交换ab数据
prt_tree tmpNode = a->lt;
a->lt = b;
a->rt = b->rt;
b->rt = b->lt;
b->lt = tmpNode;
}
bool find(prt_tree root, int val)
{
if (root->data == val)
{
return true;
}
prt_tree tmp = find_tree(root, val);
if (tmp == NULL || tmp == root)
{
return false;
}
return true;
}
void print_tree(prt_tree root) //中序输出就是排序啦
{
if (root == NULL)
{
return;
}
print_tree(root->lt);
printf("%d\t", root->data);
print_tree(root->rt);
}
int main()
{
prt_tree root = create_tree(201);
for (int i = 0; i < 20; i++)
{
root = add_tree(rand(), root);
}
int s = 0;
scanf("%d", &s);
find(root, s);
print_tree(root);
system("pause");
return 0;
}

View File

@ -0,0 +1,156 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/**
* 树
*/
struct tree;
typedef struct tree *prt_tree;
struct tree
{
int data;
prt_tree child; //子节点链表
prt_tree brother; //兄弟节点链表
};
prt_tree create_tree()
{
void *tmp = malloc(sizeof(struct tree));
memset(tmp, 0, sizeof(struct tree));
return tmp;
}
/**
* 最后一个兄弟节点
*/
prt_tree end_node_brother(prt_tree node)
{
while (1)
{
if (node->brother != NULL)
{
node = node->brother;
}
else
{
break;
}
}
return node;
}
/**
* 最后一个子节点
*/
prt_tree end_node_child(prt_tree node)
{
while (1)
{
if (node->child != NULL)
{
node = node->child;
}
else
{
break;
}
}
return node;
}
/**
* 子节点增加
*/
prt_tree child_add(int data, prt_tree root)
{
//判断子节点是不是空的,不是空就插入子节点的最后一个
//应该子节点是只有一个的,其余的子节点通过兄弟节点链接
prt_tree node = malloc(sizeof(struct tree));
prt_tree child;
memset(node, 0, sizeof(struct tree));
child = end_node_child(root);
child->child = node;
node->data = data;
return node;
}
/**
* 兄弟节点增加
*/
prt_tree brother_add(int data, prt_tree root)
{
//判断兄弟节点是不是空的,不是空就插入至兄弟节点的最后一个
prt_tree node = malloc(sizeof(struct tree));
prt_tree brother;
memset(node, 0, sizeof(struct tree));
brother = end_node_brother(root);
brother->brother = node;
node->data = data;
return node;
}
/**
* 添加树的内容
*/
void add_tree(prt_tree root)
{
char action = 0;
printf("当前节点数据:%d 操作:\n", root->data);
scanf("%s", &action);
switch (action)
{
case 'i':
{
int data = 0;
printf("子节点数据:\n");
scanf("%d", &data);
prt_tree child = child_add(data, root);
add_tree(child);
//子节点插入
break;
}
case 'o':
{
int data = 0;
printf("兄弟节点数据:\n");
scanf("%d", &data);
prt_tree child = brother_add(data, root);
add_tree(child);
//兄弟节点插入
break;
}
case 'q':
//滚回上一个节点
return;
default:
break;
}
add_tree(root);
}
/**
* 输出数
*/
void print_tree(prt_tree root)
{
if (root != NULL)
{
//输出子节点
printf("%d的子节点:\n", root->data);
prt_tree child = root->child;
print_tree(child);
//输出兄弟节点
printf("%d的兄弟节点:\n", root->data);
prt_tree brother = root->brother;
print_tree(brother);
printf("%d\n", root->data);
}
}
int main()
{
prt_tree root = NULL;
root = create_tree();
add_tree(root);
print_tree(root);
system("pause");
return 0;
}

View File

@ -0,0 +1,159 @@
#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");
}

View File

@ -0,0 +1 @@
<mxfile host="www.draw.io" modified="2019-10-06T07:07:06.040Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" etag="-PQZjZE8ojSPPq5nVqYj" version="12.0.2" type="github" pages="1"><diagram id="kHGcZlMXsnaXwJfJm3EK" name="Page-1">7Vtdk5owFP01PLYjBBAe1eq2M9vpxz6025cOK1lIG4kT4yr99Q2SyEeylum2EB2fdnNJgHvOzbk3V7XAbLW/odE6fU9iiC1nFO8t8MZyHHvkuPxPYclLiweEIaEoFpMqwx36BeVKYd2iGG4aExkhmKF107gkWQaXrGGLKCW75rRHgptPXUcJVAx3ywir1i8oZmlpDZxxZX8LUZLKJ9t+WF5ZRXKy8GSTRjHZ1UxgboEZJYSV/632M4gL8CQu5brFM1ePL0Zhxros2ON3Px8e4oDk9i4IJx/8W/vrK1De5SnCW+GweFmWSwRgzAERQ0JZShKSRXheWaeUbLMYFo8Z8VE155aQNTfa3PgDMpYLdqMtI9yUshUWV1VXhHcbsqVLeOL9ZUhENIHsxDzhVuFL7QECqBtIVpDRnE+gEEcMPTXJj0QMJcd5YumE0iivTVgTlLFN7c4fCwOfILYDj5vXXnnPXMZLi7TWCjsYnV7B/ynfQo5q7lSmQyjow2LxkN5+XzwRMs0/fV5+w+Pww7tXtnN5caF31D7TwADB+D8HxilcG3GxUEKjIr5gcZciBu/W0YGwHU8THUl+gpTB/UlWJHygDYYnRHdXaXYoTGlNrsHoeSJrQP7FBlKBSvmti3ttksHxAq4Sbn5/gGkDyztzwXE6JiL3X+vNi1C3zz3/d4VdJjRDcFfT63YDqQlSaoPhhEGrpMEQAQn3iH0tlnOZLEf3tStv9uLOh0EuBxl3t7aoGN7Xr1XLDiO57u+D3+0Y/MFQsa8l1LWvjL6UUXk6NkTOXEXOMBm+yvGbSnaUqKFKnEBBCWWDgyS7E7l03hsWJBnZNZTIlg0Okw3aFfPwSKm7zpp7VjC3gqk1H1vTmTUJGUXQmvvWZGSFqu5y51kTqg2j5CecEUwot2QkK8T3EWHcMkUYJRkfLjmkvHAB0wJKtIzwRFxYoTg+KLeOm6aa//utPtbsdE+lxvlvpz+VGWchKjwKE7QpMLtYMhy7Jby6ErJPOnTNLEkHT1QaFb4YLlpUALc/Kk6ew2pcPLshek+F7bjtsWDQy4iuKVILXF1ivJzIVTNuj8Gr58PX8XGir3cxZByhl12BcGgq1GL6T5ret5x4Lcy8/upFfRY8o16f3oGuH+pIxwxpeDiaQv0KfB/A6/T6CnwPwIdD4Gxci++FnI7N4vTUoda4ZDv4xxaSPRMPOl7Y4YDeK1jqqdCMGs41DSmgtkfPK6UBzUcc+om+UfIHdPJ3Bb4H4FVtuALfC/BgCJzPo4jrzqlnFqe6o6hBRVyr4afrMvWabdUGrDFFnD9qVrzu4GDpWnJnJdR+101t1snMPfuasDPwoVHAA7W/ZML3XjzjlCFUcDLhOx3tdOP5A3fogdozMOEM7I36gqn4esTx91DlTxaqX5WB+W8=</diagram></mxfile>

View File

@ -0,0 +1,57 @@
avlTree 自平衡二叉查找树 是在插入的时候进行旋转,使树的深度相同(不超过1)
![](灵魂画图/valTree单旋.png)
splayTree 伸展树 是在搜索的时候将节点往上提,提到根节点
单次旋转
```graphviz
digraph{
label="初始状态"
l_6;l_77;
a_7[color=blue]
b_8[color=red]
a_7->l_6->l_5
a_7->b_8->r_9
b_8->l_77
l_6->r_66
}
```
```cpp
int tmp = a->data;
a->data = b->data;
b->data = tmp;
```
```graphviz
digraph{
label="交换ab"
l_6;l_77;
b_7[color=red]
a_8[color=blue]
a_8->l_6->l_5
a_8->b_7->r_9
b_7->l_77
l_6->r_66
}
```
```cpp
//之后处理节点,需要吧b_7移动到左边,a_8左指向b_7
//b_7左指向原a_8左(l_6),b_7右指向原b_7左(l_77)
//a_8右指向b_7右(r_9)
prt_tree tmp=a_8->lt;
a_8->lt=b_7;
a_8->rt=b_7->rt;
b_7->rt=b_7->lt;
b_7->lt=tmp;
```
```graphviz
digraph{
label="处理节点"
l_6;r_77;
b_7[color=red]
a_8[color=blue]
a_8->b_7->l_6->l_5
a_8->r_9
b_7->r_77
l_6->r_66
}
```