在第五章,我们学习了树这个数据结构,并且学习了其定义、遍历等操作,最后还学习了哈夫曼树。
一.树的遍历
树的遍历操作有以下三种:
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].rch); }
2。中序遍历(左孩子,根,右孩子)
void InOrderTravel(node t[], int x) { if(t[x].lch!=-1) InOrderTravel(t, t[x].lch); cout << t[x].name << " "; if(t[x].rch!=-1) InOrderTravel(t, t[x].rch); }
3。后序遍历(左孩子,右孩子,根)
void PostOrderTravel(node t[], int x) { if(t[x].lch!=-1) PostOrderTravel(t, t[x].lch); if(t[x].rch!=-1) PostOrderTravel(t, t[x].rch); cout << t[x].name << " "; }
二.实践遇到的问题。
针对“深入虎穴”这道编程题,看到输入格式的时候一开始有点懵,不知道怎么将这样的输入方式与树这个数据结构相契合。
但后来在老师带领下,明白了这个输入格式所对应的逻辑图。
然后建立结点。
typedef struct{ int doors;//门的数量 int *p;//p指向门的编号,将p看作是整型数组 }node;
然后主函数。
int main(){ node *a; int i,j,k,root; root = input(a); cout<< find(a,root)<<endl; return 0; }
输入和寻找是最大的问题,一开始在find函数中还把循环里的i<a[x]写成了i<=a[x],导致溢出,无论怎样测试都不对
int input(node *&a) { int n,i,x,j; bool *vi; cin>>n; a = new node[n+1];//为a数组申请空间。 vi= new bool[n+1]; for(i=1;i<=n;i++) {//初始化vi为false vi[i]=false; } for(i=1;i<=n;++i) { cin>> x; a[i].doors=x; a[i].p=new int[x]; for(j=0;j<x;++j)//new的空间为x,x的有效下标为0~x—1,故循环从0开始。 { cin>>a[i].p[j]; vi[a[i].p[j]]=true; } } //找出根在数组的下标 for(i=1;i<=n;++i) { if(!vi[i])break; } return i; } int find(node *a,int root) { //从a数组的下标向下搜索 queue<int>q;//定义用于待访问的门编号的队列。 //根编号入队 q.push(root); int x,i; //当队列不为空 //x = 出队 //x后的门编号入队 while(!q.empty()){ x=q.front(); q.pop(); for(i=0 ; i<a[x].doors;++i) { q.push(a[x].p[i]); } } //答案为x return x; }
做完这道题以后,就觉得自己分析问题不够清晰,思路有些混乱,然后做题过程中十分粗心、大意。
还需要多多练习,多敲代码,继续整理笔记,理清思路。