AVL树-如何跟踪树的高度? typedef和结构指针之间的区别

时间:2018-08-30 20:20:47

标签: c algorithm binary-tree avl-tree

代码应打印AVL树(平衡二叉树)。为什么我的代码不起作用?以下是this website和我的代码。区别仅在于节点的定义。

正确版本:

struct Node
{
    int key;
    struct Node *left;
    struct Node *right;
    int height;
};

struct Node* newNode(int key)
{
    struct Node* node = (struct Node*)
                        malloc(sizeof(struct Node));
    node->key   = key;
    node->left   = NULL;
    node->right  = NULL;
    node->height = 1;  // new node is initially added at leaf
    return(node);
}

我(不正确的)现代编译器优化中的代码修改版本:

typedef struct tree *T_tree;
struct tree {
    T_tree left;
    int key;
    T_tree right;
    int height;
    //int size = 0;
};
T_tree Tree (T_tree l, int k, T_tree r) {
    T_tree t = malloc(sizeof(*t));
    t-> left=l;
    t-> key=k;
    t->right = r;
    if (l==NULL &&  r == NULL) {
        t->height = 1;
    }
    /*
    else {
        t->height++;
    }*/
    return t;
}

使用main的完整正确代码:

#include<stdio.h>
#include<stdlib.h>

// An AVL tree node
struct Node
{
  int key;
  struct Node *left;
  struct Node *right;
  int height;
};

// A utility function to get maximum of two integers
int max(int a, int b);

// A utility function to get the height of the tree
int height(struct Node *N)
{
  if (N == NULL)
    return 0;
  return N->height;
}

// A utility function to get maximum of two integers
int max(int a, int b)
{
  return (a > b)? a : b;
}

/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct Node* newNode(int key)
{
  struct Node* node = (struct Node*)
                    malloc(sizeof(struct Node));
  node->key   = key;
  node->left   = NULL;
  node->right  = NULL;
  node->height = 1;  // new node is initially added at leaf
  return(node);
}

// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct Node *rightRotate(struct Node *y)
{
  struct Node *x = y->left;
  struct Node *T2 = x->right;

  // Perform rotation
  x->right = y;
  y->left = T2;

  // Update heights
  y->height = max(height(y->left), height(y->right))+1;
  x->height = max(height(x->left), height(x->right))+1;

  // Return new root
  return x;
}

// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct Node *leftRotate(struct Node *x)
{
  struct Node *y = x->right;
  struct Node *T2 = y->left;

  // Perform rotation
  y->left = x;
  x->right = T2;

  //  Update heights
  x->height = max(height(x->left), height(x->right))+1;
  y->height = max(height(y->left), height(y->right))+1;

  // Return new root
  return y;
}

// Get Balance factor of node N
int getBalance(struct Node *N)
{
  if (N == NULL)
      return 0;
  return height(N->left) - height(N->right);
}

// Recursive function to insert a key in the subtree rooted
// with node and returns the new root of the subtree.
struct Node* insert(struct Node* node, int key)
{
  /* 1.  Perform the normal BST insertion */
  if (node == NULL)
      return(newNode(key));

  if (key < node->key)
      node->left  = insert(node->left, key);
  else if (key > node->key)
      node->right = insert(node->right, key);
  else // Equal keys are not allowed in BST
      return node;

  /* 2. Update height of this ancestor node */
  node->height = 1 + max(height(node->left),
                       height(node->right));

  /* 3. Get the balance factor of this ancestor
      node to check whether this node became
      unbalanced */
  int balance = getBalance(node);

  // If this node becomes unbalanced, then
  // there are 4 cases

// Left Left Case
if (balance > 1 && key < node->left->key)
    return rightRotate(node);

// Right Right Case
if (balance < -1 && key > node->right->key)
    return leftRotate(node);

// Left Right Case
if (balance > 1 && key > node->left->key)
{
    node->left =  leftRotate(node->left);
    return rightRotate(node);
}

// Right Left Case
if (balance < -1 && key < node->right->key)
{
    node->right = rightRotate(node->right);
    return leftRotate(node);
}

/* return the (unchanged) node pointer */
return node;
}


// A utility function to print preorder traversal
// of the tree.
// The function also prints height of every node
void preOrder(struct Node *root)
{
    if(root != NULL)
    {
        printf("%d ", root->key);
        preOrder(root->left);
        preOrder(root->right);
    }
}

/* Drier program to test above function*/
int main()
{
  struct Node *root = NULL;

  /* Constructing tree given in the above figure */
  root = insert(root, 10);
  root = insert(root, 20);
  root = insert(root, 30);
  root = insert(root, 40);
  root = insert(root, 50);
  root = insert(root, 25);

  /* The constructed AVL Tree would be
            30
           /  \
         20   40
        /  \     \
       10  25    50
  */

  printf("Preorder traversal of the constructed AVL"
         " tree is \n");
  preOrder(root);

  return 0;
}

但这给出了错误的值吗?完整的错误代码,带有main:

#include <stdio.h>
#include <stdlib.h>

typedef struct tree *T_tree;
struct tree {
    T_tree left;
    int key;
    T_tree right;
    int height;
    //int size = 0;
};

T_tree Tree (T_tree l, int k, T_tree r) {
    T_tree t = malloc(sizeof(*t));
    t-> left=l;
    t-> key=k;
    t->right = r;
    if (l==NULL &&  r == NULL) {
        t->height = 1;
    }
    /*
    else {
        t->height++;
    }*/
return t;
}
//bigger of 2 integers:
int max(int a, int b) {
    if (a>=b) {
        return a;
    }
    else {
        return b;
    }
}

//actual height of tree
int height(T_tree t) {
    if (t==NULL)
        return 0;
    return t->height;
}

T_tree rightRotate(T_tree t) {
    T_tree t1 = t->left;
    T_tree t2 = t1->right;
    //rotation:
    t1->right = t;
    t->left = t2;
    //update heights:

    t->height = max(height(t->left), height(t->right))+1;
    t1->height = max(height(t1->left), height(t1->right))+1;

    return t1;
};
T_tree leftRotate(T_tree t) {
    T_tree t1 = t->right;
    T_tree t2 = t1->left;
//rotation:
t1->left = t;
t->right = t2;
//update heights:

t->height = max(height(t->left), height(t->right))+1;
t1->height = max(height(t1->left), height(t1->right))+1;

return t1;
};
//get balance factor of node N
int getBalance(T_tree node) {
    if (node == NULL)
        return 0;
    return height(node->left) - height(node->right);
}

T_tree insert(int key, T_tree t) {
    if (t==NULL) {
        return Tree(NULL, key, NULL);  
    }
    if (key < (t->key)) {
        Tree(insert(key,t->left), t->key, t->right);
    }
    else if (key > t->key) {
        return Tree(t->left, t->key, insert(key, t-> right));
    }
    else return Tree(t->left, key, t-> right);
    //update height of this node
    t->height = 1 + max(height(t->left), height(t->right));
    //is node becomed unbalanced?
    int balance = getBalance(t);
    if (balance >1 && key< t->left->key)
        return rightRotate(t);

    if (balance <-1 && key > t->right->key)
        return leftRotate(t);

    if (balance>1 && key > t->left->key) {
        t->left = leftRotate(t->left);
        return rightRotate(t);
    }
    if (balance < -1 && key < t->right->key) {
        t->right = rightRotate(t->right);
        return leftRotate(t);
    }
    return t;
}

void preOrder(T_tree root)
{
    if(root != NULL)
    {
        printf("%d ", root->key);
        preOrder(root->left);
        preOrder(root->right);
    }
}

int main(int argc, char const *argv[])
{
    T_tree t1 = NULL;
    t1 = insert(10, t1);
    t1 = insert(20, t1);
    t1 = insert(30, t1);
    t1 = insert(40, t1);
    t1 = insert(50, t1);
    t1 = insert(15, t1);
    preOrder(t1);
    return 0;
}

网站上的第一个版本为我提供了正确的值:

30 20 10 25 40 50

但是第二个,如果我在主函数的末尾加15,即使它是相同的打印函数,打印也会忽略它:

10 20 30 40 50

(还有另一个问题:为什么我需要cltr + ka来使代码可见,为什么?也许我应该在我使用的编辑器中设置4个空格宽的标签,这就是为什么粘贴无法完全按照应该吗?)

0 个答案:

没有答案