霍夫曼编码的R语言实现
#各字符出现的频率
p <- c(0.4,0.2,0.1,0.2,0.1)
#编码矩阵
code_matrix <- matrix(NA, nrow=length(p), ncol=length(p)-1)
#记录每次合并得到的树的成员,列是第n次合并,行是成员,1代表合并后在一个子树
subtreeSet <- matrix(NA, nrow=length(p), ncol=length(p)-1)
#因为构建的是二叉树,所以n个字符一共会合并n-1次
for(i in 1:(length(p)-1)){
#将p从小到大排序,最小的两个合并
orderp <- order(p, decreasing=FALSE)
#本次合并中,第一个一个标记为0
code_matrix[orderp[1], i] <- 0
#与第一个同一子树的成员也标记为0
index1 <- which(subtreeSet[orderp[1],]==1)
for(j in index1){
index2 <- which(subtreeSet[,j]==1)
code_matrix[index2, i] <- 0
#更新子树成员
subtreeSet[index2, i] <- 1
}
#本次合并中,第二个标记为1
code_matrix[orderp[2], i] <- 1
#与第二个同一子树的成员也标记为1
index1 <- which(subtreeSet[orderp[2],]==1)
for(j in index1){
index2 <- which(subtreeSet[,j]==1)
code_matrix[index2, i] <- 1
#更新子树成员
subtreeSet[index2, i] <- 1
}
#更新子树成员
subtreeSet[orderp[c(1,2)], i] <- 1
#将第二个的频率跟新为第一个加第二个的(用第二个代表这个子树)
p[orderp[2]] <- p[orderp[2]] + p[orderp[1]]
#将第一个的频率设为1,保证其不参与后面的合并
p[orderp[1]] <- 1
}