树
1、遍历
1.1 层序遍历
void BFS(int root){
queue<node> q;
q.push(tree[root]);
while(!q.empty()){
node temp = q.front();
q.pop();
printf("%d",temp.id);
if(temp.l != -1) q.push(tree[temp.l]);
if(temp.r != -1) q.push(tree[temp.r]);
}
}
1.2 中序遍历
void DFS(int root){
if(root == -1) return;
DFS(tree[root].l);
printf("%d",root);
DFS(tree[root].r);
}
1.3 后序
void postTra(int start){
if(start == -1){
return;
}
postTra(tree[start].lnode);
postTra(tree[start].rnode);
printf(" %d",tree[start].num);
}
1.4 前序、后序、中序遍历互相转换
已知先序、中序 求后序:
三个参数,分别为:
> --->当前子树根节点对应inorder的下标:root;
> --->当前子树的起始坐标(preorder):start;
> --->当前子树的最后一个坐标(preorder):end;
递归边界
> ---> start > end
递归操作
> --->循环找到(inorder中)根节点所在位置(根据inorder[root]):i;
> --->递归*2;两组参数:
> --->(root + 1,start,i - 1) (root + i - start + 1,i + 1,end)
总结了半天,总结不出来规律……练吧,练出肌肉记忆脑子就不发懵了
2、查找树BST
3、平衡二叉树AVL
二叉树的链表表示
struct node{
int val;
struct node *left,*right;
};
//左旋----RR型----(-2,-1)
node* rotateLeft(node *root){
node* t = root->right;
root->right = t->left;
t->left = root;
return t;
}
//右旋----LL型----(2,1)
node* rotateRight(node *root){
node* t = root->left;
root->left = t->right;
t->right = root;
return t;
}
//先左后右----LR型----(2,-1)
node* rotateLeftRight(node *root){
root->right = rotateLeft(root->right);
return rotateRight(root);
}
//插入
node* insert(node *root,int val){
if(root == NULL){
root->val = val;
root->left = root->right = NULL;
}else if(val < root->val){
insert(root->left,val);
if()
}else{
insert(root->right,val);
}
return root;
}
4、并查集
union
void unin(int a,int b){
a = findFather(a);
b = findFather(b);
father[b] = a;
}
优化查询,越查越快。
int findFather(int index){
int a = index;
while(index != father[index])
index = father[index];
while(a != index){
int temp = a;
a = father[a];
father[a] = index;
}
return index;
}
5、堆
6、哈夫曼树
7、完全二叉树的判别(链表表示)
bool cbt(node* root){
queue<node*> q;
q.push(root);
while(root = q.front()){
//队列头部为空节点时停止入队
q.push(root->left);
q.push(root->right);
q.pop();
}
while(!q.empty()){
//空节点后还有非空节点,则不是完全二叉树
if(q.front() != NULL) return false;
q.pop();
}
return true;
}