王道——数据结构——栈和队列(1)
王道——数据结构——树与二叉树(1)
王道——数据结构——树与二叉树(2)
王道——数据结构——树与二叉树(3)
本文为王道数据结构的第五章——树与二叉树的编程题。
运行软件:vscode
使用c++文件编写
本文所使用的树为《王道——数据结构——树与二叉树(1)》中建立的树
5、求以孩子兄弟表示法存储的森林的叶节点的个数
// 第五题 求叶子结点的个数,使用sum计数,孩子兄弟表示法的森林中没有左孩子的即为叶节点
void test5(CSTree T, int &sum){
if(T->firstchild == NULL)
sum++;
else
test5(T->firstchild, sum);
if(T->nextsibiling != NULL)
test5(T->nextsibiling, sum);
// 运行代码
// CSTree T;
// InitCSTree(T);
// buildTree(T);
// int sum = 0;
// test5(T, sum);
// printf("%d", sum);
}
6、以孩子兄弟链表为存储结构,请设计递归算法求树的深度
// 第六题 使用递归求树的深度,访问左子树,树的深度增加,访问右子树,树深度不增,当递归返回,树的深度减少时,判断当前深度是否是最大深度
void test6(CSTree T, int &high, int &highest){ // high 初始值为1,highest初始值为0
if(T->firstchild != NULL){
high++;
test6(T->firstchild, high, highest);
if(high>highest)
highest = high;
high--;
}
if(T->nextsibiling != NULL)
test6(T->nextsibiling, high, highest);
// 运行代码
// CSTree T;
// InitCSTree(T);
// buildTree(T);
// int highest = 0, high = 1;
// test6(T, high, highest);
// printf("%d", highest);
}
7、已知一棵树的层次序列及每个结点的度,编写算法构造此树的孩子-兄弟链表。
// 使用辅助结点数组,将结点序列放进结点数组里面
void test7(int data[], int du[], CSTree &T, int n){
int i, last = 0;
CSNode *point = new CSNode[20];
for(i = 0;i<n;i++){ // 放结点数组
point[i].data = data[i];
point[i].firstchild = point->nextsibiling = NULL;
}
for(i = 0; i< n; i++){
d = du[i]; // 第i个结点的度
if(d){
last++;
point[i].firstchild = point[last]; // 第i个结点的左孩子为第i个结点的第一个孩子
for(int j = 2;j<=d; j++){ // 将i结点的其他孩子作为右子树放在第i个结点的第一个孩子的右子树上
last++;
point[last-1].nextsibiling = piont[last]
}
}
}
T= point[0];
delete [] point;
}
6、试编写一个算法,判断给定的二叉树是否是二叉排列树
// 第六题 使用栈实现中序遍历该树,如果结果不是递增序列,不是二叉排序树
void test_BST6(BiTree T){
LinkStack S;
InitLinkStack(S);
BiTNode *p = T, *pre = NULL, *temp;
while(p||S != NULL){
if(p){
Push(S, p);
p = p->lchild;
}
else{
Pop(S, temp);
if(pre && pre->data.value > temp->data.value)
break;
pre = temp;
if(temp->rchild != NULL)
p = temp->rchild;
}
}
if(pre->data.value > temp->data.value)
printf("不是二叉排序树");
else
printf("是二叉排序树");
// 运行代码
// BiTree T;
// InitBiTree(T);
// buildTree(T);
// test_BST6(T);
}
7、设计一个算法,求出指定结点在给定二叉排序树中的层次
// 第七题 通过与根节点比较,大于根节点去右子树继续查找,层数加一,小于则去左子树查找,层数加一
int test_BST7(BiTree T, BiTNode *p){
if(T == NULL)
return -1;
int high = 1;
BiTNode *q = T;
while(q && p->data.value != q->data.value){
if(p->data.value < q->data.value)
q = q->lchild;
else
q = q->rchild;
high++;
}
return high;
// 运行代码
// BiTree T;
// InitBiTree(T);
// buildTree(T);
// int x;
// BiTNode *p = (BiTNode *)malloc(sizeof(BiTNode));
// printf("请输入你想查找的数值:");
// scanf("%d", &x);
// p->data.value = x;
// p->lchild = NULL;
// p->rchild = NULL;
// x = test_BST7(T, p);
// if(x == -1)
// printf("树为空");
// else
// printf("你查找的数值在二叉树的第 %d 层", x);
}
8、利用二叉树遍历的思想编写一个判断二叉树是否是平衡二叉树的算法
// 第八题 使用tag标记该树是否为平衡树,tag为1是平衡树,tag为0不是平衡树,
// 当树空或只有根节点时为平衡树,当左右子树差值大于一时不是平衡树
void test_BST8(BiTree T, int &high, int &tag){
int tagl = 1, tagr = 1, h = 0, hl=0, hr = 0;
if(T == NULL){
high = 0;
tag = 1;
}
else if(T->lchild == NULL && T->rchild == NULL){
high = 1;
tag =1;
}
else{
test_BST8(T->lchild, hl, tagl); // 对左子树遍历,并返回左子树高度,是否为平衡树
test_BST8(T->rchild, hr, tagr);
high = (hl>hr? hl: hr) +1;
if(abs(hl-hr) < 2)
tag = tagl && tagr;
else
tag =0;
}
// 运行代码
// BiTree T;
// InitBiTree(T);
// buildTree(T);
// int high = 0, tag = 1;
// test_BST8(T, high, tag);
// if(tag == 1)
// printf("是平衡二叉树");
// else
// printf("不是平衡二叉树");
}
9、设计一个算法,求出给定二叉树中最小和最大的关键字。
// 第九题 最小关键字为最左边的结点,最大关键字为最右边的结点
void test_BST9(BiTree T){
BiTNode *p = T;
while(p->lchild != NULL)
p = p->lchild;
printf("最小关键字为:%d", p->data.value);
p = T;
while(p->rchild != NULL)
p = p->rchild;
printf("\n最大关键字为:%d", p->data.value);
// 运行代码
// BiTree T;
// InitBiTree(T);
// buildTree(T);
// test_BST9(T);
}
10、设计一个算法,从小到大输出二叉排序树中所有值不小于k的关键字。
// 先找出最大的关键字,然后与k进行比较,如果小于k输出提示语句,否则使用栈实现右根左遍历并输出,直至小于k或栈空
void test_BST10(BiTree T, int k){
BiTNode *p = T, *temp;
while(p->rchild != NULL)
p = p->rchild;
if(p->data.value < k)
printf("树中所有节点均小于%d", k);
else{
LinkStack S;
p = T;
InitLinkStack(S);
while(p||S != NULL){
if(p){
Push(S, p);
p = p->rchild;
}
else{
Pop(S, temp);
if(temp->data.value < k)
break;
else{
printf("%d ", temp->data.value);
p = temp->lchild;
}
}
}
}
// 运行代码
// BiTree T;
// InitBiTree(T);
// buildTree(T);
// int x;
// printf("请输入一个数,你将得到该树中不小于这个数的所有数(从大到小):");
// scanf("%d", &x);
// test_BST10(T, x);
}
12、编写一个递归算法,在一颗有n个结点的、随机建立起来的二叉排序树上查找第k(1≤k≤n)小的元素,并返回指向该结点的指针。要求算法的平均时间复杂度为O(log2n)。二叉排序树的每个结点中除data、lchild、rchild等数据成员外,增加一个count成员,保存以该结点为根的子树上的结点数。
// 第十二题, 根节点左右孩子的count与k比较,如果左孩子的count大于k,指针指向左孩子继续比较,如果左孩子的count小于k,指针指向右孩子,k变为k-左孩子count-1
BiTNode *test_BST11(BiTree T, int k){
if(T->count < k)
return NULL;
BiTNode *p = T;
while(p->count == k-1){
if(p->lchild->count > k)
p = p->lchild;
else{
k = k-count-1;
p = p->rchild
}
}
return p;
}