zoukankan      html  css  js  c++  java
  • 数据结构—二叉树

    1.   二叉树

    1.1 概念

         二叉树是n个有限元素(结点)的集合,由根结点及两个互不相交的左、右子二叉树组成,且左节点中的数据始终小于右节点。

    1.2 形态

         二叉树是递归形成的,它的形态可以概括为五种基本形态:

    (1)空二叉树;

    (2)只有一个根节点的二叉树;

    (3)只有左结点的二叉树;

    (4)只有右结点的二叉树;

    (5)完全二叉树。

    1.3 性质

    性质1:二叉树的第i层上至多有(i≥1)个节点。

    性质2:深度为h的二叉树中至多含有-1个节点。

    性质3:若在任意一棵二叉树中,有n个叶子节点,有n2个度为2的节点,则必有n0=n2+1 。

    1.4 二叉树的构建

    1.4.1 结点

         叉树中每个结点需要包含数据域、左子结点指针域、右子结点指针域。

     

          class  Node

    {

       private:

           int    data;

           Node*  leftNode;

           Node*  rightNode;

       public:

           Node(int data)

         {

             this->data=data;

            this->leftNode=NULL;

            this->rightNode=NULL;

        }

    }

    1.4.2 二叉树类

         实际上结点类就是二叉树,而接下来要编写的二叉树类是为了方便使用二叉树设计的,可以理解为二叉树使用类。

         二叉树类的基本成员:根节点。//root

         基本方法:插入数据。//按左存小右存大的原则

    class  BinaryTree

    {

       private:

                 Node* root;

        public:

          //构造

              BinaryTree()

             {

             root=NULL;

              }

    //插入数据

    void insert(int data)

    {

             //step1:建立新的结点

            Node* newNode=new Node(data);

             //step2:判断根节点是否为空

           if(root==NULL)

              {

                   root=newNode;

                  return;

              }

                   else

             {

                 //current用于指向当前结点,parent用于指向当前结点的父节点

               Node* current=root;

               Node* parent;

               while(true)

           {

             parent=current;

            if(date<current->data)

            {

                   //current指向左孩子结点

                  current=current->leftNode;

                  if(current!=NULL)

                    {

                     parent->left=newNode;

                   //找到叶子结点后,终止循环

                          return;

                   }

           }

                else

                {

                       current=current->rightNode;

                        if(current!=NULL)

                       {

                         parent->right=newNode;

                              return;

                          }

                      }

             }

          }

       }

    }

    1.5 遍历

    1.5.1 递归遍历

         二叉树的遍历方式有很多,根据双亲结点、左子结点、右子节点的访问顺序可以归结为:

    (1)前序遍历  

    void  serch_tree(Node* root)

    {

       if(!root) 

    return;

    cout<<root->data<<endl;//先读取双亲结点的数据

    serch_tree(root->left);//打印左子树

    serch_tree(root->right);//打印右子树

    }

    (2)中序遍历

    void  serch_tree(Node* root)

    {

       if(!root) 

    return;

    serch_tree(root->left);

    cout<<root->data<<endl;//中读取双亲结点的数据

    serch_tree(root->right);

    }

     

    (3)后序遍历

    void  serch_tree(Node* root)

    {

       if(!root) 

    return;

    serch_tree(root->left);

    serch_tree(root->right);

    cout<<root->data<<endl;//后读取双亲结点的数据

    }

    递归遍历二叉树的优点是编码简单,但是当树的深度较大时,由于不断的数据压栈,造成空间开销大的问题。

    1.5.2 非递归遍历

    非递归遍历需要用到栈,首先将树中的左节点全部压栈,然后进入右子树,继续循环,直至栈及节点均为NULL。

    BTNode* p = root;

    stack<BTNode*> s;

    while (!s.empty() || p)

    {

        //代码段(i)一直遍历到左子树最下边,边遍历边保存根节点到栈中

        while (p)

        {

            s.push(p);

            p = p->lchild;

        }

        //代码段(ii)p为空时,说明已经到达左子树最下边,这时需要出栈了

        if (!s.empty())

        {

            p = s.top();

            s.pop();

            cout << p->data;

            //进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)

            p = p->rchild;

        }

    }

          

  • 相关阅读:
    c# 文件上传
    iOSswift基础篇1
    copyWithZone 的使用方法
    客户端登陆接收大量数据导致数据丢失问题解决方法
    设计模式观察者模式(KVO)
    SQLite 之 C#版 System.Data.SQLite 使用
    设计模式MVC(C++版)
    JS 创建自定义对象的方法
    手机号、邮箱、身份证号 格式 验证
    在.cs文件中添加客户端方法
  • 原文地址:https://www.cnblogs.com/lyjbk/p/13688019.html
Copyright © 2011-2022 走看看