数据结构学习笔记8 树 课后习题
2014-03-03 22:20
295 查看
4.29参考了答案
#include <STDIO.H> #include <stdlib.h> typedef struct Node * RanTree; typedef RanTree Position; struct Node { int Data; RanTree Left; RanTree Right; }; RanTree SearchTree(int N); RanTree RandomSearchTree(int Low,int Upper); int RandomNum(int Low,int Upper); void ListDir(RanTree T,int Depth,int Flag); void PrintName(RanTree T,int Depth,int Flag); RanTree SearchTree(int N) { RanTree H; H=RandomSearchTree(1,N); return H; } RanTree RandomSearchTree(int Low,int Upper) { Position P; P=NULL;//这里对P赋值是为了对树叶的左右子树赋值为NULL if (Low<=Upper) { P=(Position)malloc(sizeof(struct Node)); P->Data=RandomNum(Low,Upper); P->Left=RandomSearchTree(Low,P->Data-1); P->Right=RandomSearchTree(P->Data+1,Upper); } return P; } int RandomNum(int Low,int Upper) { return (rand() % (Upper-Low+1))+ Low;//产生Low和Upper之间的随机数 } void ListDir(RanTree T,int Depth,int Flag) { if (T!=NULL) { PrintName(T,Depth,Flag); RanTree T1,T2; T1=T->Left; ListDir(T1,++Depth,1);//这里处理深度问题 T2=T->Right; ListDir(T2,Depth,2); } } void PrintName(RanTree T,int Depth,int Flag) { int i; for (i=0;i<Depth;i++) printf(" "); if(Flag==1) printf("Left:"); else if(Flag==2) printf("Right:"); else printf("ROOT:"); printf("%d\n",T->Data); } int main(void) { int N=15; RanTree H; H=SearchTree(N); ListDir(H,0,0); return 0; }运行时间为O(N)
4.30求高度为H的最小的***L树
妈蛋啊,要哭了。竟然花了将近4个小时,1.5h用于构建***L树,2.5h用于赋值这个图可以有助于理解最小的***L树。
#include <stdio.h> #include <STDLIB.H> #include "H_height_minimum_***L.h" #define H 5 struct AvlNode { int Data; AvlTree Left; AvlTree Right; int TreeHeight; }; void ListDirectory(AvlTree T)//先序遍历打印树 { ListDir(T,0,0); } void ListDir(AvlTree T,int Height,int Flag) { if (T!=NULL) { PrintName(T,Height,Flag); Position T1,T2; T1=T->Left; ListDir(T1,++Height,1);//这里处理深度问题 T2=T->Right; ListDir(T2,Height,2); } } void PrintName(AvlTree T,int Height,int Flag) { int i; for (i=0;i<Height;i++) printf(" "); if(Flag==1) printf("Left:"); else if(Flag==2) printf("Right:"); else printf("ROOT:"); printf("%d DATA=%d\n",T->TreeHeight,T->Data); } AvlTree Hminimun***L(int Height,AvlTree P)//计算树各个节点的高度 { if(Height>=0) { Position tmpCell; tmpCell=(Position)malloc(sizeof(struct AvlNode)); tmpCell->TreeHeight=Height; tmpCell->Right=NULL; tmpCell->Left=NULL; if(Height) { tmpCell->Right=Hminimun***L(Height-1,P);//递归调用 tmpCell->Left=Hminimun***L(Height-2,P); if (Height==1) { tmpCell->Left=NULL;//对于左子树的创建时Height-2。当Height=1时在Hminimum***L函数中不符合判断条件,就没有对左子树赋值NULL。这里加入 } /*tmpCell->Left->Right=NULL; tmpCell->Left->Left=NULL; tmpCell->Right->Right=NULL; tmpCell->Right->Left=NULL;*/ } P=tmpCell; //free(tmpCell);这里不能free,不然新创建的节点就不存在了 return P; } } AvlTree InsertData(AvlTree Tree,int i)// { if(Tree->Left!=NULL) { Tree->Left=InsertData(Tree->Left,i);//这里的赋值应该是针对Tree->Left i=MaxTree(Tree);//这里处理数据,为了不利用全局变量。每次调用函数之后进行数据插入之后,应当把当前树的最大值返回给father,便于后面的father节点赋值&右兄弟赋值 } /*else 这里不需要else。最小的***L树在当前节点可能不存在左子树,但是当前节点一定需要赋值Data {*/ Tree->Data=++i; if (Tree->Right!=NULL)//判断右子树的情况,进行赋值 { Tree->Right=InsertData(Tree->Right,i); i=MaxTree(Tree); } /*}*/ return Tree; } int MaxTree(AvlTree Tree) { int i,j,k; i=Tree->Data; if (Tree->Right) { j=MaxTree(Tree->Right); } if (Tree->Left) { k=MaxTree(Tree->Left); } i=i>j?i:j; i=i>k?i:k; return i; } int main(void) { AvlTree H_min_***L; //H_min_***L=(Position)malloc(sizeof(struct AvlNode)); H_min_***L=Hminimun***L(H,H_min_***L); H_min_***L=InsertData(H_min_***L,0); ListDirectory(H_min_***L); return 0; }以上程序中,我在编写时候,怎么处理 i 这个数据花了很长时间。当时不想用全局变量,选择了当前树的最大值。其实,还有一个很简便的方法:用指针NodeData指向 i ,每次调用 i 都是*NodeData代替。这样就不存在不同层次递归调用 i 的当前值不同的问题。
4.31生成高度为H具有关键字2^(H+1)-1的理想二叉查找树
毫无疑问,这个理想的二叉查找树除叶子以外的所有节点都应该是Full Node,即每个节点有两个儿子。而且我们可以设定是编程之前已知树的形状,只需建立这个树并顺序插入数据即可。即,这个题目主要做的是4.30中为每个节点赋值的工作。AvlTree H_***L(int HEIGHT,int *i_pointer)//计算树各个节点的高度 { Position tmpCell; tmpCell=NULL; if(HEIGHT>=0) { tmpCell=(Position)malloc(sizeof(struct AvlNode)); tmpCell->Left=H_***L(HEIGHT-1,i_pointer); tmpCell->TreeHeight=HEIGHT; tmpCell->Data=++*i_pointer; tmpCell->Right=H_***L(HEIGHT-1,i_pointer);//递归调用 } return tmpCell; } int main(void) { AvlTree H_Tree; int i=0; H_Tree=H_***L(5,&i); ListDirectory(H_Tree); return 0; }
PS:基本上之前看的书,都做了课后习题。有些是自己写,有些参考了课后答案。但是进度太慢。之后不会再做课后习题,只会实现书上demo。然后多看书,在项目中应用所学。
相关文章推荐
- 数据结构复习笔记七:动态存储管理
- 数据结构之链表1(单项链表)
- Python数据结构:序列(列表[]、元组())与映射(字典{})语法总结
- [数据结构]栈
- [数据结构]二叉树
- 归并排序(迭代实现)- 数据结构和算法95
- linux虚拟文件系统数据结构
- FFmpeg数据结构解释(AVCodecContext,AVStream,AVFormatContext)
- 数据结构和算法为什么这么重要?
- Python笔记——基本数据结构:列表、元组及字典
- 数据结构 -- 查找之 二分法查找
- 常用的内部排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 数据结构:线性表的链式存储(单向链表)--Java实现
- 数据结构--循环双向链表
- 数据结构:线性表的顺序存储--Java实现
- 算法基础(五):二叉树(基础)
- 九度OJ 1505 两个链表的第一个公共结点 【数据结构】
- 九度OJ 1505 两个链表的第一个公共结点 【数据结构】
- 神一般的数据结构--可持久化treap