数据结构 - 树与二叉树 (C++)

一. 树的基本概念
(Tree)是n(n>=0)个结点的有限集。它有唯一的(1结点)和若干颗互不相交的子树(如图上子树5、11、12等)组成。
数据结构 - 树与二叉树 (C++)_第1张图片
 接下来以上面树为例子介绍树的基本术语。

  • 结点:1、2、3等都是结点,每个结点包含数据元素还有指向子树的分支。
  • 结点的度:结点拥有的子树的数。(如:5结点的度为2)
  • 树的度:树种各结点度的最大值。(如:上述树的度为3,即为3结点的度)
  • 叶子结点:度为0的结点,也叫终端结点。(如:2、13、14等)
  • 非终端结点:度不为0的结点,也叫分支结点。(如:3、7、9等)
  • 孩子:结点子树的根。(如:1的孩子为2、3、4、5)
  • 双亲:与孩子结点相对应。(如:2、3、4、5结点的双亲都是1结点)
  • 兄弟:同一个双亲的孩子之间互为兄弟。(如:2、3、4、5互为兄弟)
  • 祖先:从根到某一结点路径上的全部结点。(如:对路径1、5、11,1和5都是11的祖先)
  • 子孙:以某结点为根的子树中的所有结点,都是该结点的子孙。(如:4的子孙是9、10、16)
  • 层次:从根开始,每层子树算作一层。
  • 树的高度(或深度):树中结点的最大层次。(如:上述树的高度为4)
  • 有序树:树中结点的子树从左到右是有次序的,不能交换。
  • 无序树:树中结点的子树没有顺序,可以相互交换。
  • 森林:若干棵互不相交的树的集合。

二. 树的存储结构

  1. 顺序存储结构

 假设以一组连续空间存储数的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。
示意图
数据结构 - 树与二叉树 (C++)_第2张图片数据结构 - 树与二叉树 (C++)_第3张图片
代码实现

/* 树的双亲表法结点结构定义*/
#define MAX_TREE_SIZE 100
typedef int  ElemeType;

typedef struct PTNode{ // 结点结构
    ElemeType data; //结点数据
    int parent;    // 双亲位置
}PTNode;

typedef struct { // 树结构
    PTNode nodes[MAX_TREE_SIZE];   // 结点数组
    int r; // 根的位置
    int n; // 结点数
}PTree;

特点

  • 由于根结点是没有双亲的,约定根结点的位置位置域为-1.
  • 根据结点的parent指针很容易找到它的双亲结点。所用时间复杂度为O(1),直到parent为-1时,表示找到了树结点的根。
  • 缺点:如果要找到孩子结点,需要遍历整个结构才行。
  1. 链式存储结构
//二叉树链式存储结构定义 
typedef struct BTNode{
	ElemType  data;		//数据域 
	struct BTNode *lchild;	//左孩子 
	struct BTNode *rchild;	//右孩子 
}BTNode; 

三. 二叉树的遍历

//二叉树先序遍历 - 递归 
void preorder(BTNode *p){
	if(p != NULL){
		visit(p);	//访问结点 
		preorder(p->lchild);//先序遍历左孩子结点 
		preorder(p->rchild);//先序遍历右孩子结点 
	}
}

//二叉树中序遍历 - 递归 
void inorder(BTNode *p){
	if(p != NULL){
		inorder(p->lchild);//中序遍历左孩子结点 
		visit(p);	//访问结点 
		inorder(p->rchild);//中序遍历右孩子结点 
	}
}

//二叉树中后序遍历 - 递归 
void postorder(BTNode *p){
	if(p != NULL){
		postorder(p->lchild);//后序遍历左孩子结点 
		postorder(p->rchild);//后序遍历右孩子结点 
		visit(p);	//访问结点 
	}
}

四. 构造二叉树
根据 先序遍历 + 中序遍历 或 中序遍历 + 后序遍历 可以构造一个二叉树:

//根据前序序列,中序序列构造二叉树 
//参数:前序序列 中序序列 序列长度 
BTNode *createBT(ElemType *pre, ElemType *in, int n){
	BTNode *root = NULL;	//定义二叉树根节点     
	ElemType *p;			
	int k;
	
	if(n <= 0)	//数组长度错误 
		return NULL;
	if(pre == NULL || in == NULL)//序列空 
		return NULL;
		
	root = (BTNode*)malloc(sizeof(BTNode));	//构造根结点 
	root->data = *pre;
	
	for(p = in;p < in + n;++p)	//计算左子树长度 
		if(*p == *pre)
			break;
	k = p - in;
	
	root->lchild = createBT(pre + 1,in,k);	//递归构造左右子树 
	root->rchild = createBT(pre + 1 + k, p + 1, n - k - 1);	
	
	return root;
}

五.求结点数

//计算二叉树的结点数 
int nodeNum(BTNode *p){
	if(p != NULL)
		return nodeNum(p->lchild) + nodeNum(p->rchild) + 1;
	else
		return 0;
} 

//计算二叉树的叶子结点数 
int lastNodeNum(BTNode *p){
	if(p != NULL){
		if(p->lchild == NULL && p->rchild == NULL)
			return 1;
		else 
			return lastNodeNum(p->lchild) + lastNodeNum(p->rchild);
	}
	else
		return  0;
} 

演示代码

#include 
#include 

using namespace std; 

typedef char ElemType  ; 

//二叉树链式存储结构定义 
typedef struct BTNode{
	ElemType  data;		//数据域 
	struct BTNode *lchild;	//左孩子 
	struct BTNode *rchild;	//右孩子 
}BTNode; 


//根据前序序列,中序序列构造二叉树 
//参数:前序序列 中序序列 序列长度 
BTNode *createBT(ElemType *pre, ElemType *in, int n){
	BTNode *root = NULL;	//定义二叉树根节点     
	ElemType *p;			
	int k;
	
	if(n <= 0)	//数组长度错误 
		return NULL;
	if(pre == NULL || in == NULL)//序列空 
		return NULL;
		
	root = (BTNode*)malloc(sizeof(BTNode));	//构造根结点 
	root->data = *pre;
	
	for(p = in;p < in + n;++p)	//计算左子树长度 
		if(*p == *pre)
			break;
	k = p - in;
	
	root->lchild = createBT(pre + 1,in,k);	//递归构造左右子树 
	root->rchild = createBT(pre + 1 + k, p + 1, n - k - 1);	
	
	return root;
}

//访问函数
void visit(BTNode *p){
	//访问结点 
	cout<data; 
} 

//二叉树先序遍历 - 递归 
void preorder(BTNode *p){
	if(p != NULL){
		visit(p);	//访问结点 
		preorder(p->lchild);//先序遍历左孩子结点 
		preorder(p->rchild);//先序遍历右孩子结点 
	}
}

//二叉树中序遍历 - 递归 
void inorder(BTNode *p){
	if(p != NULL){
		inorder(p->lchild);//中序遍历左孩子结点 
		visit(p);	//访问结点 
		inorder(p->rchild);//中序遍历右孩子结点 
	}
}

//二叉树中后序遍历 - 递归 
void postorder(BTNode *p){
	if(p != NULL){
		postorder(p->lchild);//后序遍历左孩子结点 
		postorder(p->rchild);//后序遍历右孩子结点 
		visit(p);	//访问结点 
	}
}



int main(int argc, char** argv) {
	
	ElemType pre[] = "ABCDEF";
	ElemType in[] = "CBAEDF";
	BTNode *a = (BTNode *)malloc(sizeof(BTNode)); 
	a = createBT(pre,in,6);
	inorder(a);
	
	
	return 0;
}

在这里插入图片描述

你可能感兴趣的:(【计算机理论基础】)