第五章随笔小结

第五章是大名鼎鼎的树,学的怎么说呢。。。

原理不难,操作啊,遍历啊,查找删除啥的也都基本掌握了。就感觉现在思维很难拓展发散开,像哈夫曼树感觉真是太神奇了。

还是先捋一下学了啥吧

首先存储还是借助线性工具来存储这种非线性的东西,主要通过数组下标啊,链表啊某种逻辑来实现树结点之间的链接。一般有1.双亲表示法2.孩子表示法3.孩子兄弟法。。。当然兵无常势,水无常形,表示法还有很多,需要自己在解决问题过程中选择合理的方法

然后遍历则有先、中、后、层次遍历四种遍历

void PreOrderTravel(node t[], int x)
{//先序遍历t[x]为根结点的树t
    cout << t[x].name << " ";
    if(t[x].lch!=-1) PreOrderTravel(t, t[x].lch);
    if(t[x].rch!=-1) PreOrderTravel(t, t[x].rch);
}

void InOrderTravel(node t[], int x)
{//中序遍历t[x]为根结点的树t
    if(t[x].lch!=-1) InOrderTravel(t, t[x].lch);
    cout << t[x].name << " ";
    if(t[x].rch!=-1) InOrderTravel(t, t[x].rch);
}

void PostOrderTravel(node t[], int x)
{//后序遍历t[x]为根结点的树t
    if(t[x].lch!=-1) PostOrderTravel(t, t[x].lch);
    if(t[x].rch!=-1) PostOrderTravel(t, t[x].rch);
    cout << t[x].name << " ";
}

层次

void levelOrderTraverse(node t[], int x)
{//层次遍历t[x]为根结点的树t
    int tmp;
    queue<int> q;
    q.push(x); //根结点所在下标入栈 

    while(!q.empty()){
        tmp = q.front();
        q.pop();
        if(tmp!=-1){
            cout << t[tmp].name << " ";
            q.push(t[tmp].lch);
            q.push(t[tmp].rch);
        }
    }
}

基于此可以解决许多问题。。。讲讲作业

首先是简单的遍历查找了,就是题目读了半天

Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a "-" will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each test case, print in one line all the leaves‘ indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

Sample Input:

8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

Sample Output:

4 1 5

#include<iostream>
#include<queue>

using namespace std;

typedef struct {
    int lch;
    int rch;
}node;

int BulidTree(node t[]);
void levelOrderTraverse(node t[], int x); //层次遍历 

int main()
{
    node t[100];
    int x;
    x = BulidTree(t);
    levelOrderTraverse(t, x);
    return 0;
}

int BulidTree(node t[])
{
    bool check[100] = { false };
    int n;
    char x, y;

    cin >> n;

    for (int i = 0; i < n; i++) {
        cin >> x >> y;

        if (x != ‘-‘) {
            t[i].lch = x - ‘0‘;
            check[t[i].lch] = true;
        }
        else
            t[i].lch = -1;

        if (y != ‘-‘) {
            t[i].rch = y - ‘0‘;
            check[t[i].rch] = true;
        }
        else
            t[i].rch = -1;
    }

    for (int i = 0; i < n; i++) {
        if (!check[i]) return i;
    }
}

void levelOrderTraverse(node t[], int x)
{//层次遍历t[x]为根结点的树t
    int tmp;
    int space=-1;
    queue<int> q;
    q.push(x); //根结点所在下标入栈 

    while (!q.empty()) {
        tmp = q.front();
        q.pop();
        if (tmp != -1) {
            if (t[tmp].lch == -1 && t[tmp].rch == -1){
                if(space==1)  cout<<" ";  //处理末尾空格
                cout<<tmp;
                space=1;
                }
            q.push(t[tmp].lch);
            q.push(t[tmp].rch);
        }
    }
}

没啥好说的。。。

然后又是一道天梯题,难度倒是还可以

著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报。已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门。每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门…… 他的手里有一张表格,是其他间谍帮他收集到的情报,他们记下了每扇门的编号,以及这扇门背后的每一条通路所到达的门的编号。007 发现不存在两条路通向同一扇门。

内线告诉他,情报就藏在迷宫的最深处。但是这个迷宫太大了,他需要你的帮助 —— 请编程帮他找出距离入口最远的那扇门。

输入格式:

输入首先在一行中给出正整数 N(<),是门的数量。最后 N 行,第 i 行(1)按以下格式描述编号为 i 的那扇门背后能通向的门:

K D[1] D[2] ... D[K]

其中 K 是通道的数量,其后是每扇门的编号。

输出格式:

在一行中输出距离入口最远的那扇门的编号。题目保证这样的结果是唯一的。

输入样例:

13
3 2 3 4
2 5 6
1 7
1 8
1 9
0
2 11 10
1 13
0
0
1 12
0
0

输出样例:

12

#include<iostream>
#include<queue>
using namespace std;

typedef struct{
    int doors;//门的数量
    int *p;//指向的门的编号序列
}node;

int input(node *,int );
int level(node *,int );

int main(){
    node *a;      //用于存储整棵树
    int n,root;
    cin>>n;
    a=new node[n+1];
    root = input(a, n); //输入,找根
    cout << level(a, root); //参差遍历
    return 0;
}
int input(node *a,int n){
  //读入n扇门的信息给a数组,返回根所在的门牌号
  int i,j;
  bool *vi;
  vi=new bool[n+1];
  for(int i=1;i<=n;i++){  //初始化vi数组的全部元素为false
      vi[i]=false;
  }
    for(int i=1;i<=n;i++){
        cin>>a[i].doors;
        if(a[i].doors!=0){
            a[i].p=new int[a[i].doors];  //申请门的空间
            for(int j=0;j<a[i].doors;j++){
                cin>>a[i].p[j];
                vi[a[i].p[j]]=true;
            }
        }
        else  a[i].p=NULL;  //doors为0
    }   //读入n扇门的信息
    for(int i=1;i<=n;i++){
        if(vi[i]!=true) return i;
    }
}

int level(node *a,int r){
    queue<int> q;
    int t,i;
    q.push(r);

    while(!q.empty()){
        t=q.front();
        q.pop();

        if(a[t].doors!=0){  //t号门后还有门,后面的门入队
            for(int i=0;i<a[t].doors;++i){
                q.push(a[t].p[i]);
            }
        }
    }
    return t;
}

感觉首先思路一定不能乱,对于这种较复杂的题注意把控好自己的操作和思维以及写出来代码的目的

其次对于数组下标的对应,越界,内存分配需要有一种野兽般的直觉,当然这点要多多练习。。。

上一章讲的思维线还在整合。。。看来要多找点题刷一刷了。新的目标是把自己的思维要发散开,不能打代码时思维太过僵硬或者总是拓展不开来。。。

原文地址:https://www.cnblogs.com/20181002925hh/p/10810393.html

时间: 2024-11-06 13:36:58

第五章随笔小结的相关文章

第五章学习小结

---恢复内容开始--- 第五章主要学习的是树与二叉树,有利用数组进行存储的顺序二叉树,也有利用链表进行存储的链式二叉树,在这个基础上又展开了二叉树的遍历. 二叉树的遍历分为前序遍历,中序遍历以及后序遍历,主要区别在于遍历的顺序不同. 前序遍历: (1)访问根结点. (2)前序遍历左子树. (3)前序遍历右子树 . 中序遍历: (1)中序遍历左子树 (2)访问根结点 (3)中序遍历右子树 后序遍历: 1)后序遍历左子树 (2)后序遍历右子树 (3)访问根结点 对于二叉树树的遍历的应用: 给定两棵

第五章内容小结

在第五章,我们学习了树这个数据结构,并且学习了其定义.遍历等操作,最后还学习了哈夫曼树. 一.树的遍历 树的遍历操作有以下三种: 1.先序遍历(根,左孩子,右孩子) void PreOrderTravel(node t[], int x) { cout << t[x].name << " "; if(t[x].lch!=-1) PreOrderTravel(t, t[x].lch); if(t[x].rch!=-1) PreOrderTravel(t, t[x]

《软件工程》-第五章随笔

本章主要讲述软件工程中将离散数学的方法用于解决软件工程领域的问题.形式化方法的开发可以追溯到20世纪50年代后期对编译技术的研究.也可以理解为,软件开发实际上就是把现实世界的需求映射成软件的模型化过程. 形式规约:软件规格说明是对软件系统对象,队象的操作方法,以及对象行为的描述.非形式的规格说明可用自然语言,图,表等形式描述. 形式证明与验证:主要包括模型检测和定理证明. 程序求精:将自动推理和形式化方法相结合,从抽象的形式规约推演出具体的面向计算机的程序代码的全过程. Z语言为以集合论和一阶谓

第五章随笔

本章继上一章的两人合作,深入讲解,介绍了团队的定义,模式,开发流程等,虽然有多种模式,也有多种开发流程,但这些各有其优缺点,有其适合的情况,所以在进行选择时,应该的更多的分析项目的需求,以及需要达到的目标,对质量的要求,是否需要在短时间内完成,是否需要尽早的得到用户的反馈,是否需要后期严格要求的维护等等,根据所做项目的特点,针对目前团队的人员能力水平,资源情况来确定具体的模式以及开发流程:实现队员能力的发挥,资源的合理利用,最终达到开发团队和用户的一致目标.

Android深度探索与HAL驱动开发(卷1)-- 第五章随笔

RISC(reduced instruction set computer)精简指令集计算机 简介 精简指令集,是计算机中央处理器的一种设计模式,也被称为RISC(Reduced Instruction Set Computer的缩写).[1] 这种设计思路对指令数目和寻址方式都做了精简,使其实现更容易,指令并行执行程度更好,编译器的效率更高.常用的精简指令集微处理器包括DECAlpha.ARC.ARM.AVR.MIPS.PA-RISC.PowerArchitecture(包括PowerPC)和

[Java Concurrency in Practice]二至五章小结

下面这个"并发技巧清单"列举了在第一部分(二至五章)中介绍的主要概念和规则. 可变状态是至关重要的(It's the mutable state,stupid). 所有的并发问题都可以归结为如何协调对并发状态的访问.可变状态越少,就越容易确保线程安全性. 尽量将域声明为final类型,除非需要它们是可变的. 不可变对象一定是线程安全的. 不可变对象能极大地降低并发编程的复杂性.它们更为简单而且安全,可以任意共享而无须使用加锁或保护性复制等机制. 封装有助于管理复杂性. 在编写线程安全的

Python基础教程(第五章 条件、循环和其他语句)

本文内容全部出自<Python基础教程>第二版,在此分享自己的学习之路. ______欢迎转载:http://www.cnblogs.com/Marlowes/p/5329066.html______ Created on Xu Hoo 读者学到这里估计都有点不耐烦了.好吧,这些数据结构什么的看起来都挺好,但还是没法用它们做什么事,对吧? 下面开始,进度会慢慢加快.前面已经介绍过了几种基本语句(print语句.import语句.赋值语句).在深入介绍条件语句和循环语句之前,我们先来看看这几种基

MiS603开发板 第五章 按钮去抖实验

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第五章 按钮去抖实验 按键的消抖,是指按键在闭合或松开的瞬间伴随着一连串的抖动,这样的抖动将直接影响设计系统的稳定性

MiS603开发板 第十五章 MCB DDR3内存测试

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第十五章 MCB DDR3内存测试 15.1 DDR3存储器模块及其测试 图像算法硬件最关键的一部分就是内存,内存保