二叉树

特点:每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。二叉树的左右子树不能任意颠倒(有序),如果某结点只有一颗子树,一定要指明它是左子树还是右子树。


二叉树的分类
1 斜树
所有结点都只有左子树的二叉树称为左斜树,所有结点都只有右子树的二叉树称为右斜树;左斜树和右斜树统称为斜树。特点:每一层只有一个结点,斜树的结点个数与其深度相同。
2 满二叉树
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,那么这棵二叉树称为满二叉树。特点:叶子只能出现在最下一层;只有度为0和度为2的结点。
3 完全二叉树
对一颗具有n个结点的二叉树按层序编号,如果编号i的结点与同样深度的满二叉树中编号为i的结点在二叉树中的位置完全相同,则这棵树称为完全二叉树。特点:深度为k的完全二叉树在k-1层是满二叉树;叶子结点只能出现在最下两层,且最下层的叶子结点都集中在左侧连续的位置;如果有度为1的结点,只可能有一个,且该结点只有做左孩子。

二叉树的基本性质
1:在一棵二叉树中,如果叶子结点的个数为n0,度为2的结点个数为n2,则n0=n2+1。
2:二叉树的第i层上最多有2^(i-1)个结点。
3:在一棵深度为k的二叉树中,最多有2^k-1个结点。
4:具有n个结点的完全二叉树的深度为[log2n]+1
(向下取整)。
5:对一颗棵具有n个结的完全二叉树从1开始按层序编号,则对于编号为i的结点,有如下关系成立
①如果i>1,则结点i的双亲编号为i/2向下取整,否则结点i是根结点,无双亲。
②如果2i<=n,则结点i的左孩子的编号为2i,否则结点i无左孩子。
③如果2i+1<=n,则结点i的右孩子的编号为2i+1,否则结点i无右孩子。

二叉树的存储结构

顺序存储结构
用一维数组存储二叉树的结点,用结点的存储位置(下标)表示结点之间的逻辑关系。
对于一般的二叉树,可以按照完全二叉树进行层序编号,然后再用一维数组顺序存储。
具体步骤:
1:将二叉树按完全二叉树编号。根结点的编号为1,若某结点i有左孩子,则其左孩子的编号为2i;若某结点i有右孩子,则其右孩子的编号为2i+1。
2:将二叉树的结点按照编号顺序存储到一维数组中。

#include<iostream>
using nameapace std;
const int size=100;
template<class Type>
class LinearBinTree
{
private:
    Type Data[size];
    int last;
public:
LinearBinTree():last(0){
for(int i=0;i<size;i++)
Data[i]=Type(-111);
}
~LinearBinTree(){}
bool AddNode(Type);
bool IsEmpty(){return last==0;}
bool IsFull(){return size-1<=last;}
void Print();
void PreOrderTraversal();
};
template<class Type>
bool LinearBinTree<Type>::AddNode(Type x)
{
    if(IsFull())
        return false;
    if(IsEmpty())
    {
    Data[1]=x;
    last=1;
    return true;
}

int i=1;
while(i)
{
    if(Data[i]==Type(-111))
    {
        Data[i]=x;
        last=(i>last?i:last);
        return true;
    } 
    if(Data[i]>x)
        i=2*i;
    else
        i=2*i+1;

    return false;
}

template<class Type>
void LinearBinTree<Type>::Print()
{
    for(int i=1;i<=last;i++)
    {
        if(Data[i]==Type(-111))
        continue;
        cout<<Data[i]<<" ";
    }
    cout<<endl;
}

二叉链表的存储结构及遍历
令二叉树的每个结点对应一个链表结点,链表结点除了存放二叉树结点的数据信息外,还要存放指示左右孩子的指针。
二叉链表结点结构

template<typename T>
struct BiNode{
T data;
BiNode *lchild,rchild;
};
#include<iostream>
#include<string>
using namespace std;
struct BiNode{
	char data;
	BiNode *l,*r;
	};
class BiTree{
	public:
	    BiTree(){root=great();}
	    ~BiTree(){release(root);}
		void preorder(){preorder(root);}
		void inorder(){inorder(root);}
		void postorder(){postorder(root);}
	private:
	    BiNode *great();
		void release(BiNode *bt);
		void preorder(BiNode *bt);
		void inorder(BiNode *bt);
		void postorder(BiNode *bt);
		BiNode *root;
};
BiNode *BiTree::great()//构建
{
	BiNode *bt;
	char a;
	cin>>a;
	if(a=='#') bt=NULL;
	else{
		bt=new BiNode;
		bt->data=a;
		bt->l=great();
		bt->r=great();
		}
	return bt;
}
void BiTree::preorder(BiNode *bt)//前序遍历
{
	if(bt==NULL) return;
	else{
		cout<<bt->data;
		preorder(bt->l);
		preorder(bt->r);
	}
}
void BiTree::inorder(BiNode *bt)//中序遍历
{
	if(bt==NULL) return;
	else{
		inorder(bt->l);
		cout<<bt->data;
		inorder(bt->r);
	}
}
void BiTree::postorder(BiNode *bt)//后序遍历
{
	if(bt==NULL) return;
	else{
		postorder(bt->l);
		postorder(bt->r);
		cout<<bt->data;
	}
}
void BiTree::release(BiNode *bt)
{
if (bt==NULL) return;
else{
    release(bt->l); 
    release(bt->r); 
    delete bt;
    } 
}
int main()
{
	string s;
	while(1){
		BiTree t;
		cin>>s;
	    t.preorder();
		cout<<endl;
        t.inorder();
		cout<<endl;
	    t.postorder();
		cout<<endl;
		if(s=="Y"){
	        continue;
			}
        else if(s=="N")
	        break;
		}
	return 0;
}

二叉链表的推广:三叉链表
为了能够高效地解决孩子寻找双亲结点的问题,由二叉链表的基础之上,结点新添加一个parent域,用于存储孩子的父亲。
结构体如下:

struct TriNode
{
    T data;
    TriNode *lchild,*rchild,*parent;
}


这种存储结构既便于寻找孩子结点,又便于查找双亲结点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值