二叉排序树的插入与删除

一、二叉排序树的插入

  首先检查要插入的数据是否已存在,若存在则不插入,若不存在,则把元素插入到在二叉树上查找失败时的结点的左孩子和右孩子上。需要考虑的特殊情况是插入第一个元素前,二叉树为空。

  

 1 bool insert(BiTreeNode *&root,DataType *item) {
 2     BiTreeNode *current = NULL,*parent = NULL,*p = NULL;
 3     current = root;
 4     while(current != NULL) {
 5         if(current->data.key == item->key)return false;
 6         parent = current;
 7         if(current->data.key < item->key)
 8             current = current->rightChild;
 9         else
10             current = current->leftChild;
11     }
12     p = new BiTreeNode;
13     p->data = *item;
14
15     //the new node is root node
16     if(parent == NULL)
17         root = p;
18     //as leftChild
19     else if(item->key < parent->data.key)
20         parent->leftChild = p;
21     //as rightChild
22     else
23         parent->rightChild = p;
24     return true;
25 }

二、二叉排序树的删除

  删除操作的要求是:首先检查要删除的元素是否存在,若不存在,直接返回若存在,理论上需要考虑2*4种情况。

  a、要删除的节点为根节点。

  b、要删除的节点不为根节点。

    1、该节点无孩子节点。

      sln1:直接删除该节点。

    2、该节点只有左孩子节点。

      sln2:被删除节点的父节点指向该节点的左孩子节点,被删除节点是其父节点的左节点还是右节点,亦或是根节点,则需要判断。

    3、该节点只有右孩子节点。

      sln3:类似sln2。

    4、该节点有左、右孩子节点。

      sln4:首先:寻找数据元素关键字大于要删除节点关键字的最小值,即要删除节点右子树的最左子树,例如为Kdata。

        然后:把Kdata的数据赋给要删除的元素。

        最后:以要删除元素的右子树为根节点,以Kdata为要删除的数据,递归调用删除算法。

 1 bool deleteNode(BiTreeNode *&root,DataType item) {
 2     BiTreeNode *current = root,*parent = NULL,*p = NULL,*kmin = NULL;
 3     bool flag = false;
 4     //寻找要删除的节点和其父节点
 5     while(current != NULL) {
 6         if(current->data.key == item.key) {
 7             flag = true;
 8             break;
 9         }
10         parent = current;
11         if(current->data.key < item.key)
12             current = current->rightChild;
13         else current = current->leftChild;
14     }
15     //未找到要删除的元素
16     if(flag == false) {
17         cout<<"delete error:item not found"<<endl;
18         return false;
19     }
20     if(current->leftChild == NULL) {
21         p = current;
22         if(parent != NULL) {
23             if(parent->leftChild != NULL && parent->leftChild->data.key == current->data.key)
24                 parent->leftChild = current->rightChild;
25             else parent->rightChild = current->rightChild;
26         } else {
27             root = current->rightChild;
28         }
29         delete p;
30     } else if(current->rightChild == NULL) {
31         p = current;
32         if(parent != NULL) {
33             if(parent->leftChild != NULL && parent->leftChild->data.key == current->data.key)
34                 parent->leftChild = current->leftChild;
35             else parent->rightChild = current->leftChild;
36         } else {
37             root = current->leftChild;
38         }
39         delete p;
40     } else {
41         kmin = current->rightChild;
42         while(kmin->leftChild != NULL) {
43             kmin = kmin->leftChild;
44         }
45         if(parent != NULL)
46             current->data = kmin->data;
47         else
48             root->data = kmin->data;
49         deleteNode(current->rightChild,kmin->data);
50     }
51     return true;
52 }

完整测试代码:

  1 #include <iostream>
  2 #include <stdlib.h>
  3 #include <stdio.h>
  4
  5 using namespace std;
  6
  7 struct DataType {
  8     int key;
  9 };
 10
 11 typedef struct node {
 12     DataType data;
 13     struct node *leftChild;
 14     struct node *rightChild;
 15     node() {
 16         leftChild = NULL;
 17         rightChild = NULL;
 18     }
 19 } BiTreeNode;
 20
 21 BiTreeNode *search(BiTreeNode *root,DataType item) {
 22     BiTreeNode *p = NULL;
 23     if(root!=NULL) {
 24         p = root;
 25         while(p!=NULL) {
 26             if(p->data.key == item.key)
 27                 return p;
 28             if(item.key > p->data.key)
 29                 p = p->rightChild;
 30             else
 31                 p = p->leftChild;
 32         }
 33     }
 34     return NULL;
 35 }
 36
 37 bool insert(BiTreeNode *&root,DataType *item) {
 38     BiTreeNode *current = NULL,*parent = NULL,*p = NULL;
 39     current = root;
 40     while(current != NULL) {
 41         if(current->data.key == item->key)return false;
 42         parent = current;
 43         if(current->data.key < item->key)
 44             current = current->rightChild;
 45         else
 46             current = current->leftChild;
 47     }
 48     p = new BiTreeNode;
 49     p->data = *item;
 50
 51     //the new node is root node
 52     if(parent == NULL)
 53         root = p;
 54     //as leftChild
 55     else if(item->key < parent->data.key)
 56         parent->leftChild = p;
 57     //as rightChild
 58     else
 59         parent->rightChild = p;
 60     return true;
 61 }
 62
 63 void inTraverse(BiTreeNode *root) {
 64     if(root == NULL) {
 65         cout<<"inTraverse error:root = NULL"<<endl;
 66         return;
 67     }
 68     if(root->leftChild != NULL)
 69         inTraverse(root->leftChild);
 70     cout<<root->data.key<<" ";
 71     if(root->rightChild != NULL)
 72         inTraverse(root->rightChild);
 73 }
 74
 75 bool deleteNode(BiTreeNode *&root,DataType item) {
 76     BiTreeNode *current = root,*parent = NULL,*p = NULL,*kmin = NULL;
 77     bool flag = false;
 78     //寻找要删除的节点和其父节点
 79     while(current != NULL) {
 80         if(current->data.key == item.key) {
 81             flag = true;
 82             break;
 83         }
 84         parent = current;
 85         if(current->data.key < item.key)
 86             current = current->rightChild;
 87         else current = current->leftChild;
 88     }
 89     //未找到要删除的元素
 90     if(flag == false) {
 91         cout<<"delete error:item not found"<<endl;
 92         return false;
 93     }
 94     if(current->leftChild == NULL) {
 95         p = current;
 96         if(parent != NULL) {
 97             if(parent->leftChild != NULL && parent->leftChild->data.key == current->data.key)
 98                 parent->leftChild = current->rightChild;
 99             else parent->rightChild = current->rightChild;
100         } else {
101             root = current->rightChild;
102         }
103         delete p;
104     } else if(current->rightChild == NULL) {
105         p = current;
106         if(parent != NULL) {
107             if(parent->leftChild != NULL && parent->leftChild->data.key == current->data.key)
108                 parent->leftChild = current->leftChild;
109             else parent->rightChild = current->leftChild;
110         } else {
111             root = current->leftChild;
112         }
113         delete p;
114     } else {
115         kmin = current->rightChild;
116         while(kmin->leftChild != NULL) {
117             kmin = kmin->leftChild;
118         }
119         if(parent != NULL)
120             current->data = kmin->data;
121         else
122             root->data = kmin->data;
123         deleteNode(current->rightChild,kmin->data);
124     }
125     return true;
126 }
127
128 void createFile(int n) {
129     FILE *fp = fopen("file.txt","w");
130     while(n--) {
131         fprintf(fp,"%d ",rand()%10000);
132     }
133     fclose(fp);
134 }
135
136 int *readFile(int n) {
137     int *num = new int[n],i=0;
138     FILE *fp = fopen("file.txt","r");
139     while(!feof(fp)) {
140         fscanf(fp,"%d ",&num[i++]);
141     }
142     return num;
143 }
144
145 int main() {
146     BiTreeNode *root = NULL;
147     int n = 100,*num = NULL,i;
148     createFile(n);
149     num = readFile(n);
150     for(i=0; i<n; i++) {
151         DataType x;
152         x.key = num[i];
153         insert(root,&x);
154     }
155     for(i=0; i<n; i++) {
156         cout<<endl<<"del:"<<num[i]<<endl;
157         DataType m;
158         m.key = num[i];
159         deleteNode(root,m);
160         inTraverse(root);
161     }
162     //BiTreeNode *root = NULL;
163     return 0;
164 }

时间: 2024-09-30 16:20:41

二叉排序树的插入与删除的相关文章

二叉排序树的插入和删除

二叉排序树:又称"二叉查找树","二叉搜索树". 二叉排序树是一颗空树,或者具有以下性质: 1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值. 2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值. 3.它的左.右子树也分别为二叉排序树. //二叉排序树结构 typedef int ElemType; typedef struct BstNode { ElemType data; struct BstNode* parent; //双亲

二叉排序树(插入、删除、更新、遍历、搜索、求树高。。。)

#include <iostream> using namespace std; // 有序二叉树(二叉搜索树) class Tree { public: // 构造过程中初始化为空树 Tree (void) : m_root (NULL), m_size (0) {} // 析构过程中销毁剩余节点 ~Tree (void) { clear (); } // 插入数据 void insert (int data) { insert (new Node (data), m_root); ++m_

重温数据结构:二叉排序树的查找、插入、删除

读完本文你将了解到: 什么是二叉排序树 Binary Sort Tree BST 二叉排序树的关键操作 查找 插入 删除 运行代码测试 一道面试题 总结 Thanks 我们知道,二分查找可以缩短查找的时间,但是有个要求就是 查找的数据必须是有序的.每次查找.操作时都要维护一个有序的数据集,于是有了二叉排序树这个概念. 上篇文章 我们介绍了 二叉树 的概念,二叉树有左右子树之分,想必在区分左右子树时有一定的规则. 现在我们来介绍二叉树的一种特殊形式 - 二叉排序树,了解它的区分策略及常用操作. 什

二叉查找树(二叉排序树)创建,插入,删除操作。

二叉排序树 二叉排序树是一个基础的树的数据结构.应用非常多. 它的特性就是,左孩子小于parent,右孩子大于parent. 寻找节点 寻找节点就是直接根据数值的大小,从root节点开始遍历,大于当前遍历节点就向它的右子树查找,相反则查找它的左子树.然后返回. 查找最大最小节点 直接根据root节点,遍历到最右就是最大节点,遍历到最左,就是最小节点. 插入节点 插入节点我这里插入的节点都会成为叶子节点.根据大小的关系向下遍历,遍历到最后的节点,然后插入就可以了. 删除节点 这里删除节点是相对麻烦

二叉排序树(BST):创建、查找、插入与删除

删除结点的相关操作(左右子树均为非空的删除结点的方法): 算法分析: 下面以实例来说明二叉排序树的创建.查找.插入和删除等相关操作: 如输入关键字序列(45,24,37,12,54,93),然后对其进行相应的操作,程序如下: #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; typedef struct BiTNode { int value; struct B

Java实现二叉排序树的插入、查找、删除

import java.util.Random; /** * 二叉排序树(又称二叉查找树) * (1)可以是一颗空树 * (2)若左子树不空,则左子树上所有的结点的值均小于她的根节点的值 * (3)若右子树不空,则右子树上所有的结点的值均大于她的根节点的值 * (4)左.右子树也分别为二叉排序树 * * * 性能分析: * 查找性能: * 含有n个结点的二叉排序树的平均查找长度和树的形态有关, * (最坏情况)当先后插入的关键字有序时,构成的二叉排序树蜕变为单枝树.查找性能为O(n) * (最好

二叉排序树的查找、插入和删除

1.      二叉排序树 二叉排序树(Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有结点值相同的结点. 二叉排序树又称二叉查找树(Binary Search Tree),亦称二叉搜索树.通常采用二叉链表作为二叉排序树的存储结构.中序遍历二叉排序树可以得到关键字有序的序列,即一个无序序

二叉平衡树的插入和删除操作

1.      二叉平衡树 二叉排序树的时间复杂度和树的深度n有关.当先后插入的结点按关键字有序时,二叉排序树退化为单枝树,平均查找长度为(n+1)/2,查找效率比较低.提高查找效率,关键在于最大限度地降低树的深度n.因此需要在构成二叉排序树的过程中进行“平衡化”处理,使之成为二叉平衡树. 二叉平衡树,又称AVL树.它或者是一棵空树,或者是具有下列性质的树: 1)      具备二叉排序树的所有性质: 2)      左子树和右子树深度差的绝对值不超过1: 3)      左子树和右子树都是二叉

BST二叉排序树的查找和删除的完整C代码

二叉排序树的查找算法 假定二叉排序树的根节点指针为root,给定的关键字值为key,则查找算法可描述为: 置初值:p = root : 如果 key = p -> data ,则查找成功,算法结束: 否则,如果key < p->data ,而且 p 的左子树非空,则将 p 的左子树根送 p ,转步骤 2 :否则,查找失败,算法结束: 否则,如果 key > p->data ,而且 p 的右子树非空,则将 p 的右子树根送 p ,转步骤 2 :否则,查找失败,算法结束. //B