设为首页 加入收藏

TOP

慕课网学习笔记之数据结构树(C++)(一)
2016-10-08 17:31:05 】 浏览:569
Tags:慕课网 学习 笔记 数据结构

什么是树?——数是节点有限集合

  

这里写图片描述

孩子:在上图中BCD都是A的孩子,EF是B的孩子,GH是D的孩子
双亲:A是BCD的双亲,B是EF的双亲,D是GH的双亲,注意这里双亲是指一个节点而非两个。
:节点的度等于节点的孩子数。A的度为3,B的度为2,D的度为2,CEFGH度都是0。
叶子:终端节点就是叶子。CEFGH
根:非终端节点。ABD
有序树:举例来说:如果EF不可以换顺序,则为有序树。
无序树:相对于有序树。
祖先:当前节点,一直向上所路过的所有节点直到根都是该节点祖先。
子孙:当前节点,向下的所有节点,都是该节点的子孙。
深度:节点深度为该节点所在层数;树的深度为该树的最大深度。
森林:多颗独立的树在一起就成了森林。
二叉树:所有节点的度都小于等于2。
二叉树的遍历:前序遍历,中序遍历,后序遍历。

  

这里写图片描述

记忆口诀:根左右、左根右、左右根。
树的应用:压缩软件、人机对战。

二叉树的实现:

1.数组实现
2.链表实现
第一种数组实现的方式较为简单

/*****************************************/
/* 二叉树(数组表示) 

    关于数据与树之间的算法转换 

    int tree[n] 3 5 8 2 6 9 7             

                    3(0)

            5(1)              8(2)

      2(3)      6(4)     9(5)         7(6)


    结论:
        父亲节点下标*2+1 为该节点左孩子的下标 
        父亲节点下标*2+2 为该节点右孩子的下标   
*/ 

当节点不存在时有些不好表达,如果用0来代表无此节点,当存放的数据就是0时便会影响树的操作。
第二种链表实现

/********************************************
    节点要素: 索引   数据  左孩子指针   右孩子指针  父节点指针 
        tree[n] 3 5 8 2 6 9 7   


                    3(0)

            5(1)              8(2)

      2(3)      6(4)     9(5)         7(6)

      下标来表示遍历顺序: 
      前序:0 1 3 4 2 5 6
      中序:3 1 4 0 5 2 6
      后序:3 4 1 5 6 2 0  
*/

tree.h文件:

#ifndef TREE_H
#define TREE_H
#include"Node.h"

class Tree
{
public:
    Tree();                                                 //创建树   
    ~Tree();                                               //销毁树 
    Node *SearchNode(int nodeIndex);                            //根据索引寻找节点 
    bool AddNode(int nodeIndex,int direction,Node *pNode);  //添加节点 
    bool DeleteNode(int nodeIndex,Node *pNode);             //删除节点 
    void PreorderTraverse();                                //前序遍历
    void InorderTraverse();                                 //中序遍历 
    void PostorderTraverse();                               //后序遍历                          
private:
    Node *m_pRoot;  
};
#endif

Node.h文件:

#ifndef NODE_H
#define NODE_H

class Node
{
public :
    Node();
    Node *SearchNode(int nodeIndex); //寻找索引号所在节点,若存在返回该节点,否则返回NULL 
    void DeleteNode();               //删除节点 
    void PreorderTraverse();         //前序遍历 
    void InorderTraverse();          //中序遍历             
    void PostorderTraverse();        //后序遍历 
    int index;                       //索引号 
    int data;                        //数据 
    Node *pLChild;                   //左孩子指针 
    Node *pRChild;                   //右孩子指针 
    Node *pParent;                   //双亲指针  

};

#endif

Node.cpp文件:

#include"Node.h"
#include"stdlib.h"
#include
  
   
using namespace std; 
Node::Node()                                        //节点构造函数 
{                                                   //初始创建根节点 
    index=0;                                        // 索引初始化为0 
    data=3;                                         // 数据初始为3 
    pLChild=NULL;
    pRChild=NULL;
    pParent=NULL;
}
Node *Node::SearchNode(int nodeIndex)               
{
    if(this->index == nodeIndex)                    //找到返回 
        return this;

    Node *temp;                                     //暂存使用 
    if(this->pLChild != NULL)                       //左孩子存在 
    {   
        if(this->pLChild->index == nodeIndex) 
            return  this->pLChild;  
        else                                        //如果没找到 
        {
        temp=this->pLChild->SearchNode(nodeIndex);  //递归调用 
        if(temp != NULL)
            return temp;                            //找到则返回,否则继续向下 
        }       
    }   

    if(this->pRChild != NULL)                       //右孩子存在 
    {   
        if(this->pRChild->index == nodeIndex)
            return  this->pRChild;                  
        else                                        //未找到 
        {
        temp=this->pRChild->SearchNode(nodeIndex);  //递归调用 
            return temp;                            //直接return 出去 不需要继续找 
        }   
    }       
}

void Node::DeleteNode()                             
{
    if(this->pLChild !=NULL)                        //左孩子存在 
        this->pLChild->DeleteNode();                //递归调用 
    if(this->pRChild !=NULL)
        this->pRChild->DeleteNode();                //递归调用 
    if(this->pParent !=NULL)                        //判断自己是双亲的左孩子or右孩子 
    {
        if(this->pParent->pLChild == this)
            this->pParent->pLChild=NULL;            
        if(this->pParent->pRChild == this)
            this->pParent->pRChild=NULL;            //判断出来使双亲该孩子指为NULL 
    }       
    delete this;                                    //自己的子孙杀完,双亲对自己指向空,可以自杀了 
}
void Node::PreorderTraverse()                       //前序遍历,递归调用 
{
    cout<
   
    index<<" "<
    
     data << endl;//打印根 if(this->pLChild !=NULL) //左 this->pLChild->PreorderTraverse(); //递归 if(this->pRChild != NULL) //右 this->pRChild->PreorderTraverse(); //递归 } /**中序遍历和后序遍历同理,只需要更改程序执行顺序**/ void Node::InorderTraverse() { if(this->pLChild !=NULL) this->pLChild->Inorder
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇c/c++经典算法面试题 下一篇C/C++文件IO

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目