说来也惭愧,就近两周都在看二叉树,虽然学的时间很多,但是对他的了解确实少之又少。或许是跳过了线性表的链式存储,感觉学的时候就比较困难,就来一点一点说吧。
二叉树每个结点有两个子结点——左孩子、右孩子。左孩子和右孩子也可以当做结点,也会有他的左孩子右孩子,这样就构成了一个倒立的树。
结点的构造
struct Node
{
int data; //存放数据
Node* lch; //左孩子的地址
Node* rch; //右孩子的地址
};
树:
struct Tree
{
Node *root;//树根
};
树根,其他的空间来用new来创建。
二叉搜索树(BST):每个元素有唯一的键值,键值能够比较大小,任意一个结点的键值,都比他的左子树大比他的右子树小。
插入一个结点。
void Insert(Tree *tree,int value)
{
Node* node=new Node; //构造一个空间,插入新的子结点
node->data=value;
node->lch=NULL;
node->rch=NULL;
if(tree->root==NULL)
tree->root=node;
else
{ Node *temp=tree->root;
while(temp!=NULL) //寻找插入结点
{
if(value<temp->data) //判断在左节点还是右节点
{if(temp->lch==NULL)
{temp->lch=node;return ;}
else{temp=temp->lch;}
}
else
{if(temp->rch==NULL)
{temp->rch=node; return ;}
else temp=temp->rch;
}
}
}
return ;
}
其实在这里插入之后怎么样变成还需要变成平衡二叉树,但是我还没有搞明白他怎么变成,通过treap还是其他的,等我深入了解一下在来补充吧。
旋转:
treap树的旋转就是交换父节点和子结点(更换父亲),再使得原来的树达到新的二叉搜索树。这个旋转感觉能够通过更换父亲而使得自己的树更加的平衡,达到平衡二叉树的效果,但是在达到效果还需要其他的代码的限制(也没做这个相关的题,现在只能了解的这么肤浅。)
旋转分为两种左旋和右旋,上图为右旋,左旋就是倒过来。
旋转代码如下:
右旋:
void rotate(Node *o,int d)
{
Node *k=o->lch;
o->lch=k->rch;
k->rch=o;
o=k;
}
左旋:
void rotate(Node *o,int d)
{
Node *k=o->rch;
o->rch=k->lch;
k->lch=o;
o=k;
}
其实当时对这个代码还是有点看不懂的,但是画一个图就瞬间明白了,所以实践出真知啊!!
最后就简简单单来一个二叉树的代码(没有旋转版)
#include <cstdlib>
//#include <stdio.h>
#include<iostream>
#include <bits/stdc++.h>
struct Node
{
int data;
Node* lch;
Node* rch;
};
struct Tree
{
Node *root;
};
void Insert(Tree *tree,int value)
{
Node* node=new Node;
node->data=value;
node->lch=NULL;
node->rch=NULL;
if(tree->root==NULL)
tree->root=node;
else
{
Node *temp=tree->root;
while(temp!=NULL)
{
if(value<temp->data)
{if(temp->lch==NULL)
{
temp->lch=node;
return ;
}
else
{temp=temp->lch;}
}
else
{
if(temp->rch==NULL)
{temp->rch=node;
return ;}
else temp=temp->rch;
}
}
}
return ;
}
void Inorder(Node *node)
{
if(node!=NULL)
{Inorder(node->lch);
printf("%d ",node->data);
Inorder(node->rch);
}
}
int main()
{
Tree tree;
tree.root=NULL;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int temp;
scanf("%d",&temp);
Insert(&tree,temp);
}
Inorder(tree.root);
return 0;
}
为啥cin和cout不能用
这串代码就是插入数字来实现中序遍历,但是这个代码有一个问题就是我的cin和cout用不了就很奇怪,只能用scanf和printf就比较奇怪,不知道是哪里的问题,而且这串代码不能实现一个平衡二叉树,也就是说,通过插入的数字有可能构造的二叉树每一个子树只有左子树或者只有右子树。总之,代码还是很废的,但是这个代码却还是大部分人能够看得懂得,并没有很复杂。
其实本来不打算写二叉树的,因为二叉树真的没有搞懂,但是不写它我也不知道改写什么了,因为这一周看的全是二叉树,找了很多的博客总感觉不是自己想找的那个,最后东拼西凑的找到了几个代码,才总算对二叉树了解了一些,二叉树的题也没做,因为二叉树的题好像都很难,对于初看二叉搜索树的我真的不从下手。最后吧总结一下上周,预告一下这一周的工作吧。上一周主要就是看的二叉树,只能说是了解的很浅很浅很浅~~~,这一周呢做几个二叉搜索树的题,在看一看了解一下二叉树,如果有空余的时间,就在做几个dp的题,(今天看了看dp,感觉当时觉得挺不好理解的东西,看在感觉也不是当初那么难了)。汇报结束,关灯睡觉!!