в свое время писал пргу с кодами Хаффмана и Шеннона-Фано.
целиком выкладывать проблематично, код - ниже. Надеюсь, разберешься )
только там дерево не строится, а лишь кодируется каждый символ.
//--------------------------------------------------------------------------- #include <vcl.h> #include <stdio.h> #include <math.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; char abc[100] = ""; int j=0, l=1; AnsiString B[100][100]; int Check(char c){ for (int i=0; i<j; i++) if (c == abc[i]) return i+1; return 0; } void Sort(float * A, int j){ AnsiString tmp; int l = 1; do { int r = 0; if(A[l] < A[l+1]){ A[l] = A[l+1] + A[l]; A[l+1] = A[l] - A[l+1]; A[l] = A[l] - A[l+1]; do { tmp = B[l+1][r]; B[l+1][r] = B[l][r]; B[l][r] = tmp; r++; } while ((B[l][r] != "0") | (B[l+1][r] != "0")); } l++; } while (l < j); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Memo1->Text = ""; StringGrid1->Cells[0][0] = "Symbol"; StringGrid1->Cells[1][0] = "Probability"; StringGrid1->Cells[2][0] = "Code Shennon-Fano"; StringGrid1->Cells[3][0] = "Code Haffman"; StringGrid1->RowCount = 2; for (int i = 1; i < StringGrid1->ColCount; i++) { StringGrid1->Cells[0][i] = ""; StringGrid1->Cells[1][i] = ""; StringGrid1->Cells[2][i] = ""; StringGrid1->Cells[3][i] = ""; } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Memo1->Text = ""; StringGrid1->RowCount = 2; for (int i = 1; i < StringGrid1->RowCount; i++) { StringGrid1->Cells[0][i] = ""; StringGrid1->Cells[1][i] = ""; StringGrid1->Cells[2][i] = ""; StringGrid1->Cells[3][i] = ""; } char A[10000]; int i; if (OpenDialog1->Execute()){ Form1->Memo1->Lines->LoadFromFile(Form1->OpenDialog1->FileName); strcpy(A,Form1->Memo1->Text.c_str()); int Length = strlen(A); if (strlen(A)==1) ShowMessage ("Введите хотя бы два символа"); else for (i=0;i<strlen(A);i++) switch(A[i]){ case ' ': A[i]='_'; break; case 13: A[i]='_'; break; // /r case 10: for(j=i; j<strlen(A)-1; j++) A[j]=A[j+1]; break; // /n } char c; j = 0; for (int i=0;i<Length;i++){ c = A[i]; if (Check© == 0){ StringGrid1->RowCount += 1; abc[j] = c; j++; StringGrid1->Cells[1][j] = 1.0/Length; StringGrid1->Cells[0][j] = c; } else StringGrid1->Cells[1][Check©] = FloatToStr(StrToFloat(StringGrid1->Cells[1][Check©])+1.0/Length); } } float H = 0; for (i = 1; i <= j; i++) H -= StrToFloat(StringGrid1->Cells[1][i])*log(StrToFloat(StringGrid1->Cells[1][i]))/log(2.0); Label2->Caption = H; AnsiString tmp; bool mark; for(int i = 1; i <= j; i++) { //сортировка mark = true; for(int l = 1; l < j; l++) if(StringGrid1->Cells[1][l] < StringGrid1->Cells[1][l+1]){ tmp = StringGrid1->Cells[1][l+1]; StringGrid1->Cells[1][l+1] = StringGrid1->Cells[1][l]; StringGrid1->Cells[1][l] = tmp; tmp = StringGrid1->Cells[0][l+1]; StringGrid1->Cells[0][l+1] = StringGrid1->Cells[0][l]; StringGrid1->Cells[0][l] = tmp; mark = false; } if (mark) break; } float a1, a2, v; do { H = 0; for (i = 1; i <= j; i++) { tmp = StringGrid1->Cells[2][i]; v = StrToFloat(StringGrid1->Cells[1][i]); mark = false; for (l = 1; l <= j; l++) if ((StringGrid1->Cells[2][i] == StringGrid1->Cells[2][l])&(l!=i)) { H = 1; v += StrToFloat(StringGrid1->Cells[1][l]); mark = true; } if (mark) { a1 = 0, a2 = 0; for (int y = 1; y <= j; y++) if (StringGrid1->Cells[2][y] == tmp) if (a2 < 0.5*v) { a2 += StrToFloat(StringGrid1->Cells[1][y]); StringGrid1->Cells[2][y] = StringGrid1->Cells[2][y] + "1"; } else { a1 += StrToFloat(StringGrid1->Cells[1][y]); StringGrid1->Cells[2][y] = StringGrid1->Cells[2][y] + "0"; } } } } while (H != 0); float P[100] = {0}; for (i = 1; i <= j; i++) { P[i] = StrToFloat(StringGrid1->Cells[1][i]); B[i][0] = B[i][0] + i; for (int r = 1; r <=j; r++) B[i][r] = "0"; } do { P[j-1] = P[j-1] + P[j]; l = 0; do { StringGrid1->Cells[3][StrToInt(B[j][l])] = "0" + StringGrid1->Cells[3][StrToInt(B[j][l])]; l++; } while(B[j][l] != "0"); l = 0; do { StringGrid1->Cells[3][StrToInt(B[j-1][l])] = "1" + StringGrid1->Cells[3][StrToInt(B[j-1][l])]; l++; } while(B[j-1][l] != "0"); int a = 0; do { B[j-1][l] = B[j][a]; l++; a++; } while (B[j][a] != "0"); j--; Sort(P, j); } while (j > 1); a1 = 0; a2 = 0; for (int i = 1; i < StringGrid1->RowCount; i++) { a1 += strlen(StringGrid1->Cells[2][i].c_str()); a2 += strlen(StringGrid1->Cells[3][i].c_str()); } StringGrid1->Cells[2][StringGrid1->RowCount-1] = a1/(StringGrid1->RowCount-2); StringGrid1->Cells[3][StringGrid1->RowCount-1] = a2/(StringGrid1->RowCount-2); }