数据结构--树和二叉树--二叉树的创建和遍历(递归和非递归方式)

来源:互联网 发布:爱普生m10清零软件 编辑:程序博客网 时间:2024/05/22 17:10

    首先给出二叉树的定义:二叉树是一种树型结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。二叉树有两中存储结构:顺序存储结构,链式存储结构。只有当一棵二叉树是完全二叉树时采用顺序存储结构才有较高的存储密度,而链式存储结构更加灵活。链式存储结构的结点又分为两中存储结构:二叉链表,三叉链表。结点中包含数据域,左右指针域的成为二叉链表。有时,为了便于找到结点的双亲,还经常在结点中添加一个指向其双亲的指针域,这种结点存储结构称之为三叉链表。

//二叉树的二叉链表存储表示

//---------------------------------------------------------

typedef struct BiNode{

    TElemType data;    //数据域

    struct BiNode * lchild,*rchild;   //左右指针域

}BiNode,*BiTree;

//---------------------------------------------------------


//二叉树的三叉链表存储表示

//---------------------------------------------------------

typedef struct BiNode{

    TElemType data;    //数据域

    struct BiNode * lchild,*rchild,*parent;   //左右指针域,指向双亲结点的指针域

}BiNode,*BiTree;

//---------------------------------------------------------

二叉树的遍历可以分为:先序遍历,中序遍历,后序遍历三种方式,遍历的实质是对一个非线性结构进行线性化的操作。

下面为创建二叉树,和遍历二叉树的代码:

//以二叉链表为存储方式的二叉树的存储表示和基本操作typedef struct BiNode{    TElemType data;   //数据域    struct BiNode *lchild,*rchild;  //左右孩子指针    BiNode(){        data=0;        lchild=NULL;        rchild=NULL;    }}BiNode,*BiTree;Status CreateBiTree(BiTree & T){    TElemType ch;    cin>>ch;    if(ch=='@') T=NULL;    else{        if(!(T=(BiTree)malloc(sizeof(BiNode)))) exit(OVERFLOW);        T->data=ch;    //生成根结点        CreateBiTree(T->lchild);  //构造左子树        CreateBiTree(T->rchild);  //构造右子树    }    return OK;}Status PreOrderTraverse(BiTree T,Status (*Visit)(TElemType e)){    //递归方式先序遍历二叉树    if(T){        if(Visit(T->data))            if(PreOrderTraverse(T->lchild,Visit))                if(PreOrderTraverse(T->rchild,Visit))                    return OK;        return ERROR;    }else    return OK;}Status GetTop(stack<BiNode*> s,BiNode* &p){    if(s.empty())return ERROR;    p=s.top();    return OK;}void Pop(stack<BiNode*> &S,BiNode* &p){    GetTop(S,p);    S.pop();}//采用二叉链表存储结构,非递归方式中序遍历二叉树T,对每一个元素调用VisitStatus InOrderTraverse1(BiTree T,Status (*Visit)(TElemType e)){    stack<BiNode*> S;    S.push(T);    BiNode* p=NULL;    while(!S.empty()){        while(GetTop(S,p)&&p) S.push(p->lchild);        Pop(S,p);        if(!S.empty()){            Pop(S,p); if(!Visit(p->data)) return ERROR;            S.push(p->rchild);        }    }    return OK;}//非递归方式中序遍历二叉树的第二种方法Status InOrderTraverse2(BiTree T,Status (*Visit)(TElemType e)){    stack<BiNode*> S;    BiTree p=NULL;    p=T;    while(p||!S.empty()){        if(p) {            S.push(p);            p=p->lchild;        }        else {            Pop(S,p);            if(!Visit(p->data)) return ERROR;            p=p->rchild;        }    }    return OK;}Status PrintElement(TElemType e){    cout<<e<<" ";    return OK;}int main(){    BiTree t;    CreateBiTree(t);    PreOrderTraverse(t,PrintElement);    InOrderTraverse1(t,PrintElement);    InOrderTraverse2(t,PrintElement);    return 0;}


0 0