数据结构学习笔记(四)
2016-04-07 22:49
519 查看
本篇主要是两个关于二叉搜索树的练习。
题目来源:浙江大学PATtest
那么怎样判断呢?可以发现如果一个数插入时经过了之前没有出现过的点,则这两棵树应该是不一样的。
debug的能力得到提高:通过打印+二分法。
**在程序中段插一个打印语句,把程序执行到那里的变量值打印出来看看。
如果正确,说明后半段错了;如果错误,说明前半段错了。
根据错误提示,根据程序的思路逐步运行,一步步排查错误出现的位置,在特定的地方进行打印输出。debug需要的是细心与耐心。**
代码:
题目来源:浙江大学PATtest
总结:
这道题刚开始自己想没有很好的思路来判断输入的序列是否构成同一棵二叉搜索树。关于要构造几颗树,输入一个序列构造一个然后再将两颗树比较,还是只要构造一颗,还是不用构造?比较好的解决办法是由第一个序列构造一颗,之后输入的序列里的数再与这颗搜索树比较,来判断。那么怎样判断呢?可以发现如果一个数插入时经过了之前没有出现过的点,则这两棵树应该是不一样的。
需要注意的地方:
建立树时注意要先生成根节点,然后后面的for循环要从i=1起,不然会出现段错误。debug的能力得到提高:通过打印+二分法。
**在程序中段插一个打印语句,把程序执行到那里的变量值打印出来看看。
如果正确,说明后半段错了;如果错误,说明前半段错了。
根据错误提示,根据程序的思路逐步运行,一步步排查错误出现的位置,在特定的地方进行打印输出。debug需要的是细心与耐心。**
代码:
/*判断是否是同一棵二叉搜索树:对于各种输入不同的序列,判断它们是否构成一样的二叉搜索树*/ #include <cstdio> #include <cstdlib> #include <stack> using namespace std; //二叉树的表示 typedef int DataType; typedef struct TreeNode *Tree; typedef struct TreeNode { DataType v; Tree left; Tree right; bool flag; //用于标记是否在之前经过 } treeNode; //二叉树的建立 Tree NewNode(int V) { Tree T = (Tree)malloc(sizeof(struct TreeNode)); T->flag = 0; T->left = NULL; T->right = NULL; T->v = V; return T; } Tree Insert(Tree T, int V) { // printf("V:%d ", V); if (!T) T = NewNode(V); else { if (V > T->v) T->right = Insert(T->right, V); else T->left = Insert(T->left, V); } return T; } Tree BuiltTree(int N) { Tree T; int V, i; scanf("%d", &V); //先建立一个头节点 T = NewNode(V); //特别注意这里i是从1开始的,因为头节点先建立了 for (i = 1; i < N; i++) { scanf("%d", &V); T = Insert(T, V); } // printf("built tree !\n"); return T; } /*void PreoderPrintTree(Tree T) { int temp; stack<int> S; // InitStack(S); while (T || !S.empty()) { while (T) { S.push(T->v); T = T->left; } if (!S.empty()) { temp = S.top(); S.pop(); printf("%d ", temp); printf("using stack to print\n"); T = T->right; } } }*/ /*void PreOrderPrintTree(Tree T) { if (!T) return; printf("%d", T->v); PreOrderPrintTree(T->left); PreOrderPrintTree(T->right); }*/ //判断输入系列与二叉树是否相等 //检查每次搜索中是否出现前面未出现的点 int check(Tree T, int V) { // printf("in \n"); //如果当前点已出现过,则递归找左右子树 if (T->flag) { if (V > T->v) { // printf("the right one\n"); return check(T->right, V); } else if (V < T->v) return check(T->left, V); else return 0; } //如果当前点之前没有出现过,且与序列中的当前点相等,则将flag标志置为1,表示经过该点 else { // printf("set right\n"); if (T->v == V) { T->flag = 1; return 1; } else return 0; } } int Judge(Tree T, int N) { int V, i, flag = 0; //该flag表示到目前为止,flag=0则一致,为1则不一致 scanf("%d", &V); if (T->v != V) { // printf("the 1st node not equal\n"); flag = 1; } else { // printf("1st's flag set to 1\n"); T->flag = 1; } for (i = 1; i < N; i++) { //特别注意这里i是从1开始的,因为头节点之前已经比较过了 scanf("%d", &V); if ((!flag) && (!check(T, V))) { // printf("not the same\n"); flag = 1; } //如果头节点一致而后面有没有出现过的点出现 } if (flag) return 0; else return 1; } void ResetTree(Tree T) { if (T->left) ResetTree(T->left); if (T->right) ResetTree(T->right); T->flag = 0; } void FreeTree(Tree T) { if (T->left) FreeTree(T->left); if (T->right) FreeTree(T->right); free(T); } int main() { Tree T; int N, L; scanf("%d", &N); while (N) { scanf("%d", &L); T = BuiltTree(N); // PreOrderPrintTree(T); for (int i = 0; i < L; i++) { if (Judge(T, N)) printf("Yes\n"); else printf("No\n"); ResetTree(T); //清除flag标志 } FreeTree(T); scanf("%d", &N); } return 0; }
相关文章推荐
- 数据结构(9):二叉树的遍历、构建以及显示(凹入法)
- 数据结构(8):二叉树的存储结构
- 第17章 二叉树,堆和优先队列(2/3)
- 数据结构(7):树的存储结构
- 数据结构学习-串(1)
- c语言数据结构(4)
- 链表-Linked List Cycle II(判断一个链表是否有环)
- C语言和数据结构的书单-再次推荐
- 数据结构双向循环链表的C语言实现(插入,查询,删除)
- 【数据结构与算法】LCA
- 顺序结构存储串实现串通配符匹配的算法
- 第17章 二叉树,堆和优先队列(1/3)
- 哈希表处理冲突的方法
- 【动态树】【Link Cut Tree】动态树的理解(入门)
- 数据结构之线性表代码实现顺序存储,链式存储,静态链表(选自大话数据结构)
- 在Hive 中如何使用符合数据结构 maps,array,structs
- 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结
- 数据结构与算法——二叉查找树类的C++实现
- 6.2 相关数据结构及其创建
- linux内核链表以及list_entry--linux内核数据结构(一)