给定二叉树的先序遍历有多少种可能的二叉树

  • 给定二叉树的先序遍历有多少种可能的二叉树

    问题:给定二叉树的先序遍历有多少种可能的二叉树

    git地址:https://github.com/944613709/HIT-Data-Structures-and-Algorithms

    算法思想:

    在二叉树先序遍历非递归算法中,二叉树先序遍历序列即为二叉树结点入栈顺序,而二叉树中序遍历序列即为二叉树结点出栈顺序,已知二叉树的先序遍历序列和中序遍历序列,即可确定一棵二叉树,所以问题等价于已知二叉树结点入栈顺序,有多少种可能的出栈顺序。

    用队列来模拟输入,队列的输出则按照原先序列的顺序。再使用一个栈来模拟入栈和出栈,结果保存在另外一个队列

    对于任意的一个元素k,要么进栈处理下一个元素,要么判断栈是否为空若不为空则进行出栈继续处理元素。当所有的元素都入栈了,k=n+1时候就可以输出队列和栈的元素,成为一个出栈序列,计数加一,再执行回溯,递归

    算法步骤:

    \1. 初始化栈和队列

    \2. 调用OutPut_S(1);函数执行从k=1开始

    (1) 如果k!=n+1,需要后续继续递归

    ① 将当前元素k入栈

    ② 处理下一个元素k+1调用OutPut_S(k+1);

    ③ 进行回溯到之前元素的状态利用pop(s)

    ④ 判断栈是非为空,如果空

    \1) 栈顶元素出栈

    \2) 存入队列

    \3) 再次调用OutPut_S(k);处理当前元素k

    \4) 出队

    \5) 将此时的元素入栈,进行回溯操作,也就是抹去之前的处理,进行递归处理其他元素

    (2) 如果k==n+1时,完成递归,所有元素都已经入过栈完毕,作为出口

    ① 打印队列元素

    \1) While直到p->next!=NULL

    a. 每一次printf并且p=p->next;

    ② 打印栈元素

    \1) 利用for循环将所有元素printf

    ③ 并且计数利用cout++

    测试样例

    img

    imgimg

    具体代码

    \#include <stdio.h>

    \#include <stdlib.h>

    \#include <string.h>

    \#include <stdbool.h>

    \#define MAX 99

    ``

    typedef struct STACK

    {

    int top;

    int data[MAX];

    }STACK;

    void push(STACK *s,int data)

    {

    s->data[++s->top]=data;

    }

    void pop(STACK *s)

    {

    s->top--;

    }

    void STACK_Initial(STACK *s)

    {

    s->top=-1;

    }

    ``

    int top(STACK *s)

    {

    return s->data[s->top];

    }

    bool Isempty(STACK *s)

    {

    if(s->top==-1)

    return true;

    else

    return false;

    }

    typedef struct Qnode

    {

    int data;

    struct Qnode* next;

    }Qnode;

    ``

    typedef struct Queue

    {

    Qnode* front;

    Qnode* rear;

    }queue;

    void Q_Initial(queue *q)

    {

    Qnode *p=malloc(sizeof(Qnode));

    p->next=NULL;

    q->front=p;

    q->rear=p;

    }

    void enqueue(queue *q,int k)

    {

    Qnode *p=malloc(sizeof(Qnode));

    p->data=k;

    p->next=NULL;

    q->rear->next=p;

    q->rear=p;

    }

    void dequeue(queue *q)

    {

    Qnode *p=q->front->next;

    q->front->next=p->next;

    free(p);

    if(q->front->next==NULL)

    q->rear=q->front;

    }

    queue *q; //队列保存已出栈元素

    int n;

    int count=0;

    STACK *s;

    ``

    void OutPut_S(int k)

    {

    int temp;

    if(k!=n+1)//当k!=n+1时候继续递归

    {

    push(s,k);

    //当前元素k入栈

    OutPut_S(k+1);

    //处理下一元素k+1

    pop(s); //回溯至当前元素状态

    if(!Isempty(s)) //当栈非空时

    {

    temp=top(s);

    pop(s);

    enqueue(q,temp);

    OutPut_S(k);

    dequeue(q);

    push(s,temp);

    }

    }

    else if(k==n+1)

    {//当k==n+1时候结束递归

    Qnode* p=q->front;

    while(p->next!=NULL)

    { //将队列元素打印——已经出栈的元素

    printf("%d ",p->next->data);

    p=p->next;

    }

    int j;

    //然后再打印栈的元素 ,然后回溯

    for(j=s->top;j>=0;j--)

    printf("%d ",s->data[j]);

    count++; //计数共有几种可能

    printf("\n");

    return ;

    }

    ``

    }

    ``

    int main()

    {

    s = malloc(sizeof(STACK));

    STACK_Initial(s);

    q = malloc(sizeof(queue));

    Q_Initial(q);

    printf("请输入先序序列有多少个元素\n");

    scanf("%d",&n);

    OutPut_S(1);

    printf("共有%d种可能",count);

    return 0;

    }

    ``


给定二叉树的先序遍历有多少种可能的二叉树
http://yoursite.com/2023/05/16/给定二叉树的先序遍历有多少种可能的二叉树/
作者
Fars
发布于
2023年5月16日
许可协议