09、二叉树编程考点
1、二叉查找树的类型定义
typedef int DataType; //结点关键码的数据类型 typedef struct node { DataType data; //结点的数据值 struct node * lchild, *rchild; //指向左、右子女结点的指针 }BiTNode, *BiTree;
注意:BiTNode 等价于 struct node;*BiTree 等价于 struct node*。
2、判别给定的二叉树是否是二叉查找树
void binSearchTree (BiTNode *t, BiTNode * & pr, int & bs) { //t赋予根结点指针root,pr赋予NULL,bs赋予1 //t为当前子树根结点 //pr是当前子树根结点t的前驱指针 if(t != NULL && bs) { binSearchTree (t->lchild, pr,bs); //递归到左子树判断 if(pr == NULL) { pr = t; bs = 1; } else { if(t->data > pr->data) { pr = t; bs = 1; } else bs = 0; } if(bs) binSearchTree (t->rchild, pr,bs); //递归到右子树判断 } }
注意:
①、因为当前子树根结点t的前驱指针的值一直在改变,故采用的是指针的引用形式
②、指针的引用,相当于传递的是: 指针的指针,这样指针的数值是可以改变的;而单传递指针,不传递指针的引用,那么指针指向的数据是可以改变,而指针本身是不可以改变的 (示例)——简单讲:*&指针本身可变; **指针本身不变,仅指向的内容可变
fun(int * pA); // pA的数值在函数返回后不会变化 fun(int*& pA); // pA的数值在函数返回可能会发生变化,如果fun函数内部对pA赋值的话 void InitStack(LNode*& HS) { HS = NULL; // 函数返回后,HS就是NULL了 } void InitStack(LNode* HS) { HS = NULL; // 函数返回后,HS依然是传递进来的数值 }
3、递归实现从大到小输出所有不小于x的关键码
void Output(BSTNode *t,Datatype x){ if(t != NULL){ if(t->rchild != NULL) Output(t->rchild,x); if(t->data >= x) printf("%d",t->data); if(t->lchild != NULL && t->lchild->data >= x) Output(t->lchild,x); } }
4、时间复杂度为O(log2n),查找第k小的元素,增加一个count成员,保存以该结点为根的字数上的结点个数
BSTNOde *Search_small(BSTNode *t,int k) { if(k<1 || k>t->count) return NULL; if(t->lchild && t->lchild->count == k-1) return t; if(t->lchild && t->lchild->count > k-1) return Search_Small(t->lchild,k); if(!t->lchild) return Search_Small(t->rchild,k-1); if(t->lchild && t->lchild->count < k-1) return Search_Small(t->rchild, t->count - t->lchild->count - 1); }
5、求指定结点在二叉查找树中的层次
int level_Count(BSTree & T, BSTNode *p) { int level=0; BSTNode * q=T; if(q!=NULL) { level++; while(q!=NULL && q->data!=p->data){ if(q->data < p->data) q=q->rchild; else q = q->lchild; level++; } if(q==NULL) level=0; } return level; }
6、按折半查找判定树的生成方法构造二叉查找树
void Create_BestBST(BSTNode *&t, int low, int high, dataTYpe k[]){ if(low >high) t = NULL; else{ int m=(low +high)/2; t=new BSTNode; t->data=k[m]; Create_BestBST(t->lchild,low,m-1,k); Create_BestBST(t->lchild,m+1,high,k); } }
7、中序遍历二叉树,将结果存放于A[n]中
void InOrderTraverse(BSTNode *t,DataType A[].int &n){ if(t!=NULL){ InOrderTraverse(t->lchild,A,n); A[n++]=t->data; InOrderTraverse(t->rchild,A,n); } }
8、将n个值不同的元素A[n]插入到一个空的二叉查找树中
void BSTI(BSTree &T,DataTYpe A[],int n) { BSTNOde *p,*pr, *q; int 1; for(i=0; i<n; i++){ q=new BSTNode; q->data=A[i]; q->lchild=q->rchild=NULL; if(T == NULL) T=q; else{ p=T; pr=NULL; whi9le(p!=NULL && p->data !=q->data) { pr=p; if(p->data < q->data) p=p->rchild; else p=p->lchild; } if(p== NULL) if(q->data <pr->data) pr->lchild=q; else pr->rchild=q; } } }
9、向二叉查找树中插入一个元素,入树中已经有该元素,则将匹配结点中的count域的值加1,否则该元素作为新结点插入
void Insert1(BSTNode *&t, BSTNode *& pr, DataTYpe x) { BSTNode *p=t; while(p != NULL) { if(p->data != x){ pr=p; if(x < p->data) p=p->lchild; else p=p-rchild; } else(p->count++;return;) } BSTNode *s = new BSTNode; s->data=x;s->count=1; s->lchild=s->rchild=NULL; if(pr==NULL) t=s; else if(x <pr->data) pr->lchild=s; else r->rchild=s; };
10、二叉查找树上的插入
int Insert(BSTree& root, DataType x){ BSTNode *s,*p,*f; p=Search(root,x,f); if(p!=NULL) return 0; s=new BSTNode; if(s==NULL)return 0; s->data=x; s->lchild=NULL;s->rchils=NULL; if(f==NULL)root=s; else if(x<f->data) f->lchild=s; else f->rchild=s; return 1; }
11、后序遍历求二叉树的高度,并判断二叉树是否平衡
int HeightBalance(BiTNode *t ,int & height){ if(t != NULL) { int lh,rh; if(!heightBalance(t->lchild,lh)) return 0; if(!heightBalance(t->rchild,rh)) return 0; height=(lh>rh)?1+lh:1+rh; if(lh-rh)<=1 &&lh-rh>=-1) return 1; else return 0; } else(height=0;return 1;) }
12、前遍历的非递归算法
void PreOrder(BITNode *t){ while(t!=NULL){ printf("%d",p->data); PreOrder(t->lchild); t=t->rchild; } } void PreOrder(BITNode *t){ BITNode *p; BiTNode *S[n];top=0; S[top]=t; while(top !=1) { p=S[top]; top--; printf("%d",p->data); if(p->lchild!=NULL) { S[++top]=p->lchild; } if(p->rchild!=NULL) { S[++top]=p->rchild; } } }
13、求一颗二叉树中叶子结点的值及所在层次
void leave(BiTree &T,BiTNode *leaf[],int lev[],int&num){ BiTNode *p=T; num=0; if(p!=NULL) { int front=0,rear=0,last=1,level=1; BiTNode *Q[n]; rear++; Q[rear]=p; while(front !=rear){ front=(front+1)%n; p=Q[front]; } if(p->lchild==NULL && p->rchild==NULL) { leaf[num]=p; lev[num]=level; num++; } if(p->lchild!=NULL) { rear=(rear+1)%n; Q[rear]=p->lchild; } if(p->rchild!=NULL) { rear=(rear+1)%n; Q[rear]=p->rchild; } if(front==last){ last=rear; level++; } } }
14、计算二叉树各层结点个数。并返回二叉树的宽度
int Level_Nodes(BiTree& T,int count[],int& level){ BiTNode *p=T; if(p!=NULL) { level=0; int front=0,rear=0,last=1,num=0,max=0; BiTNode *Q[n]; rear++; Q[rear]=p; while(front !=rear){ front=(front+1)%n; p=Q[front]; num++; if(p->lchild!=NULL) { rear=(rear+1)%n; Q[rear]=p->lchild; } if(p->rchild!=NULL) { rear=(rear+1)%n; Q[rear]=p->rchild; } if(front==last){ last=rear; count[level++]=num; num=0; } } for(num=0;num<level;num++) if(count[num]>max) max=count[num]; return max; } return 0; }
15、判断二叉树是否是完全二叉树
int isComplete_BinTree(BiTree & T){ BiTNOde *p=T; if(p==NULL) return 1; BiTNode *[Q]; int front=0,rear=0; int flag=0; Q[rear]=p; rear=(rear+1)%n; while(front !=rear){ p=Q[front]; front=(front+1)%n; if(p==NULL) flag=1; else if(flag) return 0; else{ Q[rear]=p->lchild; rear=(rear+1)%n; Q[rear]=p->rchild; rear=(rear+1)%n; } } return 1; }
16、构造一棵二叉排序树的非递归算法
void CSBT (BStree T, Elemtype A[],int n) { for(i=1; i<=n; i++) { p=T; f=NULL; while(p!=NULL) if(p->data <A[i]) { f=p; p=p->rchild; } else if(p->data >A[i]) { f=p; p=p->lchild; } s=(BSTree)malloc(sizeof(BINode)); s->data=A[i]; s->lchild = NULL; s->rchild = NULL; if(f==NULL) T=s; else if(s->data < f->data) f->lchild = s; else f->rchild = s; } }
17、返回二叉树中序遍历的第一个结点
typedef struct pp { int d; srruct pp *l, *r; }Btree; Btree *inFirstNode(Btree *bt) { if(bt==NULL) return; p=bt; while(p->l!= NULL) p=p->l; return p; }
18、设计一个算法,求在前序序列中处于第k个位置的结点
typedef struct node *pointer; struct node{ datatype data; pointer Lchild,rchild; } typedef pointer bitreptr; void pre(bitreptr t; int k; bitreptr p) { if(t!=NULL) { i=i+1; if(i==k) { p=t; return(p); } pre(t->lchild, k, p); pre(t->rchild, k, p); } }
19、交换二叉树中所有结点左右子树的算法
typedef struct node { int data; struct node *lchild,*rchild; }bitree; void swapbitree(bitree *bt) { bitree *p; if(bt==0) return; swapbitree(bt->lchild); swapbitree(bt->rchild); p = bt->lchild; bt->lchild = bt->rchild; bt->rchild = p; }
20、三种遍历形式
前序遍历 思路:访问根节点--->前序遍历左子树--->前序遍历右子树 void PreOrderTraverse(BinTree T) { if(T==NULL) return; printf("%c ",T->data); /* 显示结点数据,可以更改为其它对结点操作 */ PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */ PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */ } 中序遍历 思路:中序遍历左子树--->访问根节点--->中序遍历右子树 void InOrderTraverse(BinTree T) { if(T==NULL) return; InOrderTraverse(T->lchild); /* 中序遍历左子树 */ printf("%c ",T->data); /* 显示结点数据,可以更改为其它对结点操作 */ InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */ } 后序遍历 思路:后序遍历左子树--->后序遍历右子树--->访问根节点 void PostOrderTraverse(BinTree T) { if(T==NULL) return; PostOrderTraverse(T->lchild); /* 先后序遍历左子树 */ PostOrderTraverse(T->rchild); /* 再后序遍历右子树 */ printf("%c ",T->data); /* 显示结点数据,可以更改为其它对结点操作 */ }
21、二叉树的递归遍历转变成非递归遍历
#include"stack.h" void InOrder(Bitree T){ stack S; initStack(S); BiTNode *p=T; do{ while(p!=NULL){ Push(S,p); p=p->lchild; } if(!IsEmpty(S)){ Pop(S,p); count<<p->data<<endl; p=p->rchild; } }while(p!=NULL || !IsEmpty(S)); };
22、层次序遍历
#include "queue.h" void levelOrder(Bitree T){ BiTNode *p; Queue Q; initQueue(Q); enQueue(Q,T); while(!IsEmpty(Q)){ deQueue(Q,p); cout<<p->data<<endl; if(p->lchild= NULL) enQueue(Q,p->lchild); if(p->rchild= NULL) enQueue(Q,p->rchild); } }
23、求指定结点的父结点
BiTNode * Parent(BiTNode * t, BITNode *p) { if(t == NULL) return NULL; if(t->lchild == p || t->rchild == p) return t; //找到,返回父结点 *t BiTNode * p = Parent(t->lchild,p); //递归在左子树中查找 if(p != NULL) return p; else return Parent(t->rchild,p); //递归在右子树中查找 }
24、统计二叉树中度为1的结点个数
int Degrees_1(BiTNode *t) { if(t == NULL) return 0; if(t->lchild != NULL && t->rchild == NULL || t->lchild == NULL && t->rchild != NULL) return 1+Degrees_1(t->lchild)+Degrees_1(t->rchild); else return Degrees_1(t->lchild)+Degrees_1(t->rchild); };
25、统计二叉树中度为2的结点个数
int Degrees_2(BiTNode *t) { if(t == NULL) return 0; if(t->lchild != NULL && t->rchild != NULL ) return 1+Degrees_2(t->lchild)+Degrees_2(t->rchild); else return Degrees_2(t->lchild)+Degrees_2(t->rchild); };
26、统计二叉树中度为0的结点个数
int leaves(BiTNode *t) { if(t == NULL) return 0; if(t->lchild == NULL && t->rchild == NULL) return 1; return leaves(t->lchild)+leaves(t->rchild); };
int NumofLeaf(*t) { if(t==NULL) return 0; if(!t->lchild && !t->rchild) { return 1; d1=NumofLeaf(t->lchild); d2=NumofLeaf(t->rchild) } return(d1+d2); }
27、计算二叉树中指定结点*p所在层次
int level(BiTNode * t ,BiTNode * p,int d) { if(t == NULL) return 0; if(t == p) return d; int SubTreeLevel; if(SubTreeLevel = level(t->lchild, p, d+1) > 0) return SubTreeLevel; else return level(t->rchild, p, d+1); }
28、从二叉树中删除所有的叶子结点
void defoliate(BiTNode *& t) { if(t == NULL) return ; if(t->lchild == NULL && t->rchild == NULL) { delete t; t = NULL; } else { defoliate(t->lchild); defoliate(t->rchild); } }
29、计算二叉树中各结点中的最大元素的值
void maxValue(BITNode * t, DataType & max) { if(t != NULL) { if(t->data > max) max = t->data; maxValue(t->lchild,max); maxValue(t->rchild,max); } }
30、求前序中第k个结点
BiTNode *Pre_Search_k(BiTNode *t, int &count, int k) { if(t != NULL){ count++; if(count == k) return t; BiTNode *p; if((p = Pre_Search_k(t->lchild, count, k)) != NULL) return p; return Pre_Search_k(t->rchild, count, k) } return NULL; }
31、编写二叉树中查找值为x的结点
int Find_Print(BiTNode *t,DataType x, DataType path[],int level, int & count){ if(t != NULL){ path[level-1] = t->data; if(t->data == x) {count=level; return 1;} if(Find_Print(t->lchild, x, path, level+1,count)) return 1; return Find_Print(t->rchild, x, path, level+1,count); } else return 0; }
32、构造二叉树
前序与中序构造二叉树 void createBinTree(BiTNode *&t, Datatype pre[], DataType in[], int s1,int t1,int s2, int t2){ int i; if(s1<=t1) { t=(*BITNode) malloc(sizeof(BiTNode)); t->data=pre[s1];t->lchild=t->rchild=NULL; for(i=s2; i<=t2; i++) if(in[i]==pre[s1]) break; createBinTree(t->lchild, pre, in, s1+1,s1+i-s2,s2,i-1); createBinTree(t->lchild, pre, in, s1+i-s2+1,t1,i+1,t2); } } } 后序与中序构造二叉树 void createBinTree(BiTNode *&t, Datatype post[], DataType in[], int s1,int t1,int s2, int t2){ if(s1<=t1) { t=(*BITNode) malloc(sizeof(BiTNode)); t->data=post[s1];t->lchild=t->rchild=NULL; int i; for(i=s2; i<=t2; i++) if(in[i]==post[t1]) break; createBinTree(t->lchild, post, in, s1+i-s2,t1-1,i+1,t2); createBinTree(t->lchild, post, in, s1,s1+i-s2-1,s2,i-1); }
33、建立二叉树的二叉链表表示
void ConstructTree(Datatype T[], int n, int i,BiTNode *&ptr) { if(i>=n) ptr=NULL; else{ ptr=(BiTNode *)malloc(sizeof(BiTNode)); ptr->data=T[i]; ConstructTree(T,n,2*i+1,ptr->lchild); ConstructTree(T,n,2*i+1,ptr->rchild); } }
34、完全二叉树转换成二叉树的顺序表示
void LinkList_to_Array(BiTNode *t, Datatype A[], int n, inti){ if(t==NULL) return; if(i>=n) { printf("数组空间不足"); exit(1); } A[i]=t; LinkList_to_Array(t->lchild,A,n,2*i+1); LinkList_to_Array(t->rchild,A,n,2*i+2); }
35、输出所有节点的数值以及所在层次
void nodePrint(BiTnode *t, int i) { if(t != NULL) { cout<<t->data<<","<<i<<end1=l; nodePrint(t->lchild,i+1); nodePrint(t->rchild,i+1); } }
36、写一个算法,统计出T所指向的二叉树的结点总数和叶子结点
void BiTreeNode(BTNode *T ,int &all, int &leaf) { if(T!= NULL) { BiTreeNode(T->lchild, all ,leaf); all++; if(T->lchild == NULL && T->rchild == NULL) leaf++; BiTreeNode(T->rchild,all,leaf); } }
37、求二叉树的高度
int depth(Bitree *t) { if(t==NULL) return 0; else{ hl=depth(t->lchild); hr=depth(t->rchild); if(hl>hr) return hl+1; else return hr+1; } }
38、求一棵二叉树中结点总数的算法
int NumofAll(Bitree *BT) { if(BT == NUll) return 0; else return NumofAll(BT->lchild)+NumofAll(BT->rchild)+1; }