1. 养成在三元运算符?:两边加括号的习惯。复杂算术表达式最好加括号。
2.报错Thread 1: EXC_BAD_ACCESS则重点检查指针或数组下标。如果用了递归,则首先检查递归出口,极有可能是过晚退出递归造成的越界访问。比如退出递归的条件中左右坐标的关系带不带等号,有时是相等一种退出、小于另一种退出。
3.把中间结果打印出来有助于定位错误。
4.preSequence函数通过计算左子树结点个数来递归确定根结点的值,依次存起来得到的就是先序遍历序列。结合从小到大的中序遍历序列就可唯一确定一棵树,进而对其层次遍历。
5.只看题目不知道怎么解时,可以从样例输出入手,倒推求解过程。
6.写的时候注意细节要比后面代码跑不了debug找错误高效得多。
7.书上的方法和代码很简洁,但没太懂,回头有机会再看。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#define MAXN 1005
using namespace std;
int N, a[MAXN];
struct node{
int data;
node *lchild;
node *rchild;
};
int preCount = 0;
int preOrder[MAXN];
void preSequence(int l, int r){
if (l == r) {//
preOrder[preCount++] = a[l];
return;
}
if (l > r) {//
return;
}
int n = r - l + 1;//一开始写成l - r + 1了,导致32行Thread 1: EXC_BAD_ACCESS
int h = 1;
while (true) {
if (pow(2, h) - 1 >= n) {
break;
}
h++;
}
int lastLayerCount = n - (pow(2, h-1) - 1);
int Lcount = (int)pow(2, h-2) - 1 + (lastLayerCount<(int)pow(2, h-2)?lastLayerCount:(int)pow(2, h-2));//后半部分加个括号才对
// printf("Lcount = %d\n", Lcount);
// printf("l + Lcount = %d\n", l+Lcount);
preOrder[preCount++] = a[l + Lcount];//Thread 1: EXC_BAD_ACCESS
preSequence(l, l + Lcount - 1);
preSequence(l + Lcount + 1, r);
}
node* create(int preL, int preR, int inL, int inR){//root要加&
if (preL > preR) {
return NULL;
}
int i;
for (i=inL; i<=inR; i++) {
if (a[i] == preOrder[preL]) {
break;
}
}
int Lcount = i - inL;
node *root = new node;
root->data = a[i];//Thread 1: EXC_BAD_ACCESS
root->lchild = create(preL+1, preL+Lcount, inL, i-1);
root->rchild = create(preL+Lcount+1, preR, i+1, inR);
return root;
}
int layerCount = 0;
int layerResult[MAXN];
void layerOrder(node *root){
if (root == NULL) {
return;
}
queue<node*> q;
while (!q.empty()) {
q.pop();
}
q.push(root);
while (!q.empty()) {
node *temp;
temp = q.front();
layerResult[layerCount++] = temp->data;
q.pop();
if (temp->lchild!=NULL) {
q.push(temp->lchild);
}
if (temp->rchild!=NULL) {
q.push(temp->rchild);
}
}
}
int main(int argc, const char * argv[]) {
scanf("%d", &N);
for (int i=0; i<N; i++) {
scanf("%d", &a[i]);
}
//确定先序遍历序列
sort(a, a+N);
preSequence(0, N-1);
// for (int i=0; i<N; i++) {//test
// printf("%d ", preOrder[i]);
// }
// printf("\n");
//由先序遍历序列和中序遍历序列建树
node* root = new node;
root = create(0, N-1, 0, N-1);
//层次遍历
layerOrder(root);
for (int i=0; i<N; i++) {
printf("%d", layerResult[i]);
if (i < N - 1) {
printf(" ");
}
}
return 0;
}
//Sample Input:
//10
//1 2 3 4 5 6 7 8 9 0
//Sample Output:
//6 3 8 1 5 7 9 0 2 4
//1.75小时,傍晚0.5小时debug,提交倒是一遍过了,但debug耗时过长。合计约2小时15分钟。太慢。多写多学。
//BST相关的题目似乎边界测试不多,基本上样例过了就能AC
//主要就是写的时候犯下的一些细节错误不好找,导致debug较长时间。最好写的时候就细心,争取写好之后一遍就能运行。