簡體   English   中英

C語言中的非遞歸/迭代二進制搜索樹(作業)

[英]Nonrecursive/Iterative Binary Search Tree in C (Homework)

如何使用C中的迭代算法在二叉搜索樹中創建/刪除節點?

BST中的迭代插入和刪除

struct bst {
    int data;
    struct bst *left;
    struct bst *right;
};
typedef struct bst bst_t;

bst_t *get_new_node(int val)
{
    bst_t *node = (bst_t *) malloc(sizeof(bst_t));
    node->data = val;
    node->left = NULL;
    node->right= NULL;
    return node;
}  

bst_t *insert(bst_t *root, int val)
{   
    if(!root) return get_new_node(val);
    bst_t *prev = NULL, *ptr = root;
    char type = ' ';
    while(ptr) {
        prev = ptr;
        if(val < ptr->data) {
            ptr = ptr->left;
            type = 'l';
        } else {
            ptr = ptr->right;
            type = 'r';
        }
    }
    if(type == 'l') 
        prev->left  = get_new_node(val);
    else 
        prev->right = get_new_node(val);
    return root;
}  

int find_minimum_value(bst_t *ptr)
{
    int min = ptr ? ptr->data : 0;
    while(ptr) {                        
        if(ptr->data < min) min = ptr->data;
        if(ptr->left) {         
            ptr = ptr->left;            
        } else if(ptr->right) {
            ptr = ptr->right;
        } else ptr = NULL;
    }
    return min;
}  

bst_t *delete(bst_t *root, int val) 
{
    bst_t *prev = NULL, *ptr = root;
    char type = ' ';    
    while(ptr) {
        if(ptr->data == val) {          
            if(!ptr->left && !ptr->right) { // node to be removed has no children's
                if(ptr != root && prev) { // delete leaf node
                    if(type == 'l') 
                        prev->left = NULL;
                    else
                        prev->right = NULL;
                } else root = NULL; // deleted node is root
            } else if (ptr->left && ptr->right) { // node to be removed has two children's              
                ptr->data = find_minimum_value(ptr->right); // find minimum value from right subtree                    
                val = ptr->data;
                prev = ptr;
                ptr = ptr->right; // continue from right subtree delete min node 
                type = 'r';
                continue;               
            } else { // node to be removed has one children             
                if(ptr == root)  { // root with one child                   
                    root = root->left ? root->left : root->right;   
                } else { // subtree with one child
                    if(type == 'l') 
                        prev->left = ptr->left ? ptr->left : ptr->right;
                    else
                        prev->right = ptr->left ? ptr->left : ptr->right;   
                }           
            }
            free(ptr);
        }
        prev = ptr; 
        if(val < ptr->data) {           
            ptr = ptr->left;
            type = 'l';
        } else {
            ptr = ptr->right;
            type = 'r';
        }
    } 
    return root;
}

好貼。 只是一個建議。 我相信,在BST中找到最小值不必遍歷正確的子樹。 最小值必須在左子樹上或在節點本身上(如果左子樹為null)。 如果刪除了正確的子樹遍歷,則可以優化函數find_minimum_value。

int find_minimum_value(bst_t *ptr)
{
    while(ptr->left) {                               
        ptr = ptr->left;
    }
    return ptr->data;
} 

迭代插入:

struct tree_node *Insert_Element (struct tree_node *root, void *key, void *data) {
  struct tree_node *new_node, *node;

  node = root;

  do {    
    switch (compare(key, node->key)) {

      case -1: {
        if (node->left == NULL) {
          if ((new_node = create_node(key, data)) == NULL) {
            return NULL;
          }

          node->left = new_node;    
          return new_node;
        }

        node = node->left;
      } break;

      case 1: {
        if (node->right == NULL) {
          if ((new_node = create_node(key, data)) == NULL) {
            return NULL;
          }

          node->right = new_node;
          return new_node;
        }

        node = node->right;
      } break;

      default: {    
        return node;
      }
    }
  } while (node != NULL);

  return NULL;
}

在C語言中,您可以將樹中的指針intptr_tintptr_t類型,並對它們執行按位操作。

遍歷樹時,可以通過將其與遍歷的指針進行異或來存儲節點的“父”指針。 然后,可以通過使用修改后的指針對來自您的節點的地址進行異或來遍歷樹。

可以在http://sites.google.com/site/debforit/efficiency-binary-tree-traversal-with-two-pointers中找到這種傳統技術的有效示例

有了遍歷樹而無需遞歸的能力,您就可以基於遍歷樹來創建任何算法的迭代版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM