init commit
This commit is contained in:
103
archive/algorithm/struct/adt/hash.c
Normal file
103
archive/algorithm/struct/adt/hash.c
Normal 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
|
97
archive/algorithm/struct/adt/queue.c
Normal file
97
archive/algorithm/struct/adt/queue.c
Normal 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
|
86
archive/algorithm/struct/adt/stack.c
Normal file
86
archive/algorithm/struct/adt/stack.c
Normal 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
|
109
archive/algorithm/struct/adt/u_link_list.c
Normal file
109
archive/algorithm/struct/adt/u_link_list.c
Normal 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;
|
||||
}
|
94
archive/algorithm/struct/adt/u_link_list.h
Normal file
94
archive/algorithm/struct/adt/u_link_list.h
Normal 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");
|
||||
}
|
149
archive/algorithm/struct/tree/avlTree.c
Normal file
149
archive/algorithm/struct/tree/avlTree.c
Normal 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;
|
||||
}
|
186
archive/algorithm/struct/tree/b-tree.c
Normal file
186
archive/algorithm/struct/tree/b-tree.c
Normal 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;
|
||||
}
|
139
archive/algorithm/struct/tree/binary_tree.c
Normal file
139
archive/algorithm/struct/tree/binary_tree.c
Normal 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;
|
||||
}
|
65
archive/algorithm/struct/tree/b树.md
Normal file
65
archive/algorithm/struct/tree/b树.md
Normal 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绘图插件貌似语法不是很支持,直接换图了....而且确实是有些毛病)
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
然后插入5,6,7,8,9什么的直接略过吧,来看看当上一行也满了怎么办
|
||||
|
||||
这差不多是一个饱和的状态了,再插入一个10就会,往上增加一个,但是上一行也满了,操作也一样
|
||||
|
||||

|
||||
|
||||
|
34
archive/algorithm/struct/tree/huffman.c
Normal file
34
archive/algorithm/struct/tree/huffman.c
Normal 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;
|
||||
}
|
11
archive/algorithm/struct/tree/img/graph1.gv
Normal file
11
archive/algorithm/struct/tree/img/graph1.gv
Normal 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}
|
||||
}
|
BIN
archive/algorithm/struct/tree/img/graph1.png
Normal file
BIN
archive/algorithm/struct/tree/img/graph1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
16
archive/algorithm/struct/tree/img/graph2.gv
Normal file
16
archive/algorithm/struct/tree/img/graph2.gv
Normal 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}
|
||||
}
|
BIN
archive/algorithm/struct/tree/img/graph2.png
Normal file
BIN
archive/algorithm/struct/tree/img/graph2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
32
archive/algorithm/struct/tree/img/graph3.gv
Normal file
32
archive/algorithm/struct/tree/img/graph3.gv
Normal 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}
|
||||
|
||||
}
|
BIN
archive/algorithm/struct/tree/img/graph3.png
Normal file
BIN
archive/algorithm/struct/tree/img/graph3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
archive/algorithm/struct/tree/img/valTree单旋.png
Normal file
BIN
archive/algorithm/struct/tree/img/valTree单旋.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
150
archive/algorithm/struct/tree/splayTree.c
Normal file
150
archive/algorithm/struct/tree/splayTree.c
Normal 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;
|
||||
}
|
156
archive/algorithm/struct/tree/tree.c
Normal file
156
archive/algorithm/struct/tree/tree.c
Normal 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;
|
||||
}
|
159
archive/algorithm/struct/tree/trie.c
Normal file
159
archive/algorithm/struct/tree/trie.c
Normal 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");
|
||||
}
|
1
archive/algorithm/struct/tree/trie.drawio
Normal file
1
archive/algorithm/struct/tree/trie.drawio
Normal 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>
|
57
archive/algorithm/struct/tree/理解.md
Normal file
57
archive/algorithm/struct/tree/理解.md
Normal file
@ -0,0 +1,57 @@
|
||||
avlTree 自平衡二叉查找树 是在插入的时候进行旋转,使树的深度相同(不超过1)
|
||||

|
||||
|
||||
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
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user