一搜索二叉树的插入, 查找, 删除
简单说说搜索二叉树概念:
二叉搜索树又称二叉排序树, 它或者是一棵空树, 或者是具有以下性质的二叉树
若它的左子树不为空, 则左子树上所有节点的值都小于根节点的值
若它的右子树不为空, 则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
例如: int a [] = {5,3,4,1,7,8,2,6,0,9};
二叉树结构
- typedef struct BSTreeNode
- {
- struct BSTreeNode *_left;
- struct BSTreeNode *_right;
- DataType _data;
- }BSTreeNode;
二叉树节点创建
- BSTreeNode *BuyTreeNode(DataType x) // 创建节点
- {
- BSTreeNode *node = (BSTreeNode*)malloc(sizeof(BSTreeNode));
- assert(node);
- node->_data = x;
- node->_left = NULL;
- node->_right = NULL;
- return node;
- }
二叉搜索树操作:
1 搜索二叉树的插入: 在二叉搜索树中插入新元素时, 必须先检测该元素是否在树中已经存在如果已经存在, 则不进行插入; 否则将新元素加入到搜索停止的地方
非递归代码
- int BSTreeNodeInsert(BSTreeNode **pptree,DataType x) // 搜索树的插入
- {
- BSTreeNode *parent = NULL;
- BSTreeNode *cur = *pptree;
- if (*pptree == NULL)
- {
- *pptree = BuyTreeNode(x);
- return 0;
- }
- while (cur)
- {
- parent = cur;
- if (cur->_data > x)
- cur = cur->_left;
- else if (cur->_data < x)
- cur = cur->_right;
- else
- return -1;
- }
- if (parent->_data > x)
- parent->_left = BuyTreeNode(x);
- else
- parent->_right = BuyTreeNode(x);
- return 0;
- }
递归代码 :
- int BSTreeNodeInsertR(BSTreeNode **tree,DataType x) // 搜索树的插入
- {
- if(*tree == NULL)
- {
- *tree = BuyTreeNode(x);
- return 0;
- }
- if ((*tree)->_data > x)
- return BSTreeNodeInsertR(&(*tree)->_left,x);
- else if ((*tree)->_data < x)
- return BSTreeNodeInsertR(&(*tree)->_right,x);
- else
- return -1;
- }
2 搜索二叉树的查找:
非递归代码
- BSTreeNode *BSTreeNodeFind(BSTreeNode *tree,DataType x) // 查找
- {
- while (tree)
- {
- if (tree->_data == x)
- return tree;
- else if (tree->_data < x)
- tree = tree->_right;
- else
- tree = tree->_left;
- }
- return NULL;
- }
递归代码
- BSTreeNode *BSTreeNodeFindR(BSTreeNode *tree,DataType x) // 查找
- {
- if (!tree)
- return NULL;
- if (tree->_data > x)
- BSTreeNodeFindR(tree->_left,x);
- else if (tree->_data < x)
- BSTreeNodeFindR(tree->_right,x);
- else
- return tree;
- }
3 搜索二叉树的删除:
首先查找元素是否在二叉搜索树中, 如果不存在, 则返回, 否则要删除的结点可能分下面四种情况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左右孩子结点
情况 1 可以归类到 2 或者 3
对于上述情况, 相应的删除方法如下:
a. 直接删除该结点
b. 删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点
c. 删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点
d. 在它的右子树中寻找中序下的第一个结点 (关键码最小), 用它的值填补到被删除节点中, 在来处理该结点的删除问题
非递归代码实现:
- int BSTreeNodeDel(BSTreeNode **tree,DataType x) // 删除
- {
- BSTreeNode *cur = *tree;
- BSTreeNode *parent = *tree;
- BSTreeNode *del = NULL;
- while (cur)
- {
- if (cur->_data > x)
- {
- parent = cur;
- cur = cur->_left;
- }
- else if (cur->_data < x)
- {
- parent = cur;
- cur = cur->_right;
- }
- else
- {
- del = cur;
- if (cur->_left == NULL) //1 左孩子为空
- {
- if (parent->_left == cur)
- parent->_left = cur->_right;
- else if (parent->_right == cur)
- parent->_right = cur->_right;
- else if (parent == cur) // 没有父亲节点时
- *tree = parent->_right;
- }
- else if (cur->_right == NULL) //2 右孩子为空
- {
- if (parent->_left == cur)
- parent->_left = cur->_left;
- else if (parent->_right == cur)
- parent->_right = cur->_left;
- else if (parent == cur) // 没有父亲节点时
- *tree = parent->_left;
- }
- else//3 左右孩子都不为空
- {
- BSTreeNode *sub = cur->_right;
- while (sub->_left)
- {
- parent = sub;
- sub = sub->_left;
- }
- del = sub;
- cur->_data = sub->_data;
- if (parent->_left == sub)
- parent->_left = sub->_right;
- else
- parent->_right = sub->_right;
- }
- free(del);
- del = NULL;
- return 0;
- }
- }
- return -1;
- }
递归代码实现
- int BSTreeNodeDelR(BSTreeNode **tree,DataType x) // 删除
- {
- if (!*tree)
- return -1;
- if ((*tree)->_data > x)
- return BSTreeNodeDelR(&(*tree)->_left,x);
- else if ((*tree)->_data < x)
- return BSTreeNodeDelR(&(*tree)->_right,x);
- else
- {
- BSTreeNode *del = *tree;
- if (!(*tree)->_left) // 左为空
- *tree = (*tree)->_right;
- else if (!(*tree)->_right) // 右为空
- *tree = (*tree)->_left;
- else // 左右都不为空
- {
- BSTreeNode *sub = (*tree)->_right;
- while (sub->_left)
- sub = sub->_left;
- (*tree)->_data = sub->_data;
- return BSTreeNodeDelR(&(*tree)->_right,sub->_data);
- }
- free(del);
- del = NULL;
- return 0;
- }
- }
完整代码请私信或者点此链接下载数据结构搜索二叉树的插入, 查找和删除 (递归 & 非递归)
来源: http://blog.csdn.net/qq_38646470/article/details/79381971