碎碎念
最近的数据结构上课真的很难听懂,听懂了的也很容易忘,但老师说多做题是关键,“不要看书学习,要先做题再看书”.(。•ˇ‸•。)…
例题一:并查集森林和数组的构建
请给出下列操作序列的运算结果,其中M是合并,F是查找:M(1,2),M(3,4),M(3,5),M(1,7),M(3,6),M(8,9),M(1,8),M(3,10),M(3,11),M(3,12),M(3,13),M(14,15),M(16,17),M(14,16),M(1,3),M(1,14)
根据树的高度执行合并(高度高的树作为根节点):
1)画出并查集森林的构造过程。
2)画出存储该并查集的数组。
3)写出F(17)的查找过程。
解析:M为合并,M(1,2)就是把2这个节点粘到1上面,这样不停的粘之后出现了这样的并查集森林
第二问要求并查集数组,并查集数组就是把每一个元素的直接父节点存储在该元素的存储单元中。
第三问F(17),我的理解就是在数组里求17的父节点? 17->16->14->1
例题二:二分查找判定树,ASL求法
画出对长度为10的有序表进行二分查找的一棵判定树,并求出其等概率时查找成功的平均查找长度。
长度为10的有序表进行二分查找,首先查找中间元素,为5(取中间或者中间偏小的那个数),所以5是所有节点的父节点,也就是说从5这里一分为二个树,1-4为一个树,6-10为一个树。再以此为例往下分。
ASL的求法,在等概率的条件下直接看路径长度,别忘了除以十 (11+22+34+43)/10=2.9
例题三:二分法查找
编写一个函数,利用二分查找算法在一个有序表中插入一个元素x,并且保持表的有序性。
【解答】依题意,现在有序表r中利用二分查找算法查找关键字值等于或小于x的结点,mid指向正好等于x的结点或low指向关键字正好大于x的结点,然后采用移动法插入x结点即可。
mid, inplace, find=0; while(low<=high && !find) { mid=(low+high) / 2; if(x<r[mid].key) high=mid-1; else if(x>r[mid].key) low=mid+1; else { i=mid; find=1;}} if(find) inplace=mid; else inplace=low; for(int i=n; i>=inplace; i--) r[i+1].key=r[i].key; r[inplace].key=x;} ```
例题四:二叉搜索树
设数据集合d={1,12,5,8,3,10,7,13,9},试完成下列各题。
(1) 依次取d中各数据,构造一个二叉排序树bt;
(2) 如何依据此二叉树,得到d的有序序列?
(3) 画出在二叉树中删除“12”后的树结构。
二叉排序树又称二叉查找树:
定义:根结点的值大于所有左子树结点的值,小于所有右子树结点的值。(也就是说左子树比它小,右子树比它大)且左右子树也分别为二叉排序树。
性质:中序遍历的序列刚好为一组从小到大排列的序列。(1)从1开始,放1,再看12,比1大,所以放在1的右边,以此类推。 (2)就是中序遍历 (3)找12的中序遍历的前驱节点代替它
例题五:二叉排序树找公共祖先
编写算法在二叉排序树上找出任意两个不同结点的最近公共祖先。
基本思路:做算法题,应该先把基本思路,不同情况列出来
【解答】假设二叉树排序树的根结点为root,任意两结点为A和B(A<B),则有如下四种情况。
- 若A为根结点,则A为公共祖先
- 若A->data < root->data, 且B->data > root->data, 则root为公共祖先。
- 若A->data < root->data, 且B->data < root->data, 则到左子树查找。
- 若A->data > root->data, 且B->data > root->data, 则到右子树查找。
if(root==A || root==B) return root; if((A->data<root->data) && (root->data< B->data)) return root; else if((A->data<root->data) && (B->data < root->data)) return Ancestor(root->left, A, B); else return Ancestor(root->right, A, B);} ```
例题六:AVL平衡二叉树
将整数序列{4,5,7,2,1,3,6}中的数依次插入到一棵空的平衡二叉树中,试构造相应的平衡二叉树。高度为5的AVL数最多有多少个节点,最少有多少个节点?
先来回忆一下AVL树的旋转
这一题的解答:
最终答案