树可能是小伙伴们比较恐惧的一种数据结构,在将这个东东前,先明白树的基本操作
1,前中后层 四大遍历手法,下面将一一拆开讲解。
1,前序遍历
思想:先头,再左儿子, 最后右儿子
int idx = 0;
void front(TreeNode root, int* nums){
nums[idx++] = root->val;
front(root->left, nums);
front(root->right, nums);
}
结果:A B D H I E J C F K G
2, 中序遍历
思想: 先左,再头,再右节点
int idx = 0;
void mid(TreeNode root, int* nums){
if(!root){
return;
}
mid(root->left, nums);
nums[idx++] = root->val;
mid(root->right, nums);
}
结果:H D I B E J A F K C G
3,后序遍历
思想:先左,再右,最后头
int idx = 0;
void back(TreeNode* root, int* nums){
if(!root){
return;
}
back(root->left, nums);
back(root->right, nums);
nums[idx++] = root->val;
}
结果: H I D J E B K F G C A
4,层序遍历
思想:一层一层遍历
void LevelOrderBinaryTree(pTreeNode t){
pQueue pq=(pQueue)malloc(sizeof(Queue));
pq=init(pq);
enqueue(pq,t);
while(pq->rear!=pq->front){
pTreeNode x = dequeue(pq);
printf("%d ",x->data);
if(x->left){
enqueue(pq,x->left);
}
if(x->right){
enqueue(pq,x->right);
}
}
}
结果:A B C D E F G H I J K
2,二叉树
什么是二叉树?
二叉树的每个节点最多只有两个儿子(二胎政策)
二叉查找树: 对于每个节点来说, 左儿子小于他, 右儿子大于他
①创建一个空树
SearchTree MakeEmpty(SearchTree T){
if(T!=NULL){
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
}
return NULL;
}
②Find demo
Position Find(SearchTree T, int val){
if(T == NULL){
return NULL;
}
if(val > T->val){
Find(T->right, val);
}else if(val < T->val){
Find(T->left, val);
}else{
return T;
}
}
③ FindMin demo
Position FindMin(SearchTree T){
if(T == NUll)
return NULL;
if(T->left == NULL){
return T;
}
return FindMin(T->left);
}
④FindMax demo
Position FindMax(SearchTree T){
if(T == NULL)
return NULL;
while(T->right != NULL){
T = T->right;
}
return T;
}
⑤Insert demo
SearchTree Insert(SearchTree T, int val){
if(!T){
T = malloc(sizeof(SearchTree));
}else{
if(val < T->val){
T->left = Insert(T->left, val);
}else if(val > T->val){
T->right = Insert(T->right, val);
}
}
return T;
}
⑥delete demo
SearchTree Delete(SearchTree T, int val){
if(T->NULL){
return NULL;
}else if(val > T->val){
T->right = Delete(T->right, val);
}else if(val < T->val){
T->left Delete(T->left, val);
}else if(T->left && T->right){
Position temp = FindMin(T->right);
T->val = temp->val;
T->right = Delete(T->right, T->val);
}else{
Position Tmp = T;
if(T->left){
T = T->right;
}else if(T->right){
T = T->left;
}
free(Tmp);
}
return T;
}
3,AVL树
每个节点的左子树和右子树最多相差1
①AVL树的节点声明
struct AvlNode{
int val;
struct AvlNode left;
struct AvlNode right;
int height;
}
②AVL节点的高度计算
int HeightNode(Position P){
if(!p){
return -1;
}else{
return P->height;
}
}
③单旋转demo
Position Singleleft(Position K2){
Position K1;
K1 = K2->left;
K2->left = K1->right;
K1->right = K2;
K2->height = max(height(K2->left), height(K2->right)) + 1;
K1->height = max(height(K1->left), K2->height) + 1;
return K1;
}
④双旋转demo
Position Doubleleft(Position K3){
K3->left = Singleright(K3->left);
return Singleleft(K3);
}
⑤向AVL树插入节点demo
AvlTree Insert(int val, AvlTree T){
if(!T){
T = malloc(sizeof(AvlTree));
T->val = val;
T->left = NULL;
T->right = NULL;
}else if(X < T->val){
T->left = Insert(val, T->left);
if(Height(T->left) - Height(T->right) == 2 ){
T = Singleleft(T);
}else{
T = Doubleleft(T);
}
}else if(X > T->val){
T->right = Insert(val, T->right);
if(Height(T->right) - Height(T->left) == 2){
T = Singleright(T);
}else{
T = Doubleright(T);
}
}
T->height = MAX(Height(T->left), Height(T->right)) + 1;
return T;
}
至此为止,你已经明白什么是树啦,开始愉快的做题吧~
1,二叉树的中序遍历
2,合并二叉树
3,二叉树的层序遍历
4,打家劫舍
5,路径总和