赞
踩
参考:https://blog.csdn.net/qq_35644234/article/details/64516551
(这位大佬真的强啊,很喜欢他的风格)
二叉搜索树(BST,Binary Search Tree),也称为二叉查找树或二叉排序树
二叉搜索树:一颗二叉树,可以为空;如果不为空,满足以下性质:
二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树便可得到一个有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即是对无序序列进行排序的过程。
查找的效率决定于树的高度
查找最大和最小元素
递归实现 & 非递归实现
分析:关键是要找到元素应该插入的位置,可以采用与查找类似的方法
考虑三种情况:
#include <iostream> using namespace std; typedef int ElemType; struct BiTreeNode { ElemType data; BiTreeNode* left; BiTreeNode* right; }; // 查找二叉排序树 成功返回true,失败返回false // 指针p返回查找到的结果指针 bool searchBST(BiTreeNode* T, ElemType key, BiTreeNode*& p) { if (!T) { p = nullptr; return false; } // 遍历整个二叉树 while (T) { p = T; if (key == T->data) { // 相等说明找到了对应关键字 return true; } else if (key > T->data) { // 往右子树查找 T = T->right; } else if (key < T->data) { T = T->left; // 往左子树查找 } } // 如果执行到了这里,说明并未找到 return false; } // 创建二叉排序树(插入操作) bool createBST(BiTreeNode*& T, ElemType key) { BiTreeNode* p; // 未查到key的存在,则创建 if (!searchBST(T, key, p)) { BiTreeNode* newNode = new BiTreeNode; newNode->data = key; newNode->left = newNode->right = nullptr; if (!p) { // 说明当前二叉树为空 T = newNode; } else if (p->data > key) { // 新插入结点为结点的左子树 p->left = newNode; } else { p->right = newNode; // 新插入结点为右子树 } return true; } // 说明这个关键字已经在二叉排序树中 return false; } // 删除关键字结点的删除部分, T为指向被删除节点的父结点 bool deleteNode(BiTreeNode*& T) { BiTreeNode* q; if (!T->left) { // 左子树为空,直接接右子树 q = T; T = T->right; delete q; } else if (!T->right) { // 右子树为空,直接接左子树 q = T; T = T->left; delete q; } else { // 左右子树都不为空,则找左子树最靠右结点或右子树最靠左结点 q = T; BiTreeNode* del = T->left; while (del->right) { q = del; del = del->right; } // 经过上面的while循环,q已经是指向左子树最靠右的结点的父结点 // s为指向左子树最靠右的结点 T->data = del->data; // 只更新数据部分 // 下面比较绕,需要画图看看 // 处理要删除的s指针指向的左子树 if (q != T) { q->right = del->left; } else { q->left = del->left; } delete del; } return true; } // 删除关键字结点 bool deleteBST(BiTreeNode*& T, ElemType key) { if (!T) { // 数为空直接返回 return false; } while (T) { if (T->data == key) { return deleteNode(T); } else if (T->data < key) { // key大,走向右子树 T = T->right; } else { // key小,走向左子树 T = T->left; } } // 关键字不存在 return false; } // 销毁二叉排序树 void destroyBST(BiTreeNode* T) { if (T) { destroyBST(T->left); destroyBST(T->right); delete T; } }
使用二叉排序树进行查找,最好的情况是二叉排序树的形态和折半查找的判定树相同,其平均查找长度和logn成正比,即:(O(log2(n)))。
最坏情况下,当先后插入的关键字有序时,构成的二叉排序树为一棵斜树,树的深度为n,其平均查找长度为(n + 1) / 2。也就是时间复杂度为O(n),等同于顺序查找。
因此,如果希望对一个集合按二叉排序树查找,最好是要对排序树进行一些必要的优化,如下:
这些均可以使查找树的高度为 :O(log(n))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。