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)