2. 二叉排序树
2.1 二叉排序树(又叫二叉搜索、查找树) 性质:
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
- 左、右子树也分别为二叉排序树。
数列的顺序不同创建出来的二叉排序树是会不一样的!
(65 ,32,87, 46,71,98, 39)
每一层数字的顺序是可以换的,32和87是可以换的。 (32,39,46,65,71,87,89)
如果实际应用中遇到相同的值,那么向左向右插入都可以,只要保证树在中序遍历时是非严格单调递增即可。
2.2 二叉排序树的建立(非递归+递归算法实现)
注意:结构体里给了left,right默认值NULL。
非递归算法:
typedef struct BinarySortTreeNode{ int data; struct BinarySortTreeNode *Left = NULL; struct BinarySortTreeNode *Right = NULL; }*BinarySortTree; BinarySortTree CreatBStree(int *a,int length) { BinarySortTree BST = new BinarySortTreeNode; BST->data = *a++; for (int i = 1; i < length; i++) { int sign; BinarySortTreeNode *pre = BST, *p = BST, *Node=new BinarySortTreeNode; while (p) { pre = p; if (*a <= p->data) { p = p->Left; sign = 0; } else { p = p->Right; sign = 1; } } Node->data = *a; sign ? pre->Right = Node : pre->Left = Node; a++; } return BST; }
2.3 二叉排序树的插入与删除
(1)插入节点
这个算法加个循环就可以作为 " 建立二叉排序树 " 的算法,上面说的递归算法在这里 - _ - !
BinarySortTree InsertBStree(BinarySortTree BST, int x) { if (BST == NULL){ BST = new BinarySortTreeNode; BST->data = x; return BST; } if (x <= BST->data) BST->Left = InsertBStree(BST->Left, x); else if (x > BST->data) BST->Right = InsertBStree(BST->Right, x); return BST; } BinarySortTree CreatBStByRecursion(int *a,int length) { BinarySortTree BST; BST = NULL; for (int i = 0; i < length; i++) BST = InsertBStree(BST, a[i]); return BST; }
(2)查找节点
找不到返回NULL,找到返回该节点。
BinarySortTreeNode* BSTreeFind(BinarySortTree BST,int x) { if (!BST) { //cout << "binart sort tree is null." << endl;return NULL; } BinarySortTree p = BST; while (p) { if (x > p->data) p = p->Right; else if (x < p->data)p = p->Left; else if (x == p->data) return p; } return NULL; }
(3)删除节点
1. 被删除的结点是叶子,将父节点的 left 或 right 指针域设置为NULL。
这是错的!!!这是错的!!!查资料时,看到一位大兄弟这样写,p时要删除的节点,一度误导了我,让我觉得他是对的,但是作为搞基计算机人,要敢于否定!!
if( !p->lchild && !p->rchild ) p = NULL;
2. 被删除的结点只有左子树或者只有右子树,用该节点的 left 或 right 重新接上来。和删除单链表节点类似。
3. 被删除的结点既有左子树,也有右子树,需要按照二叉排序树的性质从其左子树或者有子树中选择节点补到待删除节点的位置。(选左、选右都可以)
如果从左子树中选,就应该选择左子树中最右边的那个叶子节点(这里肯定是叶子,如果不是叶子,那么就不是最右边的节点)
如果从右子树中选,就应该选择有子树中最左边的那个叶子节点。
typedef struct BinarySortTreeNode{ int data; struct BinarySortTreeNode *Left = NULL; struct BinarySortTreeNode *Right = NULL; }*BinarySortTree; void BSTreeDelete(BinarySortTree BST,int x) { if (!BSTreeFind(BST, x))return; BinarySortTreeNode *p = BST; BinarySortTreeNode *pre = p; int sign; while (p) { if (x > p->data) { pre = p; sign = 0; p = p->Right; } else if (x < p->data){ pre = p; sign = 1; p = p->Left; } else break; } //1. 左右子树都为空 if (p->Left == NULL && p->Right == NULL) { sign ? pre->Left = NULL : pre->Right = NULL; delete p; p = NULL; return; } //2. 左子树或右子树为空 if (p->Left == NULL) { sign ? pre->Left = p->Right:pre->Right = p->Right; delete p; } else if (p->Right == NULL) { sign ? pre->Left = p->Left : pre->Right = p->Left; delete p; } //3.左右子树都不为空 else { BinarySortTreeNode *pre = p->Left, *q = p->Left; while (q->Right) { pre = q; q = q->Right; } p->data = q->data; if (q == p->Left) p->Left = p->Left->Left; else {//最右边的,这个节点只可能有左子树 pre->Right = q->Left; } delete q; } }
原文地址:https://www.cnblogs.com/czc1999/p/10284501.html
时间: 2024-10-14 02:28:17