数据结构第八周 :( 数组循环右移K位 + 二叉树的创建及遍历 + 二叉树根据中序和后序求前序遍历 + 二叉树结点的共同祖先问题 + 二叉树左右子树交换操作 )

数组循环右移K位

【问题描述】将一个数组中的元素循环右移K位,要求只使用一个元素大小的附加存储空间,时间复杂度为O(n)。

【样例输入】

1 2 3 4 5 6 7 8 0

2

【样例输出】

7 8 1 2 3 4 5 6

【提示】0代表输入结束

#include<iostream>
#define N 1000
using namespace std;

void swap(int s[N], int front, int behind)
{
    int temp = 0;
    for( ; front < behind; front ++)
    {
        temp = s[front];
        s[front] = s[behind];
        s[behind] = temp;
        behind --;
    }
}
int main()
{
    int s[N];
    int i = 0;
    int num = 0;
    int len = 0;
    for(i = 0; ; i ++) // 输入数组
    {
        cin>>num;
        if(num == 0) break;
        else
        {
            len ++;
            s[i] = num;
        }
    }
    int k = 0;
    cin>>k;
    k = k % len;
    int j = len - k; //分割点
    swap(s, 0, j - 1 );
    swap(s, j, len - 1);
    swap(s, 0, len - 1);
    for(i = 0; i < len; i ++)
    {
        cout<<s[i]<<" ";
    }
    return 0;
}

二叉树的创建及遍历

【问题描述】

给出一个按照先序遍历得出的字符串,‘#’ 代表空的子节点,大写字母代表节点内容。请通过这个字符串建立二叉树,并分别采用“递归”和“非递归”的先序、中序、后序遍历的算法分别输出每一个非空节点。

【输入形式】
输入只有一行,包含一个字符串S,用来建立二叉树。保证S为合法的二叉树先序遍历字符串,节点内容只有大写字母,且S的长度不超过100。

【输出形式】
共有6行,每一行包含一串字符,表示分别按递归和非递归的先序、中序、后序遍历得出的节点内容,每个字母后输出一个空格。请注意行尾输出换行。

【样例输入】

ABC##DE#G##F###

【样例输出】

A B C D E G F

C B E G D F A

C G E F D B A

A B C D E G F

C B E G D F A

C G E F D B A

#include<iostream>
#include<stack>
#include<stdlib.h>
#include<stdio.h>
using namespace std;

typedef struct Bnode //定义二叉树节点
{
    char data;
    struct Bnode * LChild;
    struct Bnode * RChild;
}BiTreeNode,*BiTree;

void CreatBt(BiTree * root) //创建二叉树
{
    char s;
    s = getchar();
    if(s == '#')
    {
        *root = NULL;
    }
    else
    {
        *root = (BiTree)malloc(sizeof(BiTreeNode));
        (*root)->data = s;
        CreatBt(&(*root)->LChild);
        CreatBt(&(*root)->RChild);
    }
}

void RePreOder(BiTree root) //递归前序遍历
{
    if(root == NULL)
    {
        return ;
    }
    else
    {
        cout<<root->data<<" ";
        RePreOder(root->LChild);
        RePreOder(root->RChild);
    }
    return ;
}

void ReInOrder(BiTree root) //递归中序遍历
{
    if(root == NULL)
    {
        return ;
    }
    else
    {
        ReInOrder(root->LChild);
        cout<<root->data<<" ";
        ReInOrder(root->RChild);
    }
    return ;
}

void RePostOrder(BiTree root) //递归后序遍历
{
    if(root == NULL)
    {
        return ;
    }
    else
    {
        RePostOrder(root->LChild);
        RePostOrder(root->RChild);
        cout<<root->data<<" ";
    }
    return ;
}

void PreOrder(BiTree root) //前序遍历
{
    stack<BiTree> S; //元素定义为指针类型
    while(root != NULL)
    {
        cout<<root->data<<" ";
        S.push(root);
        if(root->LChild != NULL)
        {
            root = root->LChild;
        }
        else if(!S.empty())
        {
            while(!S.empty())
            {
                root = S.top(); //无参有返回值
                S.pop(); //无参无返回值
                root = root->RChild;
                if(root != NULL) break;
            }
        }
        else
        {
            root = NULL;
        }
    }
}

void InOrder(BiTree root) //中序遍历
{
    stack<BiTree> S;
    while(root != NULL)
    {
        S.push(root);
        if(root->LChild != NULL)
        {
            root = root->LChild;
        }
        else if(!S.empty())
        {
            while(!S.empty())
            {
                root = S.top();
                S.pop();
                cout<<root->data<<" "; //出栈顺序左根右
                root = root->RChild;
                if(root != NULL) break;
            }
        }
        else
        {
            root = NULL;
        }
    }
}

void PostOrder(BiTree root) //后序遍历
{
    stack<BiTree> S;
    BiTree p = root;
    BiTree q = NULL;
    while(p != NULL || !S.empty())
    {
        while(p != NULL)
        {
            S.push(p);
            p = p->LChild;
        }
        BiTree t = S.top();
        if(t->RChild == NULL || t->RChild == q)
        {
            cout<<t->data<<" ";
            S.pop();
            q = t;
        }
        else
        {
            p = t->RChild;
        }
    }
}

int main()
{
    BiTree root = NULL;
    CreatBt(&root); //创建二叉树

    RePreOder(root); //sting类传值,原string类不改变
    cout<<endl;
    ReInOrder(root);
    cout<<endl;
    RePostOrder(root);
    cout<<endl;

    PreOrder(root);
    cout<<endl;
    InOrder(root);
    cout<<endl;
    PostOrder(root);
    return 0;
}
//总结:string类初始状态无空间,不可以s[0]这样使用

二叉树根据中序和后序求前序遍历

【问题描述】 根据一棵二叉树的中序遍历序列和后序遍历序列,求这棵树的前序遍历序列。

【输入形式】 一棵树的中序遍历序列和该树后序遍历序列。输入序列中仅含有小写字母,且没有重复的字母

【输出形式】 一棵树的前序遍历序列

【样例输入】
dbeafcg

debfgca

【样例输出】

abdecfg

#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
typedef struct Bnode
{
    char data;
    struct Bnode * LChild;
    struct Bnode * RChild;
}BtNode,*BTree;
void CreatBt(BTree * root, string post, string in, int postleft, int postright, int inleft, int inright)
{
    if(postleft > postright)
    {
        *root = NULL;
    }
    else
    {
        *root = (BTree)malloc(sizeof(BtNode));
        (*root)->data = post[postright];
        //cout<<(*root)->data<<" ";
        int mid = 0;
        while(in[mid] != post[postright])
        {
            mid ++;
        }
        CreatBt(&((*root)->LChild), post, in, postleft, postleft + mid - inleft - 1, inleft, mid -1);
        CreatBt(&((*root)->RChild), post, in, postleft + mid - inleft, postright - 1, mid + 1, inright);
    }
}

void PreOrder(BTree root)
{
    if(root == NULL)
    {
        return ;
    }
    else
    {
        cout<<root->data;//root不为空才能输出
        PreOrder(root->LChild);
        PreOrder(root->RChild);
    }
}
int main()
{
    string post;
    string in;
    cin>>in;
    cin>>post;
    int len = post.length();
    BtNode * root = NULL;
    CreatBt(&root, post, in, 0, len - 1, 0, len - 1);
    PreOrder(root);
}

二叉树结点的共同祖先问题

【问题描述】假设二叉树采用二叉链表方式存储,root指向根结点,p所指结点和q所指结点为二叉树中的两个不同结点,且互不成为根到该结点的路径上的点,编程求解距离它们最近的共同祖先。

【输入形式】二叉树的前序和中序遍历序列,用以创建该二叉树的链式存储结构;以及二叉树的两个结点数据 x 和 y

【输出形式】结点数据值为 x 和结点数据值为 y 的最近的共同祖先,若没有共同祖先则输出NULL,请注意一个结点本身不能成为另一个结点的共同祖先。

【样例输入】

GABDCEF

BDAEFCG

DF

【样例输出】

A

#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;

typedef struct node
{
    char data;
    struct node * LChild;
    struct node * RChild;
}BtNode, *BTree;

void Creat(BTree * root, string Pre, string In, int preleft, int preright, int inleft, int inright)
{
    if(inleft > inright)
    {
        *root = NULL;//此时二叉树没有节点,应该让指针为空
    }
    else
    {
        int mid = 0;
        while(In[mid] != Pre[preleft])
        {
            mid ++;
        }
        *root = (BTree)malloc(sizeof(BtNode));
        (*root)->data = Pre[preleft];
        Creat(&((*root)->LChild), Pre, In, preleft + 1, preleft + mid - inleft, inleft, mid - 1);
        Creat(&((*root)->RChild), Pre, In, preleft + mid - inleft + 1, preright, mid + 1, inright);
    }
}

BTree Find(BTree root, BTree p, BTree q)
{
    if(root == NULL) return NULL;
    if(root->data == p->data || root->data == q->data) //NULL为假
    {
        return root;
    }
    BtNode * left = Find(root->LChild, p, q);
    BtNode * right = Find(root->RChild, p, q);
    if(!left && !right) return NULL;
    else if(!left && right) return right;
    else if(left && !right) return left;

    return root;
}

void PreOrder(BTree root)
{
    if(root == NULL)
    {
        return ;
    }
    else
    {
        cout<<root->data;
        PreOrder(root->LChild);
        PreOrder(root->RChild);
    }
}
int main()
{
    string Pre;
    string In;
    cin>>Pre;
    cin>>In;
    BtNode * root = NULL;
    int len = Pre.length();
    Creat(&root, Pre, In, 0, len - 1, 0, len - 1);
    BtNode * p = (BTree)malloc(sizeof(BtNode));
    BtNode * q = (BTree)malloc(sizeof(BtNode));
    //PreOrder(root);
    cout<<endl;
    string s;
    cin>>s;
    p->data = s[0];
    q->data = s[1];
    //cout<<p->data<<q->data;
    BtNode * res = Find(root, p, q);
    if(res == NULL || res->data == root->data) cout<<"NULL";
    else cout<<res->data;
    return 0;
}

二叉树左右子树交换操作

【问题描述】二叉树按照二叉链表的方式存储。编写程序,计算二叉树中叶子结点的数目并输出;编写程序,将二叉树的每个结点的左、右子树进行交换,请注意不是只交换结点的data值,而是左、右孩子指针指向的交换,最后输出交换后的二叉树的后序遍历序列。

【输入形式】二叉树的前序遍历序列,空指针的位置输入字符#

【输出形式】叶子结点的数目;左右子树交换后,后序遍历的序列,空子树的位置输出字符#

【样例输入】

ABE##F##CG###

【样例输出】

3

###GC##F##EBA

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;

typedef struct node //建立二叉树节点
{
    char data;
    struct node * LChild;
    struct node * RChild;
}BtNode, *BTree;

void CreatBt(BTree * root) //创建二叉树
{
    char c;
    c = getchar();
    if(c == '#')
    {
        *root = NULL;
    }
    else
    {
        *root = (BTree)malloc(sizeof(BtNode)); //要申请空间的
        (*root)->data = c;
        CreatBt(&((*root)->LChild));
        CreatBt(&((*root)->RChild));
    }
}

int CountLeave(BTree root) //分治法求叶子数
{
    int leave = 0;
    if(root == NULL)
        return 0;
    else
    {
        if(root->LChild == NULL && root->RChild == NULL)
            return 1;
        else
            return CountLeave(root->LChild) + CountLeave(root->RChild);
    }
    return leave;
}

void ChangeLR(BTree root)
{
    if(root == NULL)
    {
        return ;
    }
    else
    {
        BTree temp = root->LChild;
        root->LChild = root->RChild;
        root->RChild = temp;
        ChangeLR(root->LChild);
        ChangeLR(root->RChild);
    }
    return ;
}

/*void Addheight(BTree * root)
{
    if(*root == NULL)
    {
        *root = (BTree)malloc(sizeof(BtNode));
        (*root)->data = '#';
        (*root)->LChild = NULL;
        (*root)->RChild = NULL;
        return ;
    }
    else
    {
        Addheight(&((*root)->LChild));
        Addheight(&((*root)->RChild));
    }
}*/

void PostOrder(BTree root)
{
    if(root == NULL)
    {
        cout<<'#';
        return ;
    }
    else
    {
        PostOrder(root->LChild);
        PostOrder(root->RChild);
        cout<<root->data;
    }
    return ;
}

int main()
{
    BtNode * root;
    CreatBt(&root);//传指针的地址
    cout<<CountLeave(root)<<endl;
    ChangeLR(root);
    //Addheight(&root);
    PostOrder(root);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只可爱的小猴子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值