美文网首页数据结构&算法&人工智能
二叉树的链式存储结构及四种遍历算法

二叉树的链式存储结构及四种遍历算法

作者: 零岁的我 | 来源:发表于2020-02-27 16:39 被阅读0次

当二叉树不是完全二叉树时,使用顺序表来存储会造成很多的空间浪费,因此对于普通二叉树来说,使用链表存储更为合适。


普通二叉树示意图 二叉树链式存储结构示意图

采用链式存储二叉树时,其节点结构由 3 部分构成(如图 3 所示):

  • 指向左孩子节点的指针(Lchild);
  • 节点存储的数据(data);
  • 指向右孩子节点的指针(Rchild);


    链式存储中树节点结构

二叉树的构建代码及四种遍历算法代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<stack>
using namespace std;

typedef char Elemtype;

//表示树节点的结构体
typedef struct TNode{
    Elemtype data; //数据域
    struct TNode *lchild,*rchild; //左右孩子指针
}Tnode,*Tree;

//创建树
void CreateTree(Tree &T)
{
    queue<Tree> Q; //初始化一个空队列
    char buff[3]; //用来缓存输入的孩子节点数值
    printf("请输入根节点(以#表示空):");
    scanf("%c",&buff[0]); //输入根节点
    getchar();
    if(buff[0]!='#'){ //根节点不为空
        T=(Tree)malloc(sizeof(Tnode)); //为根节点开辟内存空间
        T->data=buff[0];
        //T->rchild=NULL;//根节点没有右孩子;
        Q.push(T); //根节点入队
        while(!Q.empty()){
            Tnode *tmp=(Tnode*)malloc(sizeof(Tnode)); //为孩子节点开辟内存空间
            tmp=Q.front();
            Q.pop();
            printf("请依次输入节点%c的左右孩子:",tmp->data);
            scanf("%s",buff);
            if(buff[0]!='#'){
                Tnode *lc=(Tnode*)malloc(sizeof(Tnode));
                lc->data=buff[0];
                tmp->lchild=lc;
                Q.push(lc);
            }
            else{
                tmp->lchild=NULL;
            }
            if(buff[1]!='#'){
                Tnode *rc=(Tnode*)malloc(sizeof(Tnode));
                rc->data=buff[1];
                tmp->rchild=rc;
                Q.push(rc);
            }
            else{
                tmp->rchild=NULL;
            }
        }
    }
    else{ //树为空
        T=NULL;
    }
}

//二叉树的层次遍历
/*二叉树层次遍历的思想是:
通过使用队列的数据结构,从树的根结点开始,依次将其左孩子
和右孩子入队。而后每次队列中一个结点出队,都将其左孩子和
右孩子入队,直到树中所有结点都出队,出队结点的先后顺序就
是层次遍历的最终结果。
*/
void LevelTraverse(Tree T)
{
    queue<Tree> Q;
    if(T){
        Q.push(T);
        while(!Q.empty()){
            Tnode *tmp=(Tnode*)malloc(sizeof(Tnode));
            tmp=Q.front();
            Q.pop();
            printf("%c ",tmp->data);
            if(tmp->lchild){
                Q.push(tmp->lchild);
            }
            if(tmp->rchild){
                Q.push(tmp->rchild);
            }
        }
        printf("\n");
    }
    else{
        printf("树为空\n");
    }
}

//二叉树的先序遍历,非递归实现
/*二叉树先序遍历的实现思想是:
1.访问根节点;
2.访问当前节点的左子树;
3.若当前节点无左子树,则访问当前节点的右子树;
*/
void preorderTraverse(Tree T)
{
    if(T){
        stack<Tree> S;
        S.push(T);
        while(!S.empty()){
            Tnode *tmp=(Tnode*)malloc(sizeof(Tnode));
            tmp=S.top();
            S.pop();
            printf("%c ",tmp->data);
            while(tmp){
                if(tmp->rchild){
                    S.push(tmp->rchild);
                }
                if(tmp->lchild){
                    printf("%c ",tmp->lchild->data);
                }
                tmp=tmp->lchild;
            }
        }
        printf("\n");
    }
    else{
        printf("树为空\n");
    }
}

//二叉树的中序遍历,非递归实现
/*二叉树中序遍历的实现思想是:
1.访问当前节点的左子树;
2.访问根节点;
3.访问当前节点的右子树
*/
void inorderTraverse(Tree T)
{
    if(T){
        stack<Tree> S;
        Tnode *tmp=T;
        while(tmp || !S.empty()){
            if(tmp){
                S.push(tmp);
                tmp=tmp->lchild;
            }
            else{
                tmp=S.top();
                S.pop();
                printf("%c ",tmp->data);
                tmp=tmp->rchild;
            }
        }
        printf("\n");
    }
    else{
        printf("树为空\n");
    }
}

//二叉树的后序遍历,递归实现
/*二叉树后序遍历的实现思想是:
从根节点出发,依次遍历各节点的左右子树,直到
当前节点左右子树遍历完成后,才访问该节点元素。
*/
void postorderTraverse(Tree T)
{
    if(T){
        postorderTraverse(T->lchild);
        postorderTraverse(T->rchild);
        printf("%c ",T->data);
    }
}

int main(int argc,char **argv)
{
    Tree T;
    CreateTree(T);
    printf("树的层次遍历结果为:");
    LevelTraverse(T);
    printf("树的先序遍历结果为:");
    preorderTraverse(T);
    printf("树的中序遍历结果为:");
    inorderTraverse(T);
    printf("树的后序遍历结果为:");
    postorderTraverse(T);

    return 0;
}

运行结果:


运行结果

参考链接:http://c.biancheng.net/view/3386.html

相关文章

网友评论

    本文标题:二叉树的链式存储结构及四种遍历算法

    本文链接:https://www.haomeiwen.com/subject/jrhxhhtx.html