1.查询二叉树(binary search tree)
性质:所有左子树节点的值<父节点的值<右节点的值,中序遍历可以得到排序好的数组。
struct node {
int key; node* lchild,*rchild;
};
node* new_node(void) {
node* t=(node*)malloc(sizeof(node));
t->lchild=t->rchild=NULL;
}
void tree_insert(node* root,node* t) {
int key=t->key;
if(root!=NULL) {
if(key==root->key) {
t->rchild=root->rchild;
root->rchild=t;
} else if(key>root->key) {
if(root->rchild==NULL)
root->rchild=t;
else
tree_insert(root->rchild,t);
} else {
if(root->lchild==NULL)
root->lchild=t;
else
tree_insert(root->lchild,t);
}
}
else
root=t;
}
int tree_search(node* root,int key) {
if(root==NULL) return 0;
else {
if(key==root->key)
return 1;
else if(key>root->key)
return tree_search(root->rchild,key);
else
return tree_search(root->lchild,key);
}
}
node* delete_aux(node* p) {
if(p!=NULL) {
node* q,*s;
if(p->lchild==NULL) {
q=p;
p=p->rchild;
free(q);
} else if(p->rchild==NULL) {
q=p;
p=p->lchild;
free(q);
} else {
s=p->rchild;
while(s->lchild!=NULL) {
q=s;
s=s->rchild;
}
p->key=s->key;
if(q!=p)
q->lchild=s->rchild;
else
q->rchild=s->rchild;
free(s);
}
}
return p;
}
node* tree_delete(node* root,int key) {
if(root==NULL)
return NULL;
else {
if(key==root->key)
return delete_aux(root);
else if(key>root->key)
root->rchild=tree_delete(root->rchild,key);
else
root->lchild=tree_delete(root->lchild,key);
}
}
void tree_print(node* root) {
if(root!=NULL) {
tree_print(root->lchild);
cout<<root->key<<endl;
tree_print(root->rchild);
}
}
2.红黑树(red-black tree)
3.字典树(trie)
#define N 26
struct trie_node {
//data是标志,如果data=0,表示不是完整的字符串;data=1表示完整的字符串
int data;
//trie树其实是26叉树
struct trie_node* next[N];
};
trie_node* root;
//工厂模式
trie_node* new_trie_node() {
trie_node* t=(trie_node*)malloc(sizeof(trie_node));
for(int i=0;i<N;i++) t->next[i]=NULL;
return t;
}
void trie_init() {
root=new_trie_node();
}
void trie_insert(char *str) {
int len=strlen(str);
trie_node* t=root;
for(int i=0;i<len;i++) {
trie_node* p=new_trie_node();
t->next[str[i]-'a']=p;
//最后一个节点设置data=1
if(i==len-1) p->data=1;
else p->data=0;
t=p;
}
}
int trie_search(char *str) {
trie_node* t=root;
int len=strlen(str);
for(int i=0;i<len;i++) {
if(t->next[str[i]-'a']==NULL)
return 0;
else t=t->next[str[i]-'a'];
}
return t->data;
}
void trie_delete(char *str) {
if(trie_search(str)) {
trie_node* t=root;
int len=strlen(str);
for(int i=0;i<len;i++) t=t->next[str[i]-'a'];
t->data=0;
}
}
4.左偏树(lefties tree)
左偏树最核心的是合并操作,其他的操作比较简单,且其实现的功能和最小(大)堆类似,合并的时间复杂度为O(lgN)
struct node {
int val,dist;
node* lchild,* rchild;
};
int get_dist(node*a) {
return a==NULL?(-1):a->dist;
}
node* tree_merge(node* a,node* b) {
if(a==NULL) return b;
if(b==NULL) return a;
//左边的树的根值小于右边树根值
if(a->val > b->val) swap(a,b);
//将左边根的右子树和右边树的根合并
a->rchild=tree_merge(a->rchild,b);
//使左子树的距离小于右子树的距离
if(get_dist(a->rchild) > get_dist(a->lchild))
swap(a->lchild,a->rchild);
a->dist=get_dist(a->rchild);
return a;
}
5.线段树(segment tree)
struct segment_node {
int cover; int left; int right;
struct sement_node *lchild,*rchild;
};
sement_node* segment_build(sement_node *root,int a,int b) { //a<=b
root=(sement_node*)malloc(sizeof(segment_node));
root->left=a; root->right=b;
root->lchild=NULL; root->rchild=NULL;
root->cover=0;
if(a<b) { //if a==b break the recursion
int mid=(a+b)/2;
segment_build(root->left,a,mid);
segment_build(root->right,mid+1,b);
}
return root; //return root of segment tree
}
void segment_update(segment_node* root,int a,int b) {
if(a<=root->left && b>=root->right) {
root->cover++;
segment_update(root->left,a,b);
segment_update(root->right,a,b);
} else {
int mid=(root->left+root->right)/2;
if(a<mid) segment_update(root->left,a,b);
if(b>mid) segment_update(root->right,a,b);
}
}
6.后缀树(suffix tree)
1万+

被折叠的 条评论
为什么被折叠?



