zoukankan      html  css  js  c++  java
  • 一步一步写数据结构(BST二叉排序树)

    二叉排序树的重要性不用多说,下面用c++实现二叉排序树的建立,插入,查找,修改,和删除。难点在于删除,其他几个相对比较简单。

    以下是代码:

      1 #include<iostream>
      2 using namespace std;
      3 //定义节点
      4 typedef struct BiNode
      5 {
      6     int data;
      7     struct BiNode *lchild,*rchild;
      8 }BiNode,*BiTree;
      9 
     10 //插入函数
     11 void insertBST(BiTree &T,int key)
     12 {
     13     if(NULL==T)
     14     {
     15         T=new BiNode;
     16         T->data=key;
     17         T->lchild=T->rchild=NULL;
     18     }
     19     else if(T->data==key)
     20         cout<<"不能重复!";
     21     else if(T->data>key)
     22         insertBST(T->lchild,key);
     23     else
     24         insertBST(T->rchild,key);
     25 
     26 }
     27 //通过插入函数实现创建二叉排序树
     28 void createBST(BiTree &T)
     29 {
     30     int n;
     31     cout<<"请输入要插入的节点数: ";
     32     cin>>n;
     33     int a[n];
     34     cout<<"请输入要插入的数据:中间用空格分开"<<endl;
     35     for(int i=0;i<n;i++)
     36     {
     37         cin>>a[i];
     38         insertBST(T,a[i]);
     39     }
     40 
     41     cout<<"创建二叉排序树完成!"<<endl;
     42 
     43 }
     44 
     45 //前序遍历并打印
     46 void preOrderTraverse(BiTree T)
     47 {
     48     if(T)
     49     {
     50         cout <<T->data<< " ";
     51         preOrderTraverse(T->lchild);
     52         preOrderTraverse(T->rchild);
     53     }
     54 }
     55 //中序遍历并打印
     56 void midOrderTraverse(BiTree T)
     57 {
     58 
     59     if(T)
     60     {
     61         midOrderTraverse(T->lchild);
     62         cout <<T->data<< " ";
     63         midOrderTraverse(T->rchild);
     64     }
     65 }
     66 
     67 //定义全局变量layer,表示层数
     68 int layer=0;
     69 //下面是查找函数,返回是否查找到数据并且可以确定查找元素的层数
     70 bool searchBST(BiTree &T,int key)
     71 {
     72     layer++;
     73     if(T==NULL)
     74     {
     75         return false;
     76     }
     77     else
     78     {
     79         if (key==T->data)
     80         {
     81 
     82             return true;
     83 
     84         }
     85         else if(key<T->data)
     86             searchBST(T->lchild,key);
     87         else
     88             searchBST(T->rchild,key);
     89     }
     90 }
     91 //利用上面查找函数实现查找操作
     92 void findBST(BiTree &T)
     93 {
     94     int k;
     95     cout<<"请输入要查找的元素值: ";
     96     cin>>k;
     97     if(searchBST(T,k))
     98     {
     99         cout<<"查找成功,该元素位于二叉树中!"<<endl;
    100         cout<<"层数为:"<<layer<<endl;
    101     }
    102 
    103     else
    104         cout<<"没有查找到该元素!"<<endl;
    105 }
         //定义删除节点的函数
    106 void deletenode(BiTree &p) 107 { 108 BiTree q,s; //函数形参P指向要删除的节点,即它的双亲节点的rchild 109 //根据要删除的节点的孩子情况分三种讨论 110 //没有左孩子 111 if(!p->lchild) 112 { 113 q=p; 114 p=p->rchild; 115 delete q; 116 } 117 //没有右孩子 118 if(!p->rchild) 119 { 120 q=p; 121 p=p->lchild; 122 delete q; 123 124 } 125 //两个孩子都有 126 else 127 { 128 q=p; //q指向上一个节点,s指向下一个节点,即指向q的右孩子,初始时q=p,最终s指向跟p节点换值的那个节点。 129 s=q->lchild; 130 131 while(s->rchild)    //通过这个循环实现寻找最接近要删除节点(p)值的节点 132 { 133 q=s; 134 s=s->rchild; 135 } 136 p->data=s->data;    //交换值,有个注意事项,s是不存在右孩子的,因为如果存在,则右孩子比他大,更接近p,s需要继续循环,最终s还是没有右孩子。 137 if(q!=p)           138 { 139 q->rchild=s->lchild; 140 } 141 else        //如果q,s 没有移动,即此时q=p,s的初始值就是最接近p点的节点,此时q不存在右节点,需要单独讨论
    142 { 143 q->lchild=s->lchild;       144 } 145 delete s; 146 } 147 148 149 } 150 151 //删除操作 152 bool deleteBST(BiTree &T,int del) 153 { 154 if(!T) 155 return false; 156 else 157 { 158 if(T->data==del) 159 { 160 deletenode(T); 161 return true; 162 } 163 else if(del<T->data) 164 { 165 return deleteBST(T->lchild,del); 166 } 167 else 168 { 169 return deleteBST(T->rchild,del); 170 } 171 } 172 173 } 174

     下面是主函数:

     1 //主函数
     2 int main()
     3 {
     4     BiTree T=NULL;
     5     int d;
     6     createBST(T);
     7     cout<<"前序遍历的结果为:"<<endl;
     8     preOrderTraverse(T);
     9     cout<<endl;
    10     cout<<"中序遍历的结果为:"<<endl;
    11     midOrderTraverse(T);
    12     cout<<endl;
    13     findBST(T);
    14     cout<<"请输入要删除的数据:"<<endl;
    15     cin>>d;
    16     deleteBST(T,d);
    17     cout<<"前序遍历的结果为:"<<endl;
    18     preOrderTraverse(T);
    19 
    20 }

    上面的代码分别实现了查找,建立,插入和删除的操作,删除比较难主要是因为删除节点后下面的所有节点都会受到影响。此时采取的思维是分类讨论节点的孩子节点情况,

    最复杂的情况是存在左右孩子,此时有两种思路,对左边孩子树进行操作或者对右边孩子树进行操作,我给出的代码是左边,二者道理一样。具体方法参考代码,说明很详细。

    下面给出一个存在双孩子节点的图

    画的虽然简陋,但大概意思就这样,(画图的确是理解数据结构的利器啊)最后给出控制台运行结果:

     over~

  • 相关阅读:
    怎样应对突发性的开发需求
    ASP.NET过滤HTML标签只保留换行与空格的方法
    sqlserver 各种判断是否存在(表名、函数、存储过程等)
    Timing advance of GSM(时间提前量)
    对.NET中Hashtable和ArryList的理解
    GPS原始经纬度转百度经纬度
    baidu经纬度坐标与google经纬度坐标都转换
    .NET资料之-根据两点经纬度计算直线距离
    .net处理JSON简明教程
    在asp.net中要不使用其他插件的情况下只能使用定时器来检查, 并执行任务.
  • 原文地址:https://www.cnblogs.com/jymblog/p/5435685.html
Copyright © 2011-2022 走看看