tree_nodes<char> * huffman_tree(vector<tree_nodes<char> *> node) //根据权重建立huffman树; { if (node.size()>2) { double min_1=10000000,min_2=10000000; int min_pos_1=0,min_pos_2=0; for (int i=0; i<node.size(); i++) { if (min_1>node[i]->weight) { min_1=node[i]->weight; min_pos_1=i; } } for (int i=0; i<node.size(); i++) { if (min_2>node[i]->weight && i!=min_pos_1) { min_2=node[i]->weight; min_pos_2=i; } //找出两个最小的 } tree_nodes<char> * temp; temp=new tree_nodes<char>; temp->left_son=node[min_pos_1]; temp->right_son=node[min_pos_2]; temp->weight=node[min_pos_1]->weight+node[min_pos_2]->weight; node.push_back(temp); if (min_pos_1<min_pos_2) { node.erase(node.begin()+min_pos_1); node.erase(node.begin()+min_pos_2-1); } else { node.erase(node.begin()+min_pos_2); node.erase(node.begin()+min_pos_1-1); }; //把他俩权重弄一块搁后边 return huffman_tree(node);//把这俩指针弄成一个节点搁后边 其实那个权重也放在树里的data位置 } else { tree_nodes<char> * temp; temp=new tree_nodes<char>; temp->left_son=node[0]; temp->right_son=node[1]; temp->weight=node[0]->weight+node[1]->weight; return temp; } };
int main(){ char s[1000]; int len = 0; printf("input how many symbol\n"); scanf("%d", &len); char *sym = (char*)malloc((len + 1) * sizeof(char)); frequency **f = (frequency**)malloc(len * sizeof(frequency*)); int i = 0, j = 0; for(i = 0; i < len; i++){ f[i] = (frequency*)malloc(sizeof(frequency)); scanf("%s %d", &sym[i], &f[i]->weight); f[i]->symbol = &sym[i]; } printf("input the string need to encode\n"); scanf("%s", s); int slen = strlen(s); mybtree *huffman = huffman_tree(f, len, compare); char **table = (char**)malloc(len * sizeof(char*)); int l = log2(len) + 2; for(i = 0; i < len; i++){ table[i] = (char*)malloc(l * sizeof(char)); search_symbol(huffman, sym[i], table[i]); printf("%c: %s\n", sym[i], table[i]); } char *encode = (char*)malloc(l * slen * sizeof(char)); char *ptr = encode; for(i = 0; i < slen; i++){ // search symbol for(j = 0; j < len; j++){ if(s[i] == sym[j]){ ptr += sprintf(ptr, table[j]); break; } } } printf("%s: %s\n", s, encode); return 0; }
void zip_file(string file_name) { vector<tree_nodes<char>*> the_sons; tree_nodes<char>* the_tree; std::fstream in(file_name); std::istreambuf_iterator<char> beg(in), end; std::string the_file(beg, end); stat(the_file,counting); the_sons=build_sons(counting); the_tree=huffman_tree(the_sons); for (int i=0; i<128;i++) { if (counting[i]!=0) { std::string temp_code=""; code[i]=get_the_code((char) i , temp_code , the_tree); } } coding(code,the_file); }
int main(int argc, char* argv[]) { if (argc != 2) { std::cout << "usage: ./a7 file" << std::endl; return -1; } // get input text std::ifstream f(argv[1]); std::string s; std::vector<std::string> lines; while (!f.eof()) { s = ""; std::getline(f, s); if (!s.empty()) lines.push_back(s); } f.close(); // create a list of symbols std::vector<symbol> A; symbols(lines.begin(), lines.end(), std::back_inserter(A)); // process the list (student's code) bnode<symbol>* tree = huffman_tree(A.begin(), A.end()); // print dictionary print_dictionary(std::cout, tree); // free memory (student's code) release_tree(tree); // print dictionary print_dictionary(std::cout, tree); return 0; } // main
void huffman(const vector<double> &prob,btree<int> &T) { typedef list<huffman_tree> bosque_t; // Contiene todos los arboles bosque_t bosque; // Numero de caracteres del codigo int N = prob.size(); // Crear los arboles iniciales poniendolos en // una lista Los elementos de la lista contienen // la probabilidad de cada caracter y un arbol // con un solo nodo. Los nodos interiores del // arbol tienen un -1 (es solo para // consistencia) y las hojas tienen el indice // del caracter. (entre 0 y N-1) for (int j=0; j<N; j++) { // Agrega un nuevo elemento a la lista bosque_t::iterator htree = bosque.insert(bosque.begin(),huffman_tree()); htree->p = prob[j]; htree->T.insert(htree->T.begin(),j); } // Aqui empieza el algoritmo de Huffman. // Tmp va a contener el arbol combinado btree<int> Tmp; for (int j=0; j<N-1; j++) { // En la raiz de Tmp (que es un nodo interior) // ponemos un -1 (esto es solo para chequear). Tmp.insert(Tmp.begin(),-1); // Tmp_p es la probabilidad del arbol combinado // (la suma de las probabilidades de los dos subarboles) double Tmp_p = 0.0; // Para `k=0' toma el menor y lo pone en el // hijo izquierdo de la raiz de Tmp. Para `k=1' en el // hijo derecho. for (int k=0; k<2; k++) { // recorre el `bosque' (la lista de arboles) // busca el menor. `qmin' es un iterator al menor bosque_t::iterator q = bosque.begin(), qmin=q; while (q != bosque.end()) { if (q->p < qmin->p) qmin = q; q++; } // Asigna a `node' el hijo derecho o izquierdo // de la raiz de `Tmp' dependiendo de `k' btree<int>::iterator node = Tmp.begin(); node = (k==0 ? node.left() : node.right()); // Mueve todo el nodo que esta en `qmin' // al nodo correspondiente de `Tmp' Tmp.splice(node,qmin->T.begin()); // Acumula las probabilidades Tmp_p += qmin->p; // Elimina el arbol correspondiente del bosque. bosque.erase(qmin); } // Inserta el arbol combinado en el bosque bosque_t::iterator r = bosque.insert(bosque.begin(),huffman_tree()); // Mueve todo el arbol de `Tmp' al nodo // recien insertado r->T.splice(r->T.begin(),Tmp.begin()); // Pone la probabilidad en el elemento de la // lista r->p = Tmp_p; } // Debe haber quedado 1 solo elemento en la lista assert(bosque.size()==1); // Mueve todo el arbol que quedo a `T' T.clear(); T.splice(T.begin(),bosque.begin()->T.begin()); }