1.在之前的几章我们学习了基本的线性数据结构,数组,链表,队列,栈。当然还有串没有讨论,其实是很重要的,我们下一次着重讨论串的一些操作:匹配中的B-F算法,KMP算法等。这一次我们来学习一种新的数据结构:二叉树。
2.其实早在前边我就表达了一个观点,数据结构就是生活中一些事物的的抽象,数组对应着容易,链表也像一条链子一样。当然这些树形的数据结构是远远不能够满足我们的需要的。在生活中,还有一种很常见的关系,就是子代和父代的一种层次关系。让我们回忆一下高中的一种东西:遗传图解。不知道各位是否还记得。一个亲代下边辐射出若干子代。这是很常见的关系。程序中也有一种数据结构:树状数据结构,用来描述这种关系。
3.基本的定义:首先树状数据结构一定有一个起点,我们叫做根节点。依次向下辐射,每一个节点辐射出的节点叫做该节点的父节点,这些节点叫做子节点。最下边的叫做叶节点。
树的结点(node):包含一个数据元素及若干指向子树的分支;
孩子结点(child node):结点的子树的根称为该结点的孩子;
双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
树的深度:树中最大的结点层
结点的度:结点子树的个数
树的度: 树中最大的结点度。
叶子结点:也叫终端结点,是度为 0 的结点;
分枝结点:度不为0的结点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序;4.现在给出二叉树的构建以及三种遍历输出的代码:
#include<iostream>
#include<iomanip>
using namespace std;
class Bnode {
public:
int data;//节点数据
Bnode*lchild;//左子树指针
Bnode*rchild;//右子树指针
public:
Bnode(int value) {
data = value;
lchild = rchild= NULL;//初始化操作
}
};
class Btree {
private:
Bnode*pNode=0;//根节点
Bnode*InsertNode(Bnode*p, Bnode*newNode);//Insert一个节点,我将Insert函数作为private,防止外部调用该函数来插入节
//点只允许内部调用构建节点
public:
Bnode * create(int n);
//中序遍历输出(其实这种输出是一种顺序输出)
void inorder(Bnode*p);
void inorder();
//前序遍历输出
void preorder();
void preorder(Bnode*p);
//后序遍历输出
void lastOrder();
void laseOrder(Bnode*p);
};
//递归调用函数来实现插入操作
Bnode * Btree::InsertNode(Bnode * p, Bnode * newNode)
{
//首先检查待比较的节点与新节点是否存在
if (newNode == 0 || p == 0)
{
return newNode;
}
//如果新节点的数据比根节点的数据小
if (newNode->data <= p->data)
{
if (p->lchild)//在左子树上一直向下查找
{
InsertNode(p->lchild, newNode);//递归
}
else
{
//插入数据
p->lchild = newNode;
}
}
else
{
//同理输入右子树
if (p->rchild)
{
InsertNode(p->rchild, newNode);
}
else
{
p->rchild = newNode;
}
}
return newNode;
}
Bnode * Btree::create(int n)
{
if (pNode == 0)
{
pNode = new Bnode(n);
pNode->lchild = 0;
pNode->rchild = 0;
return pNode;
}
else
{
//递归调用创建新的节点
Bnode*newNode = new Bnode(n);
InsertNode(pNode, newNode);
}
return pNode;
}
void Btree::inorder()
{
inorder(pNode);
}
void Btree::preorder()
{
preorder(pNode);
}
void Btree::preorder(Bnode * p)
{
if (p != 0)
{
cout << p->data << " ";
preorder(p->lchild);
preorder(p->rchild);
}
}
void Btree::lastOrder()
{
laseOrder(pNode);
}
void Btree::laseOrder(Bnode * p)
{
if (p != 0)
{
this->laseOrder(p->lchild);
laseOrder(p->rchild);
cout << p->data << " ";
}
}
void Btree::inorder(Bnode*p)
{
if (p != 0) {
inorder(p->lchild);
cout << p->data << " ";
inorder(p->rchild);
}
}
int main()
{
Btree*b = new Btree();
srand(time(0));
for (int i = 0; i < 10; i++)
{
int k = rand() % 100;
b->create(k);
}
b->create(88);
b->inorder();
cout << endl;
b->preorder();
cout <<endl;
//b->laseOrder();
return 0;
}