输出二叉树从根结点到每个叶子结点的路径逆序列

 《数据结构》算法设计题:假设二叉树采用二叉链存储结构,设计算法输出从根结点到每个叶子结点的路径逆序列。

要求二叉树从叶结点到根结点的路径,可以采用先序遍历、后序遍历、层次遍历等方法。本算法采用的是后序遍历非递归先序遍历递归方法。把程序要用到的二叉树的基本运算写到文件btree.h里面,实现如下功能。

  • CreateBtree(BTNode *&b, char *str):用二叉树括号串建立二叉链存储结构b。括号表示法形式:根(左子树,右子树)
  • DispBTree(BTNode *b):以括号表示法输出二叉树
  • DestroyBTree(BTNode *&b):销毁二叉树。

 

//文件名:btree.h 
#include<stdio.h>
#include<malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct node
{
	ElemType data;				//数据元素
	struct node *lchild;		//指向左孩子
	struct node *rchild;		//指向右孩子
} BTNode;
void CreateBTree(BTNode *&b,char *str)
{
    BTNode *St[MaxSize],*p=NULL;
    int top=-1,k,j=0;  
    char ch;
    b=NULL;             //建立的二叉树初始时为空
    ch=str[j];
    while (ch!='\0')    //str未扫描完时循环
    {
        switch(ch) 
        {
        case '(':St[++top]=p;k=1; break;        //为左节点
        case ')':--top;break;
        case ',':k=2; break;                        //为右节点
        default:p=(BTNode *)malloc(sizeof(BTNode));
                p->data=ch;p->lchild=p->rchild=NULL;
                    if (b==NULL)                    //p指向二叉树的根节点
                        b=p;
                    else                            //已建立二叉树根节点
                    {   
                        switch(k) 
                        {
                        case 1:St[top]->lchild=p;break;
                        case 2:St[top]->rchild=p;break;
                        }
                    }
        }
        ch=str[++j];
    }
}

void DestroyBTree(BTNode *&b)
{   if(b!=NULL)
    {  DestroyBTree(b->lchild);
       DestroyBTree(b->rchild);
       free(b);
    }
}

void DispBTree(BTNode *b)  //以括号表示法输出二叉树
{
	if(b!=NULL)
	{
		printf("%c", b->data);
		if(b->lchild!=NULL || b->rchild!=NULL)
		{
			printf("(");
			DispBTree(b->lchild);
			if(b->rchild!=NULL)
			    printf(",");
			DispBTree(b->rchild);
			printf(")");
		}
	}
}

 

#include "btree.h"         //包含二叉树的基本运算算法 

void PostOrder(BTNode *b)       //后序遍历的递归算法
{
    if (b!=NULL)  
    {   
        PostOrder(b->lchild);   //递归访问左子树
        PostOrder(b->rchild);   //递归访问右子树
        printf("%c ",b->data);  //访问根节点
    }
}
void PostOrder1(BTNode *b)
{    //后序遍历非递归算法
    BTNode *St[MaxSize];
    int top=-1;                   //栈指针置初值
    BTNode *p=b;
    BTNode *r=NULL; 
    while (p||top>-1)                 
    {
        if(p){
            St[++top]=p;
            p=p->lchild;
        }
        else
        {
            p=St[top];                  //取出当前的栈顶元素
            if (p->rchild &&p->rchild!=r)           //右子树不存在或已被访问,访问之
            {   p=p->rchild;
                St[++top]=p;
                p=p->lchild;
            }
            else                           //弹出节点并访问
            {   printf("%c ",St[top]->data); 
                top--;
                r=p;                    //r指向则被访问的节点
                p=NULL;
            }
        }
    }
}

void AllPath1(BTNode *b)
{    //后序遍历非递归算法输出每个叶子结点到根结点的路径序列 
    BTNode *St[MaxSize];
    int top=-1;                   //栈指针置初值
    BTNode *p=b;
    BTNode *r=NULL; 
    while (p||top>-1)                 
    {
        if(p)               //扫描结点p的所有左下结点并进栈
        {   St[++top]=p;    //结点p进栈
            p=p->lchild;    //移动到左孩子
        }
        else
        {
            p=St[top];                         //取出当前的栈顶元素
            if (p->rchild &&p->rchild!=r)      //右子树不存在或已被访问,访问之
            {   p=p->rchild;
                St[++top]=p;
                p=p->lchild;
            }
            else                           //弹出节点并访问
            {   if (p->lchild==NULL && p->rchild==NULL)    //若为叶子
                {   //输出栈中所有结点值
                    for (int i=top;i>0;i--)
                        printf("%c->",St[i]->data);
                    printf("%c\n",St[0]->data);
                }
                top--;
                r=p;                     //r指向则被访问的节点
                p=NULL;
            }
        }
    } 
}
void Allpath2(BTNode *b,ElemType path[],int pathlen)
{   //先序遍历方法输出每个叶子结点到根结点的路径序列 
    if(b!=NULL)
    {   if (b->lchild==NULL && b->rchild==NULL)    //b为叶子
        {   //输出栈中所有结点值
            printf("%c->",b->data);
            for (int i=pathlen-1;i>0;i--)
                printf("%c->",path[i]);
            printf("%c\n",path[0]);
        }
        else
        {   path[pathlen++]=b->data;
            Allpath2(b->lchild, path, pathlen);
            Allpath2(b->rchild, path, pathlen);
        }
    }
} 
void MaxPath(BTNode *b,ElemType path[],int pathlen,ElemType maxpath[],int &maxpathlen)
{   //先序遍历方法输出一条最长路径 
    if(b==NULL)//pathlen和maxpathlen的初值均为0
    {   if(pathlen>maxpathlen) //通过比较求最长路径
        {   for(int i=pathlen-1;i>=0;i--)
                maxpath[i]=path[i];
            maxpathlen=pathlen;
        }
    }
    else
    {   path[pathlen]=b->data;          //将当前节点放入路径中
        pathlen++;                      //路径长度增1
        MaxPath(b->lchild,path,pathlen,maxpath,maxpathlen);
                    //递归扫描左子树
        MaxPath(b->rchild,path,pathlen,maxpath,maxpathlen);
                    //递归扫描右子树
    }
}

int main()
{
    BTNode *b;
    CreateBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))"); 
    printf("二叉树b:");DispBTree(b);printf("\n");
    printf("后序遍历序列:\n");
    printf("    递归算法:");PostOrder(b);printf("\n");
    printf("  非递归算法:");PostOrder1(b);printf("\n");
    printf("Allpath1:\n");AllPath1(b);printf("\n");
    ElemType path[MaxSize],maxpath[MaxSize];
    int maxpathlen =0;
    printf("Allpath2:\n");    Allpath2(b,path,0);
	printf("Maxpath:\n");
    MaxPath(b,path,0,maxpath,maxpathlen);
    for(int i=0;i<maxpathlen-1;i++)
        printf("%c->",maxpath[i]);
    printf("%c\n",maxpath[maxpathlen-1]);
    DestroyBTree(b);
}
 

执行结果: 

  • 15
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是用C语言实现二叉树从根节点到每个叶子结点的路径序列的代码: ``` #include <stdio.h> #include <stdlib.h> // 定义二叉树构体 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 定义栈构体 typedef struct Stack { int top; int capacity; TreeNode **array; } Stack; // 初始化栈 Stack *initStack(int capacity) { Stack *stack = (Stack *)malloc(sizeof(Stack)); stack->top = -1; stack->capacity = capacity; stack->array = (TreeNode **)malloc(capacity * sizeof(TreeNode *)); return stack; } // 判断栈是否为空 int isStackEmpty(Stack *stack) { return stack->top == -1; } // 判断栈是否已满 int isStackFull(Stack *stack) { return stack->top == stack->capacity - 1; } // 入栈 void push(Stack *stack, TreeNode *node) { if (isStackFull(stack)) { printf("Stack is full!\n"); return; } stack->array[++stack->top] = node; } // 出栈 TreeNode *pop(Stack *stack) { if (isStackEmpty(stack)) { printf("Stack is empty!\n"); return NULL; } return stack->array[stack->top--]; } // 反转栈中元素 void reverseStack(Stack *stack) { if (isStackEmpty(stack)) { return; } TreeNode *node = pop(stack); reverseStack(stack); push(stack, node); } // 从根节点到叶子结点的路径序列 void reversePath(TreeNode *root) { if (root == NULL) { return; } Stack *stack = initStack(100); push(stack, root); while (!isStackEmpty(stack)) { TreeNode *node = pop(stack); if (node->left == NULL && node->right == NULL) { reverseStack(stack); while (!isStackEmpty(stack)) { printf("%d ", pop(stack)->val); } printf("%d\n", node->val); } if (node->right != NULL) { push(stack, node->right); } if (node->left != NULL) { push(stack, node->left); } } } // 测试 int main() { TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode)); root->val = 1; root->left = (TreeNode *)malloc(sizeof(TreeNode)); root->left->val = 2; root->left->left = (TreeNode *)malloc(sizeof(TreeNode)); root->left->left->val = 4; root->left->left->left = NULL; root->left->left->right = NULL; root->left->right = (TreeNode *)malloc(sizeof(TreeNode)); root->left->right->val = 5; root->left->right->left = NULL; root->left->right->right = NULL; root->right = (TreeNode *)malloc(sizeof(TreeNode)); root->right->val = 3; root->right->left = (TreeNode *)malloc(sizeof(TreeNode)); root->right->left->val = 6; root->right->left->left = NULL; root->right->left->right = NULL; root->right->right = (TreeNode *)malloc(sizeof(TreeNode)); root->right->right->val = 7; root->right->right->left = NULL; root->right->right->right = NULL; reversePath(root); return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值