二叉树的顺序存储和基本操作

本文详细介绍了二叉树的概念、性质及存储结构,并提供了递归与非递归遍历的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、二叉树的定义:

二叉树是n个结点的有限集合,当n=0时称为空树,否则:(1)有且只有一个特殊的被称为树的根结点;(2)若n>1时,其余的结点被分为两个互不相交的子集,称为左右子树,并且左右子树都是二叉树;可以看出二叉树的定义是递归的。

二、二叉树的性质:

(1)在非空二叉树上,第i层至多有2^(i-1)个结点;

(2)深度为k的二叉树至多有2^k-1个结点;

(3)对任何一个二叉树,若其叶子结点数为n0,度为2的节点数为n2,则n0=n2+1;

满二叉树:一课深度为k且有2^k-1个结点的二叉树。

完全二叉树:如果深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应,该二叉树称为完全二叉树。2^(k-1)<=n<=2^k-1

(4)n个结点的完全二叉树的深度k=[log2 n]+1,这里这个符号[x]表示小于等于x的整数;(证明过程,对上述n的不等式取对数)

(5)若对一棵有n个结点的完全二叉树(深度为└㏒2n┘+1)的结点按层(从第1层到第㏒2n +1层)序自左至右进行编号,则对于编号为i(1≦i≦n)的结点:

1 若i=1:则结点i是二叉树的根,无双亲结点;否则,若i>1,则其双亲结点编号是 [i/2]
2、 如果2i>n:则结点i为叶子结点,无左孩子;否则,其左孩子结点编号是2i。
3、 如果2i+1>n:则结点i无右孩子;否则,其右孩子结点编号是2i+1。 

三、二叉树的存储结构

1、顺序存储结构:

typedef char ElemType;
typedef struct stree
{
    ElemType bitTree[MAX_SIZE];
    int pointer;   //number of points
}STree;
//init
void STree_Init(STree &T)
{
    for(int i=0;i<MAX_SIZE;++i)
        T.bitTree[i]='0';
    T.pointer=0;
}
//insert root
int STree_insert_Root(STree &T,ElemType e)
{
    T.bitTree[1]=e;
    T.pointer++;
    return 1;
}
//insert left
int STree_insert_Left(STree &T,int i,ElemType e)
{
    if(i>=MAX_SIZE || i<0)
    {
        cout<<"argument is false!"<<endl;
        return -1;
    }
    T.bitTree[2*(i+1)]=e;
    T.pointer++;
    return 1;
}
//insert right
int STree_insert_Right(STree &T,int i,ElemType e)
{
    if(i>=MAX_SIZE || i<0)
    {
        cout<<"argument is false!"<<endl;
        return -1;
    }
    T.bitTree[2*(i+1)+1]=e;
    T.pointer++;
    return 1;
}
//
int STree_delete_Left(STree &T,int i,ElemType *x_left)
{
    if(i>=MAX_SIZE || i<0)
    {
        cout<<"argument is false!"<<endl;
        return -1;
    }
    *x_left=T.bitTree[2*(i+1)];
    T.pointer--;
    return 1;
}
//
int STree_delete_Right(STree &T,int i,ElemType *x_right)
{
    if(i>=MAX_SIZE || i<0)
    {
        cout<<"argument is false!"<<endl;
        return -1;
    }
    *x_right=T.bitTree[2*(i+1)+1];
    T.pointer--;
    return 1;
}
int STree_delete_Root(STree &T,ElemType *x_root)
{
    *x_root=T.bitTree[1];
    T.pointer--;
    return 1;
}
//
bool STree_empty(STree &T)
{
    return T.pointer==0;
}

2、三种遍历方式:前序、中序、后序

递归形式的遍历方式

//前序遍历
void STree_Traver_1(STree &T,int i)
{
        cout<<T.bitTree[i]<<" ";
        if(T.bitTree[2*i]!='0')
            STree_Traver_1(T,2*i);
        if(T.bitTree[2*i+1]!='0')
            STree_Traver_1(T,2*i+1);
}
//中序遍历
void STree_Traver_2(STree &T,int i)
{
    if(T.bitTree[2*i]!='0')
        STree_Traver_2(T,2*i);
    cout<<T.bitTree[i]<<" ";
    if(T.bitTree[2*i+1]!='0')
        STree_Traver_2(T,2*i+1);
}
//后序遍历
void STree_Traver_3(STree &T,int i)
{
    if(T.bitTree[2*i]!='0')
        STree_Traver_3(T,2*i);
    if(T.bitTree[2*i+1]!='0')
        STree_Traver_3(T,2*i+1);
    cout<<T.bitTree[i]<<" ";
}


非递归形式的遍历方式

//前序遍历
int STree_Traver_1_no(STree &T)
{
    stack<int> s({'0'});
    int p=1,q;
    if(STree_empty(T))
    {
        cout<<"tree is empty!"<<endl;
        return -1;
    }
do{
    cout<<T.bitTree[p]<<" ";
    q=p*2+1;
    if(T.bitTree[q]!='0')
        s.push(q);
    p=p*2;
    if(T.bitTree[p]=='0') //到树的底部了,回退
    {
        p=s.top();
        s.pop();
    }
 }while(T.bitTree[p]!='0');

    return 1;
}
//中序遍历
int STree_Traver_2_no(STree &T)
{
    stack<int> s;
    int p=1;
    int b=1;
    /*
    if(STree_empty(T))
    {
        cout<<"tree is empty!"<<endl;
        return -1;
    }
    */
    do
    {
        while(T.bitTree[p]!='0')
        {
            s.push(p);
            p=p*2;
        }
        if(s.empty()) b=0;
        else {
        p=s.top();
        s.pop();
        cout<<T.bitTree[p]<<" ";
        p=p*2+1;
        }
    }while(b!=0);
    return 1;
}
//后序遍历
int STree_Traver_3_no(STree &T)
{
    int p=1;
    int b=1,top=0;
    int s1[20],s2[20];
    do
    {
        while(T.bitTree[p]!='0')
        {
            s1[++top]=p;
            s2[top]=0;
            p=p*2;
        }
        if(top==0) b=0;
        else if(s2[top]==0)
        {
            p=s1[top]*2+1;
            s2[top]=1;
        }
        else
        {
            p=s1[top];
            top--;
            cout<<T.bitTree[p]<<" ";
            T.bitTree[p]='0';
        }
    }while(b!=0);
    return 1;
}


关于二叉树的顺序存储结构和递归遍历方式以及非递归遍历方式,上边全部给出了实现代码,下一篇给出链式存储结构及其遍历方式的代码。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值