算法练习题

1.树的遍历:

(1)设计思路:
①先利用利用递归,将中序和后序遍历序列构造成二叉树。
②采用层次遍历输出该树序列。
(2)代码:

1.#include <iostream>  
2.#include <stdio.h>  
3.#include <malloc.h>  
4.using namespace std;  
5.  
6.#define MaxSize 30  
7.  
8.typedef int ElemType;  
9.typedef struct node  
10.{  
11.    ElemType data;  
12.    struct node *lchild;  
13.    struct node *rchild;  
14.}BTNode;  
15.  
16.void DestroyBTree(BTNode *b)  
17.{  
18.    if(b!=NULL)  
19.    {  
20.        DestroyBTree(b->lchild);  
21.        DestroyBTree(b->rchild);  
22.        free(b);  
23.    }  
24.}  
25.  
26.BTNode *CreateBT2(int *post,int *in,int n)  
27.{  
28.    BTNode *b;  
29.    int r,*p;  
30.    int k;  
31.    if(n<=0) return NULL;  
32.    r=*(post+n-1);  
33.    b=(BTNode *)malloc(sizeof(BTNode));  
34.    b->data=r;  
35.    for(p=in;p<in+n;p++)  
36.        if(*p==r)break;  
37.    k=p-in;  
38.    b->lchild=CreateBT2(post,in,k);  
39.    b->rchild=CreateBT2(post+k,p+1,n-k-1);  
40.    return b;  
41.}  
42.  
43.void TravLevel(BTNode *b)  
44.{  
45.    BTNode *Qu[MaxSize];  
46.    int fron,rear;  
    fron=rear=0; 
2.列出叶结点:

(1)设计思路:
①按照题目中的输入,根节点是肯定不会出现在这里面的,所以我们只需要找到没有出现的数字,然后就可以确定根节点,有了根节点,然后再模拟队列的性质,依次把他的左孩子,右孩子插入进来,然后遍历指针+1,继续插入根节点的左孩子的左孩子和右孩子。
②用到一个辅助数组checked用来确定哪一个数字没有出现过,那就是根节点。
有了根节点,下一步需要一个队列ans,首先把根节点存进去,然后从根节点开始,左孩子,右孩子,左孩子的(左孩子,右孩子),右孩子的(左孩子,右孩子)…,最后,遍历ans数组,如果有一个的 left 和 right 都是-1,那么说明这个就是叶结点。
(2)代码:

1.#include <iostream>  
2.#include <stdio.h>  
3.using namespace std;  
4.  
5.struct Node  
6.{  
7.    int data;     
8.    int left;  
9.    int right;  
10.};  
11.int main()  
12.{  
13.    int n;  
14.    cin >> n;  
15.    getchar();   
16.    Node tree[15];    
17.    int checked[15] = {};   
18.    for(int i = 0;i < n;i++)  
19.    {  
20.        char l,r;     
21.        scanf("%c %c",&l,&r);  
22.        getchar();    
23.        if(l == '-')tree[i].left = -1;  
24.        else  
25.        {  
26.            tree[i].left = (l - '0');  
27.            checked[l - '0'] = 1;  
28.        }  
29.        if(r == '-')tree[i].right = -1;  
30.        else  
31.        {  
32.            tree[i].right = (r - '0');  
33.            checked[r - '0'] = 1;  
34.        }  
35.    }  
36.    int ans[15] = {};  
37.    for(int i = 0;i < n;i++)  
38.    {  
39.        if(checked[i] == 0)  
40.        {  
41.            ans[0] = i;   
42.            break;  
43.        }  
44.    }  
45.    int k = 1;   
46.    for(int i = 0;i < n;i++)   
47.    {  
48.        if(tree[ans[i]].left != -1)ans[k++] = tree[ans[i]].left;      
49.        if(tree[ans[i]].right != -1)ans[k++] = tree[ans[i]].right;    
50.    }  
51.    int flag = 0;  
52.    for(int i = 0;i < n;i++)  
53.    {  
54.        if(tree[ans[i]].left == -1 && tree[ans[i]].right == -1)  
55.        {  
56.            if(flag)cout << " ";    
57.            flag = 1;  
58.            cout << ans[i];  
59.        }  
60.    }  
61.    return 0;  
62.}  
3.二叉树的遍历:

(1)设计思路:
①首先先理解题目的意思。题目给出N行数组,每一行表示的是第N个节点的左右孩子的编码,若无左右孩子则标为0,即为叶节点。
②先定义一个数组将左右孩子编码输入,然后调用递归。由于题目已经规定根节点是1,因此先输出根节点,若当前访问节点的左右孩子不为0,则依次访问其左右孩子,输出先序序列。
(2)代码

1.#include <iostream>  
2.  
3.using namespace std;  
4.  
5.struct Node   
6.{  
7.    int lChild;   
8.    int rChild;  
9.};  
10.  
11.void Pre_traverse(Node nodes[], int root);  
12.  
13.int main()  
14.{  
15.    int N;   
16.    cin >> N;  
17.      
18.    Node nodes[N + 1];  
19.      
20.    for (int i = 1; i <= N; i++)  
21.    {  
22.        cin >> nodes[i].lChild >> nodes[i].rChild;  
23.    }  
24.      
25.    Pre_traverse(nodes, 1);  
26.}  
27.  
28.void Pre_traverse(Node nodes[], int root)  
29.{  
30.    if (root == 0)  
31.        return;  
32.      
33.    cout << root << " ";  
34.    Pre_traverse(nodes, nodes[root].lChild);  
35.    Pre_traverse(nodes, nodes[root].rChild);  
36.}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值