今天来学习一下二叉搜索树:
二叉搜索树:
这种二叉树比较适合进行搜索问题,他的左孩子比根节点小,然后根节点比右孩子小,搜索数据的话非常方便,就比如上面的二叉树,假如要搜索一个数据的时候,直接和根节点比较,比根节点小的话,就在左边查找,比根节点大的话,我们就去右边进行查找,最多就是要搜索这颗树的高度。
并且如果我们的这颗二叉树的遍历如果是中序的(左根右的方式)进行遍历的时候,他便利的结果就是一个升序的数据。
我们的这个二叉树的查找的时间复杂度为log(n);
但是有的比较极端的二叉树的时间复杂度为N;
我们在实现我们的二叉树的底层的时候,我们一般实现的是二叉树的增删查,没有修改数据这个函数,因为我们说了,我们的这个二叉搜索树,他的要求是左结点小于根节点小于右节点,如果我们贸然的修改了某个位置的数据,这时候他可能不满足我们的这个二叉搜索树的要求了。
二叉树的插入:
我们看这个图片:现在我们有一个结点:16;我们现在想把这个数据插入到我们的二叉树里面,那我们该怎么插入呢?,,我们要插入这个数据,当然我们的前提是不能破坏掉我们的搜索二叉树的结构;
进入到我们的二叉树,我们看这个数据的大小,比我们的根节点的数据要大,就看根节点的右节点,比我们的右子树的根节点还要大,我们就进入到右子树,再右子树的右节点和他进行比较,他比我们的这个结点还要大,我们就一直往右边比较,直到最后比我们的最右边的叶子结点还要大的时候,我们就把他放到我们的最右边。
这个是我们的插入函数的实现。
二叉树的删除:
当我们的结点拥有两个孩子的时候,这时候我们要删除这个结点,这时候我们不能直接删除掉,这个我们就需要找一个结点来替代我们的这个结点,替换完后,把我们的结点删除掉。
替代的结点:(左子树的最大的结点或者是右子树的最小的结点)。
这时候我们要删除8这个结点,左子树的最大的就是7,右子树最小的就是10这个节点。这两个都可以作为我们的根节点的替代的结点。
二叉树的查找:
搜索二叉树最主要的部分我们讲完了。
小拓展:
二叉树的拷贝构造和析构:
我们看这个:我们把t1拷贝给t2,这时候我们自己没有实现拷贝构造,是通过编译器自己实现的,这时候编译器自己实现的拷贝构造实现的是浅拷贝,两个指针指向同一个树,这样明显不行,所以我们就自己实现一个拷贝构造来进行。
析构函数:
我们自己写树的析构函数,析构函数的话,我们写析构的顺序应该是左右根的顺序来进行析构,我们要把根结点留到最后来析构,不然先析构根节点的话,就找不到左右孩子了。
复制重载:
我们再看我们的复制重载:要实现我们的复制重载,因为我们实现了我们的拷贝构造,我们这里的复制重载的参数,我们使用传值传参,(因为传值传参和传值返回)要调用拷贝构造,实行深拷贝,我们的变量t进行了深拷贝,指向了我们需要的内存空间,然后我们的t1指向的内存空间我们不想要了,我们就进行交换,把我们的t1指向的内存空间和t进行交换,然后出了函数以后,对象t调用析构函数释放内存空间。