在这种情况下如何避免使用全局变量

时间:2014-04-24 13:45:35

标签: r global-variables

以下代码尝试构建一个简单的二叉树。非叶节点包含左子节点Lchild'和一个正确的孩子' Rchild'叶节点不包含任何内容。节点是逐个生成的,首先是左侧分支,然后是右侧。节点按生成时间编号。节点信息(包括其Lchild和Rchild)被添加到BiTree以生长树。问题是,我怎样才能实现避免定义BiTree'和'我'全球化?因为它会导致一些

## rm(list=ls()) ## ANTI-SOCIAL
set.seed(1234)

##this part generate dataset
numVar <- 40  ##number of variables
numSamples <- 400  ##number of samples
Class <- sample(c(0,1), replace = 1, numSamples)  ##categorical outcome as '0' or '1'
predictor <- matrix( sample(c(-1,0,1), replace=1, numSamples*numVar), ncol=numVar)
data <- data.frame(predictor, Class)

##BiTree is a list storing a nodes information, reprenting a tree, defined as global
BiTree <- array( list(NULL), dim = 15 )

##set i as global variable to store the ID of each node on the tree, defiend as global
i <- 1

##function to create a tree
##parameter 'root' is the ID of root node for each sub-tree
createTree <- function( data, root )
{


   force( root ) ##without this the result will be wrong

   ##stop grow the sub-tree if data size is smaller than 10
   if( (nrow(data) <= 10 ) )  { i <<- i + 1; return(); }

   ##seperate the data into two parts to grow left-sub-tree and right-sub-tree
   index.P1 <- 1:floor( nrow( data )/2 )
   index.P2 <- !index.P1
   data.P1 <- data[ index.P1,  ]
   data.P2 <- data[ index.P2,  ]

   ##NOTE HERE: result will differ with or without execute any of the following call of root


   ##i records the ID of node in the tree. it increments after one new node is added to     the tree
   i <<- i + 1

   ##record node ID for left child of the root
   BiTree[[ root ]]$Lchild <<- i

   ##create left branch
   createTree( data.P1, i )

   ##record node ID for right child of the root
   BiTree[[ root ]]$Rchild <<- i

   ##create right branch
   createTree( data.P2, i )
}

createTree( data, 1 )

1 个答案:

答案 0 :(得分:0)

如果它只是一个编程练习并且您希望使用纯R,那么唯一的另一种方法是使用环境。没有其他R对象通过“引用”传递,即在函数调用后对args所做的更改是“可见的”。

这是一个非常原始的环境BST实现,模仿动态分配的内存和指针的使用。我不建议在实践中使用它。这个解决方案只是为了好玩。

如果您需要访问“有序集”容器,则应该在RCpp程序中使用STL的set

BST的“学校”实施

  # assumption: elements can be compared with < and ==

  # Each node will be represented by a list with 3 elements
  # (object, left, right)
  # instead of pointer we will use strings

  # note that the maximal number of nodes
  # that can be created is restricted

  # create a new empty tree
  bst_new <- function() {
     e <- new.env()
     e$root <- NULL
     e$last <- 0L # this will emulate a "heap"
     class(e) <- 'bst'
     e
  }


  # insert an element
  # duplicates are ignored
  bst_insert <- function(bst, val) {
     stopifnot(is.environment(bst), class(bst) == 'bst')

     if (is.null(bst$root)) {
        bst$root <- as.character(bst$last)
        bst$last <- bst$last + 1L
        assign(bst$root, list(val, NULL, NULL), bst)
     }
     else {
        cur_id <- bst$root
        repeat {
           cur_node <- get(cur_id, bst)
           if (val == cur_node[[1]])
              return(invisible(NULL)) # ignore
           else if (val < cur_node[[1]]) {
              if (is.null(cur_node[[2]])) {
                 cur_node[[2]] <- as.character(bst$last)
                 assign(cur_id, cur_node, bst)
                 bst$last <- bst$last + 1L
                 assign(cur_node[[2]], list(val, NULL, NULL), bst)
                 return(invisible(NULL))
              }
              else {
                 cur_id <- cur_node[[2]]
              }
           }
           else {
              if (is.null(cur_node[[3]])) {
                 cur_node[[3]] <- as.character(bst$last)
                 assign(cur_id, cur_node, bst)
                 bst$last <- bst$last + 1L
                 assign(cur_node[[3]], list(val, NULL, NULL), bst)
                 return(invisible(NULL))
              }
              else {
                 cur_id <- cur_node[[3]]
              }
           }
        }
     }
  }

  # print all elems, in order
  bst_print <- function(bst) # or print.bst
  {
     stopifnot(is.environment(bst), class(bst) == 'bst')

     bst_print_tmp <- function(bst, id_node) {
        if (is.null(id_node)) return(invisible(NULL))

        cur_node <- get(as.character(id_node), envir=bst)
        bst_print_tmp(bst, cur_node[[2]]) # left
        print(cur_node[[1]]) # this
        bst_print_tmp(bst, cur_node[[3]]) # right
     }

     bst_print_tmp(bst, bst$root)
     invisible(NULL)
  }


  tree <- bst_new()
  bst_insert(tree, 3)
  bst_insert(tree, 5)
  bst_insert(tree, 1)
  bst_insert(tree, 2)
  bst_insert(tree, 8)
  bst_insert(tree, 7)
  bst_print(tree)

## [1] 1
## [1] 2
## [1] 3
## [1] 5
## [1] 7
## [1] 8