本章学习了树和森林。因为之前对汉罗塔问题和费波纳兹数列问题理解不够透彻,自己对于递归思路不够清晰,再加上树的基本操作依赖于递归,所以感觉自己这一章学起来比较困难。这一章难点比较多,第一是新鲜的术语比较多,比如度,非终端结点,完全二叉树等等;第二是树的种类本身就比较多,树与树之间的基本操作遇到的问题可能不同;第三是树的基本操作基本上与递归有关。
上个星期第一次真正地在机房跟着老师写代码,感觉跟着老师的脚步,思路会比较清晰,并且在老师的讲解下,会引发自己对于问题的一些思考。
深入虎穴这道题的重点在于队列的理解和使用,在找到根结点并且建立好二叉树以后,问题就会变得更加简单。
#include<iostream> #include<algorithm> #include<cmath> #include<string> #include<string.h> #include<queue> using namespace std; typedef struct { int doors;//门的数量 int *p;//p指向具体们的编号,把p看作一个整型数组 }node; int input(node*&a) { int n, i; bool *vi = NULL;//定义布尔数组 cin >> n; a = new node[n+1];//创建a结构体数组 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; 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;//若门存在,则置1 } } //找出根在i数组的下标 for (i = 1; i <= n; i++) { if (!vi[i]) break; } return i; } int find(node*a, int root) { //从a数组的下标往下搜索 queue<int> q;//定义用于存放带访问的门编号和队列 int x, i; //根编号入队 q.push(root); //当队列不为空 出队一个元素,x->出队 while (!q.empty()) { x = q.front();//取队头元素 q.pop();//队头元素出队 for (i = 0; i < a[x].doors; i++) { q.push(a[x].p[i]); } } return x; } int main() { //变量的定义 node*a;//定义一个动态的整型数组 int root;//定义辅助变量以及root root = input(a); cout << find(a, root) << endl;//输出答案 system("pause"); return 0; }
下一道题是作业题里面的List Leaves。这一道题也比较简单,只要在层次遍历递归的条件中加一个中止条件就可以了。
#include<iostream> #include<queue> using namespace std; typedef struct { int name; 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);//层次遍历二叉树 system("pause"); return 0; } int BulidTree(node t[]) {//建立二叉树的函数 bool check[100] = { false };//置零 int n; char x, y; cin >> n; for (int i = 0; i < n; i++) {//循环输入x,y t[i].name = 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; queue<int> q; q.push(x); //根结点所在下标入栈 int che = 0; while (!q.empty()) { tmp = q.front(); q.pop(); if (tmp != -1) { if (t[tmp].lch == -1 && t[tmp].rch == -1) { if (che == 0) { cout << t[tmp].name; che = 1; } else cout << " " << t[tmp].name; } q.push(t[tmp].lch); q.push(t[tmp].rch); } } }
在上一阶段的学习中,前期做到了每天都打代码,然后也坚持看C语言的书,做SQL的题,但是上一个星期自己可能想放松,没能怎么花时间打代码,没能坚持,有点可惜。
下一阶段的学习中,要坚持打代码,复习好高数,争取自己把哈夫曼树和邻接表搞一遍,然后再把SQL的题目刷完。加油吧!莫懈怠!