您的位置:首页 > 其它

一棵排序二叉树,令 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] 内的所有结点。

实现如下:

#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;
}
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 n2 null struct tree
相关文章推荐