数据结构-树
来源:互联网 发布:立白皂液怎么样 知乎 编辑:程序博客网 时间:2024/06/05 11:04
树: 是 n(n≥0) 个结点的有限集合。如果该集合为空,称为空树。在任意一棵非空树中:
1)有且仅有一个特定的称为根结点 ( root ) 的结点;
2) 其他结点可分为若干个互不相交的子集(递归定义),而且每一个子集本身又是一棵树,称为根的子树。
基本概念:
结点:树的顶点;
结点的度:结点分支的个数,即子树的数目 如:A的度-3;B的度-2;K的度-0;
树的度:树中所有结点的度的最大值 如:树的度为3;
叶子结点:度为零的结点,也称终端结点 如例:K,L,F,G,M,I,J为终端结点
分支结点:度大于0的结点 如例:A,B,C,D,E
根:非终端结点
深度:结点深度:某一层结点的数目
树的深度:树有几层
森林:多棵树放在一起
二叉树
定义:所有结点的度都小于等于2
二叉树的遍历
前序遍历:根在前面访问 左根右
中序遍历:左结点 根 右结点
后序遍历:左结点 右结点 根
树的用途
搜索-人机对战、压缩软件-哈夫曼树
二叉树的表达
数组表示
父亲结点下标*2+1 该结点左
父亲结点下标*2+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)
Tree.h的代码如下:
#ifndef TREE_H#define TREE_Hclass Tree{public: Tree(int size,int *pRoot); //创建树 ~Tree(); //销毁树 int *SearchNode(int nodeIndex); //根据索引寻找结点 bool AddNode(int nodeIndex,int direction,int *pNode); //添加结点 bool DeleteNode(int nodeIndex,int *pNode); //删除结点 void TreeTraverse(); //遍历结点private: int *m_pTree; int m_iSize;};#endif
Tree.c的代码如下:
#include "Tree.h"#include <iostream>using namespace std;Tree::Tree(int size,int *pRoot){ m_pTree = new int[size]; m_iSize = size; for(int i=0;i<size;++i) { m_pTree[i]=0; } m_pTree[0]=*pRoot;}Tree::~Tree(){ delete[] m_pTree;}int* Tree::SearchNode(int nodeIndex){ if(nodeIndex < 0 || nodeIndex >= m_iSize) { return NULL; } if(m_pTree[nodeIndex]==0) { return NULL; } return &m_pTree[nodeIndex];}bool Tree::AddNode(int nodeIndex,int direction,int *pNode){ if(nodeIndex < 0 || nodeIndex >= m_iSize) { return NULL; } if(m_pTree[nodeIndex]==0) { return NULL; } if(direction==0) { if(nodeIndex * 2 +1 >= m_iSize) { return NULL; } if(m_pTree[nodeIndex * 2 +1]) { return NULL; } m_pTree[nodeIndex * 2 +1] = *pNode; } if(direction==1) { if(nodeIndex * 2 +2 >= m_iSize) { return NULL; } if(m_pTree[nodeIndex * 2 +2]) { return NULL; } m_pTree[nodeIndex * 2 +2] = *pNode; } return true;}bool Tree::DeleteNode(int nodeIndex,int *pNode){ if(nodeIndex < 0 || nodeIndex >= m_iSize) { return false; } if(m_pTree[nodeIndex]==0) { return false; } *pNode = m_pTree[nodeIndex]; m_pTree[nodeIndex] = 0; return true;}void Tree::TreeTraverse(){ for(int i=0;i<m_iSize;++i) { cout << m_pTree[i] << " "; }}
main.cpp的程序如下:
#include<iostream>#include"Tree.h"using namespace std;int main(){ int root = 3; Tree *p = new Tree(10,&root); int node1=5; int node2=8; p->AddNode(0,0,&node1); p->AddNode(0,1,&node2); int node3=2; int node4=6; p->AddNode(1,0,&node3); p->AddNode(1,1,&node4); int node5=9; int node6=7; p->AddNode(2,0,&node5); p->AddNode(2,1,&node6); int node = 0; p->DeleteNode(5,&node); cout << endl << "node="<< node << endl; p->TreeTraverse(); int *p1 = p->SearchNode(2); cout << *p1 << endl; delete p; while(1); return 0;}
链表表示
要素:索引、数据、左孩子指针、右孩子指针、父结点指针
结点的数据成员如下,Node.h:
#ifndef NODE_H#define NODE_Hclass Node{public: Node(); Node *SearchNode(int nodeIndex); //五个数据成员 int index; //结点的索引 int data; //结点的数据 可以是复杂的,也可以是内 Node *pLChild; //做孩子指针 ,都是Node* Node *pRChild; //右孩子指针 Node *pParent; //父亲结点指针};#endif
Node.c文件内容如下:
#include "Node.h"#include <iostream>using namespace std;Node::Node(){ index = 0; data = 0; pLChild = NULL; pRChild = NULL; pParent = NULL;}Node *Node::SearchNode(int nodeIndex){ //判断该结点是否为要搜索的结点 if(this->index = nodeIndex) { return this; } //判断左边的结点是否为要搜索的结点 if(this->pLChild != NULL) { if(this->pLChild->index == nodeIndex) { return this->pLChild; } } //判断右边的结点是否为要搜索的结点 if(this->pRChild != NULL) { if(this->pRChild->index == nodeIndex) { return this->pRChild; } } return NULL;}
树的类如下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 TreeTraverse(); //遍历结点 void PreorderTraverse(); //前序遍历 根左右 void InorderTraverse(); //中序遍历 左根右 void PostorderTraverse(); //后序遍历 左右根 //结点要素:索引 数据 做孩子指针 右孩子指针(通过头结点找子结点)private: Node *m_pRoot;};#endif
创建树的函数为Tree();
具体实现方法为:
Tree::Tree(){ m_pRoot = new Node(); //创建一个根结点}
销毁树不能只销毁一个m_pRoot指针,先看看如何实现结点的寻找,即Node *SearchNode(int nodeIndex)函数,实现如下,这里不是很理解,继续向下看:
Node* Tree::SearchNode(int nodeIndex){ return m_pRoot->SearchNode(nodeIndex);//调用Node的成员函数来寻找结点}
然后是添加结点函数:bool AddNode(int nodeIndex,int direction,Node *pNode);
bool Tree::AddNode(int nodeIndex,int direction,Node *pNode){ Node *temp = this->SearchNode(nodeIndex); if(temp == NULL) { return false; } Node *node = new Node(); //判断申请的内存是否失败 if(node == NULL) return false; node->index = pNode->index; node->data = pNode->data; if(direction == 0) { temp->pLChild = node; } if(direction == 1) { temp->pRChild = node; } return true;}
对于删除结点的函数设计比较困难,函数为bool DeleteNode(int nodeIndex,Node *pNode); //删除结点
需要在Node中添加void DeleteNode()函数:
void Node::DeleteNode(){ //删除自己的左右孩子结点,为迭代的过程 if(this->pLChild != NULL) { this->pLChild->DeleteNode(); } if(this->pRChild != NULL) { this->pRChild->DeleteNode(); } if(this->pParent != NULL) { //这里好像有错误 if(this->pParent->pLChild != NULL) { this->pParent->pLChild = NULL; } if(this->pParent->pRChild != NULL) { this->pParent->pRChild = NULL; } } delete this;}
课程要求
完成树的基本操作:
1.树的创建与销毁;
2.树中结点的搜索;
3.树中结点的添加与删除;
4.树中结点的遍历
- 数据结构--树
- 树--数据结构
- 数据结构-树
- 【数据结构】树
- 数据结构--树
- 数据结构---树
- 数据结构---->树
- 数据结构 树
- 数据结构树
- 数据结构 树
- 数据结构----树
- 数据结构--树
- 数据结构 - 树
- 数据结构:树
- 数据结构 - 树
- 数据结构-树
- 数据结构---树
- 数据结构:树
- python科学计算--核心工具包一瞥(二)(win10 64位,numpy,scipy,pandas,seaborn,wordcloud安装)
- matlab之求向量中出现最多的元素和频率
- Java基本语法---枚举
- 剑指offer面试题[9-2]-变态跳台阶
- 入门经典_Chap05_习题题解
- 数据结构-树
- 算法题练习系列之(三):成绩排序
- HTML==网页编程基础知识
- Latex中导入参考文献问题
- fwrite函数的简介
- MFC中SendMessage的用法与相应函数的添加
- python读取xml
- Java集合判断空和非空
- c++中setw(n)的用法