一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。 复杂度如果是O(n2)则不得分。
2012-05-19 21:59
681 查看
一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。
复杂度如果是O(n2)则不得分。
分析: 二叉排序树 具有(左子树< 根结点 < 右子树)性质
(1) 二叉排序树的构建过程中总是将新节点插入到叶子结点。
(2)二叉排序树的最小结点是该二叉排序树的最左边的结点。
(3)二叉排序树的最大结点是该二叉排序树的最右边的结点。
(4)查找首个大于给定值的结点(本题就是这个)。
分以下几种情况:
0.比较根结点的值与指定的值,若果根结点的值大于指定的值
则转 1, 否者(otherwise)转2.
1. 当根节点的值大于该值,
(a) 根结点的左子树为空,则根结点为所求。
(b)若左子树不为空,
(i)若左子树的最大结点的值 不大于 指定的值, 则根结点为所求。
(ii)若左子树的最大结点的值 大于 指定的值, 则所求结点在左子树中。将左子树的根节点替换根结点转0.
2. 当根结点值 不大于 指定的值时,
(a) 若根结点的右子树为空,则不存在, 返回NULL。
(b) 若根结点的右子树不为空, 在右子树中找到首个大于指定值得结点,并用这个结点替换根结点,然后转0.
其实,是一个循环不变式!时间复杂度应该小于 O(h*lgn), 因为
h 为树的高度,每一次根节点的比较,使树的规模至少减少一半(若果是平衡二叉排序树的话)。
(5)查找小于指定值的首个结点,方法类似于(4),关键找到那个循环不变式。//右子树的最小结点。
(6)补充, 查找值在指定区间[a, b] 内的所有结点。
实现如下:
复杂度如果是O(n2)则不得分。
分析: 二叉排序树 具有(左子树< 根结点 < 右子树)性质
(1) 二叉排序树的构建过程中总是将新节点插入到叶子结点。
(2)二叉排序树的最小结点是该二叉排序树的最左边的结点。
(3)二叉排序树的最大结点是该二叉排序树的最右边的结点。
(4)查找首个大于给定值的结点(本题就是这个)。
分以下几种情况:
0.比较根结点的值与指定的值,若果根结点的值大于指定的值
则转 1, 否者(otherwise)转2.
1. 当根节点的值大于该值,
(a) 根结点的左子树为空,则根结点为所求。
(b)若左子树不为空,
(i)若左子树的最大结点的值 不大于 指定的值, 则根结点为所求。
(ii)若左子树的最大结点的值 大于 指定的值, 则所求结点在左子树中。将左子树的根节点替换根结点转0.
2. 当根结点值 不大于 指定的值时,
(a) 若根结点的右子树为空,则不存在, 返回NULL。
(b) 若根结点的右子树不为空, 在右子树中找到首个大于指定值得结点,并用这个结点替换根结点,然后转0.
其实,是一个循环不变式!时间复杂度应该小于 O(h*lgn), 因为
h 为树的高度,每一次根节点的比较,使树的规模至少减少一半(若果是平衡二叉排序树的话)。
(5)查找小于指定值的首个结点,方法类似于(4),关键找到那个循环不变式。//右子树的最小结点。
(6)补充, 查找值在指定区间[a, b] 内的所有结点。
实现如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <assert.h> typedef int item_t; typedef struct node { item_t item; struct node *left; struct node *right; } node_t; typedef node_t * BSTree; typedef void (*printFuncPtr)(item_t item); void print(item_t item); BSTree createBinarySearchTree(BSTree *root, int size, item_t min, item_t max); void destroyBinarySearchTree(BSTree root); void postOrderTravel(BSTree root, printFuncPtr print); void midOrderTravel(BSTree root, printFuncPtr print); void preOrderTravel(BSTree root, printFuncPtr print); node_t *minNodeOfBinarySearchTree(BSTree root); node_t *maxNodeOfBinarySearchTree(BSTree root); node_t *findNearestBigNode(BSTree root, item_t item); node_t *findNearestSmallNode(BSTree root, item_t item); node_t *insertNode(BSTree *root, item_t item); int main() { int i; int len = 20; item_t minItem; item_t maxItem; item_t midItem; BSTree root = NULL; node_t *max_node_ptr; node_t *min_node_ptr; node_t *nearest_big_node_ptr; node_t *nearest_small_node_ptr; for(i=1; i<len; i++) { root = createBinarySearchTree(&root, i, 0, i); printf("root=%p\n", root); printf("<%d> midOrderTravel: ", i); midOrderTravel(root, print); printf("\n"); printf("<%d> preOrderTravel: ", i); preOrderTravel(root, print); printf("\n"); printf("<%d> postOrderTravel: ", i); postOrderTravel(root, print); printf("\n"); min_node_ptr = minNodeOfBinarySearchTree(root); max_node_ptr = maxNodeOfBinarySearchTree(root); if(min_node_ptr) { minItem = min_node_ptr->item; printf("The min node of the tree is %p : %d\n", min_node_ptr, minItem); } if(max_node_ptr) { maxItem = max_node_ptr->item; printf("The max node of the tree is %p : %d\n", max_node_ptr, maxItem); } midItem = (maxItem + minItem) >> 1; nearest_big_node_ptr = findNearestBigNode(root, midItem); if(nearest_big_node_ptr) { printf("find the nearest midItem (%d) big node %p: itsItem is %d \n", midItem, nearest_big_node_ptr, nearest_big_node_ptr->item); } nearest_small_node_ptr = findNearestSmallNode(root, midItem); if(nearest_small_node_ptr) { printf("find the nearest midItem (%d) small node %p: itsItem is %d \n", midItem, nearest_small_node_ptr, nearest_small_node_ptr->item); } printf("\n\n"); if(root) { destroyBinarySearchTree(root); root = NULL; } } return 0; } /* int getRandom(int min, int max) { assert(max>=min); srand((unsigned) time(NULL)); return min + rand()%(max-min); } */ void print(item_t item) { printf("%d ", item); } node_t *insertNode(BSTree *rootPtr, item_t item) { node_t *tmp = (node_t *) malloc(sizeof(node_t)); assert(tmp!=NULL); if(!tmp) fprintf(stderr, "error: There is not enough memory to use!!\n"); if(tmp) { tmp->item = item; tmp->left = NULL; tmp->right = NULL; } if(!*rootPtr) { if(tmp) *rootPtr = tmp; return tmp; } BSTree root = *rootPtr; while(root) { if(root->item >= item) { if(root->left == NULL) { //是叶子节点 root->left = tmp; return tmp; //break; } root = root->left; }else { if(root->right == NULL) { //是叶子节点 root->right = tmp; return tmp; //break; } root = root->right; } } } BSTree createBinarySearchTree(BSTree *rootPtr, int size, item_t min, item_t max) { int i; item_t item; printf("size= %d \n", size); srand((unsigned) time(NULL)); for(i=0; i<size; i++) { item = min + rand()%(max-min); printf("%d ", item); insertNode(rootPtr, item); } printf("\n"); return *rootPtr; } void destroyBinarySearchTree(BSTree root){ if(root) { //后续遍历 destroyBinarySearchTree(root->left); destroyBinarySearchTree(root->right); free(root); } /* if(root) { //中序遍历 destroyBinarySearchTree(root->left); node_t *right = root->right; free(root); destroyBinarySearchTree(right); } */ /* if(root){ //前序遍历 node_t *left = root->left; node_t *right = root->right; free(root); free(left); free(right); } */ } void preOrderTravel(BSTree root, printFuncPtr print) { if(root) { print(root->item); preOrderTravel(root->left, print); preOrderTravel(root->right, print); } } void midOrderTravel(BSTree root, printFuncPtr print) { if(root) { midOrderTravel(root->left, print); print(root->item); midOrderTravel(root->right, print); } } void postOrderTravel(BSTree root, printFuncPtr print) { if(root) { postOrderTravel(root->left, print); postOrderTravel(root->right, print); print(root->item); } } node_t *minNodeOfBinarySearchTree(BSTree root) { if(!root) return NULL; while(root){ if(root->left == NULL) return root; root = root->left; } } node_t *maxNodeOfBinarySearchTree(BSTree root) { if(!root) return NULL; while(root){ if(root->right == NULL) return root; root = root->right; } } node_t *findNearestBigNode(BSTree root, item_t item) { while(root) { if(root->item > item) { if(root->left) { node_t * maxNodePtr = maxNodeOfBinarySearchTree(root->left); if(maxNodePtr && maxNodePtr->item <= item) return root; root = root->left; }else { return root; } } else { if(root->right) { root = root->right; }else { return NULL; } } } } node_t *findNearestSmallNode(BSTree root, item_t item) { while(root) { if(root->item < item) { if(root->right) { node_t * minNodePtr = minNodeOfBinarySearchTree(root->right); if(minNodePtr && minNodePtr->item >= item) return root; root = root->right; }else { return root; } } else { if(root->left) { root = root->left; }else { return NULL; } } } }
相关文章推荐
- 一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。复杂度如果是O(n2)则不得分。
- 一棵排序二叉树(即二叉搜索树BST),令 f=(最大值+最小值)/2,设计一个算 //法,找出距离f值最近、大于f值的结点。复杂度如果是O(n2)则不得分。
- 一棵排序二叉树,令 f=(最大值+最小值)/2, 设计一个算法,找出距离f 值最近、大于f 值的结点。 复杂度如果是O(n2)则不得分
- 14、一棵排序二叉树,令 f=(最大值+最小值)/2, 设计一个算法,找出距离f值最近、大于f值的结点。
- 二叉排序树中,令f = (最大值+最小值) / 2,设计一个算法, 找出距离f值最近、大于f值的结点。复杂度不能为O(n2)。
- 一颗排序二叉树,令f=(最大值+最小值)/2,找出距离f值最近、大于f值的结点
- 如果字符串的一个子串(其长度大于 1)的各个字符均相同,则称之为等值子串。试设计一算法,求出串S中的最大等值子串 函数返回最大等值子串的长度,如果没有则返回1。 例如: 若S= “abc123abc1
- 13、设计一个算法,找出二叉树上任意两个结点的最近共同父结点。
- 任意给定一个大于等于10的整数A,请写一程序,以最小的时间复杂度找出比A小并且最接近A的一个整数B。要求:A的每位之和与B的每位之和相等 例:如果A=123 那么B=114
- 定义一个由整数组成的数组,然后输入一个整数X,如果X不在此数组中,返回小于X的最大数的位置i和大于X的最小数的位置j
- 设计一个最优算法来查找n个元素数组中的最大值和最小值
- 一个无序整数数组,数组元素大于5个,请用一种高效的算法找出其中最大的5个值.
- 【Java】给定有向图,设计一个算法,找出两个结点之间是否存在一条路径
- 有一棵二叉树,请设计一个算法,按照层次打印这棵二叉树。 给定二叉树的根结点root,请返回打印结果,
- 设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
- 堆的数据结构能够使得堆顶总是维持最大(对于大根堆)或最小(对于小根堆),给定一个数组,对这个数组进行建堆,则平均复杂度是多少?如果只是用堆的 push 操作,则一个大根堆依次输入 3,7,2,4,1,5,8 后,得到的堆的结构示意图是下述图表中的哪个?
- 设计一个算法,通过一趟遍历在单链表确定最大的结点
- 设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。
- 程序员面试金典——解题总结: 9.18高难度题 18.11给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出四条边都是黑色像素的最大子方阵。
- 设计一个算法,找出二叉树中某两个结点的第一个公共祖先.。不得将额外的结点存储在另外的数据结构中。注意:这不一定是二叉查找树。