Advertisement
Guest User

Untitled

a guest
Jan 8th, 2021
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 26.24 KB | None | 0 0
  1.  
  2. #include<stdio.h>
  3.  
  4. //  Функция подсчитывает количество каждого из 256 символов в исходном
  5. //  массиве wrkdata длиной size и сохраняет это количество в массив stat
  6. void GetCharsOccurrence(unsigned long size,unsigned char*wrkdata,unsigned long*stat)
  7. {
  8.     unsigned long n;
  9.     //  Инициализация статистики нулями
  10.     for(n=0;n<256;n++)
  11.     {
  12.         stat[n]=0;
  13.     };
  14.     //  Подсчёт количества
  15.     for(n=0;n<size;n++)
  16.     {
  17.         stat[wrkdata[n]]+=1;
  18.     };
  19. };
  20.  
  21. //  Элемент бинарного дерева
  22. struct TreeNode
  23. {
  24.     unsigned long Weight;
  25.     unsigned char Sign;
  26.     TreeNode*Left;
  27.     TreeNode*Rght;
  28. };
  29.  
  30. //  Элемент кольцевого списка
  31. struct CListNode
  32. {
  33.     TreeNode*TNode;
  34.     CListNode*Prev;
  35.     CListNode*Next;
  36. };
  37.  
  38. //  Упакованная битовая последовательность
  39. struct PackedData
  40. {
  41.     unsigned long BuffSize;
  42.     unsigned char*Buff;
  43.     unsigned long ByteCount;
  44.     unsigned char BitCount;
  45.     unsigned long ByteCount2;
  46.     unsigned char BitCount2;
  47. };
  48.  
  49. //  Элемент таблицы
  50. struct CodeTableCell
  51. {
  52.     unsigned char Length;
  53.     unsigned long Bits;
  54.     unsigned long Weight;
  55. };
  56.  
  57. //  Добавление элемента к кольцевому списку
  58. void AddCListNode(CListNode**root,TreeNode*node)
  59. {
  60.     CListNode*tmp;
  61.     if(*root)
  62.     //  Если кольцевой список имеет элементы
  63.     {
  64.         //  Сохраняем указатель на последний элемент списка
  65.         tmp=(*root)->Prev;
  66.         //  Элемент перед первым в списке -- новый элемент
  67.         (*root)->Prev=new CListNode;
  68.         //  Элемент перед новым -- бывший последний
  69.         (*root)->Prev->Prev=tmp;
  70.         //  Элемент после добавленного -- первый элемент списка
  71.         (*root)->Prev->Next=*root;
  72.         //  Элемент после бывшего последнего -- добавленный
  73.         tmp->Next=(*root)->Prev;
  74.     }
  75.     else
  76.     //  Если кольцевой список пуст
  77.     {
  78.         //  Первый элемент списка -- новый элемент
  79.         *root=new CListNode;
  80.         //  Следующий и предыдуший элементы списка в кольце из одного
  81.         //  элемента -- это собственно сам этот элемент
  82.         (*root)->Prev=*root;
  83.         (*root)->Next=*root;
  84.     };
  85.     //  Добавленный элемент указывает на элемент бинарного дерева
  86.     (*root)->Prev->TNode=node;
  87. };
  88.  
  89. //  Проверка единственности элемента
  90. int isCListNodeAlone(CListNode*root)
  91. {
  92.     if(root)
  93.     //  Если в списке есть элементы
  94.     {
  95.         //  Проверяем единственность и возвращаем результат
  96.         return root->Next==root;
  97.     }
  98.     else
  99.     {
  100.         return-1;
  101.     };
  102. };
  103.  
  104. //  Удаление элемента из кольцевого списка
  105. void RemoveCListNode(CListNode**root,CListNode**node)
  106. {
  107.     if(*node)
  108.     //  Если в списке есть элементы
  109.     {
  110.         if(isCListNodeAlone(*node))
  111.         //  Если в кольцевом списке всего один элемент
  112.         {
  113.             //  Обнуление указателей удаляемого элемента
  114.             (*node)->Prev=0;
  115.             (*node)->Next=0;
  116.             //  Удаление элемента
  117.             delete*node;
  118.             //  Обнуление указателя на элемент
  119.             *node=0;
  120.             *root=0;
  121.         }
  122.         else
  123.         //  Если в кольцевом списке более одного элемента
  124.         {
  125.             if(*node==*root)
  126.             //  Если удаляемый элемент -- корневой элемент списка
  127.             {
  128.                 //  Новый корень списка -- второй элемент списка
  129.                 *root=(*root)->Next;
  130.             }
  131.             //  Следующий элемент списка теперь должен ссылаться на предыдущий
  132.             (*node)->Next->Prev=(*node)->Prev;
  133.             //  Предыдущий элемент списка теперь должен ссылаться на следующий
  134.             (*node)->Prev->Next=(*node)->Next;
  135.             //  Обнуление указателей удаляемого элемента
  136.             (*node)->Prev=0;
  137.             (*node)->Next=0;
  138.             //  Удаление элемента
  139.             delete*node;
  140.             //  Обнуление указателя на элемент
  141.             *node=0;
  142.         };
  143.     };
  144. };
  145.  
  146. //  Функция производит поиск и возвращает два узла кольцевого списка, которые
  147. //  ссылаются на листья/ветви бинарного дерева, имеющие наименьший вес
  148. void GetTwoLeastWeightedNodes(CListNode*root,CListNode**node1,CListNode**node2)
  149. {
  150.     //  Инициализация выходных переменных
  151.     *node1=0;
  152.     *node2=0;
  153.     if(root)
  154.     //  Если в кольцевом списке имеются элементы
  155.     {
  156.         //  Указатель на элемент кольцевого списка, обрабатываемый в данных момент
  157.         CListNode*currnode;
  158.         //  Первое приближение для первого легчайшего элемента -- первый элемент списка
  159.         *node1=root;
  160.         //  Текущий рабочий элемент -- второй элемент списка
  161.         currnode=root->Next;
  162.         //  Цикл поиска первого легчайшего элемента
  163.         while(currnode!=root)
  164.         //  Выполнять до тех пор, пока текущим элементом не станет первый элемент списка
  165.         {
  166.             if((*node1)->TNode->Weight>currnode->TNode->Weight)
  167.             //  Если вес легчайшейшего элемента больше веса текущего рабочего
  168.             {
  169.                 //  Легчайшим элементом будет текущий рабочий
  170.                 *node1=currnode;
  171.             };
  172.             //  Следующий проверяемый элемент
  173.             currnode=currnode->Next;
  174.         };
  175.         if(*node1==root)
  176.         //  Если первый легчайший элемент -- первый элемент списка
  177.         {
  178.             //  Первым приближением для второго легчайшего элемента будет второй элемент списка
  179.             *node2=root->Next;
  180.             //  А текущим рабочим элементом -- третий элемент списка
  181.             currnode=(*node2)->Next;
  182.         }
  183.         else
  184.         //  Если первый легчайший элемент не является первым элементом списка
  185.         {
  186.             //  Первым приближением для второго легчайшего элемента будет первый элемент списка
  187.             *node2=root;
  188.             //  А текущим рабочим элементом -- второй элемент списка
  189.             currnode=(*node2)->Next;
  190.         };
  191.         //  Цикл поиска второго легчайшего элемента
  192.         while(currnode!=root)
  193.         //  Выполнять до тех пор, пока текущим элементом не станет первый элемент списка
  194.         {
  195.             if((*node2)->TNode->Weight>currnode->TNode->Weight&&currnode!=*node1)
  196.             //  Если вес второго легчайшего элемента больше веса текущего рабочего
  197.             //  и текущий рабочий не является первым легчайшим
  198.             {
  199.                 //  Вторым легчайшим элементом будет текущий рабочий
  200.                 *node2=currnode;
  201.             };
  202.             //  Следующий проверяемый элемент
  203.             currnode=currnode->Next;
  204.         };
  205.     };
  206. };
  207.  
  208. //  Максимальная глубина дерева
  209. unsigned char GetMaxTreeDepth(TreeNode*root)
  210. {
  211.     if(root)
  212.     //  Если список не пуст
  213.     {
  214.         if(root->Left==0)
  215.         //  Если текущий элемент лист
  216.         {
  217.             //  Вернуть значение
  218.             return 1;
  219.         }
  220.         else
  221.         //  Если текущий элемент -- ветвь
  222.         {
  223.             //  Промежуточные значения
  224.             unsigned char tmp1,tmp2;
  225.             //  Определить максимальную глубину каждой ветви
  226.             tmp1=GetMaxTreeDepth(root->Left);
  227.             tmp2=GetMaxTreeDepth(root->Rght);
  228.             //  Вернуть еденицу плюс максимальное значение
  229.             return((tmp1>tmp2)?tmp1:tmp2)+1;
  230.         };
  231.     }
  232.     else
  233.     //  Если список же пуст
  234.     {
  235.         return 0;
  236.     };
  237. };
  238.  
  239. //  Минимальная глубина дерева
  240. unsigned char GetMinTreeDepth(TreeNode*root)
  241. {
  242.     if(root)
  243.     //  Если список не пуст
  244.     {
  245.         if(root->Left==0)
  246.         //  Если текущий элемент лист
  247.         {
  248.             //  Вернуть значение
  249.             return 1;
  250.         }
  251.         else
  252.         //  Если текущий элемент -- ветвь
  253.         {
  254.             //  Промежуточные значения
  255.             unsigned char tmp1,tmp2;
  256.             //  Определить минимальную глубину каждой ветви
  257.             tmp1=GetMinTreeDepth(root->Left);
  258.             tmp2=GetMinTreeDepth(root->Rght);
  259.             //  Вернуть еденицу плюс минимальное значение
  260.             return((tmp1<tmp2)?tmp1:tmp2)+1;
  261.         };
  262.     }
  263.     else
  264.     //  Если список же пуст
  265.     {
  266.         return 0;
  267.     };
  268. };
  269.  
  270. //  Процедура построения дерева Хаффмана
  271. void MakeHuffmanTree(unsigned long*stat,TreeNode**root)
  272. {
  273.     unsigned long n;
  274.     //  Указатель на вспомогательный кольцевой список
  275.     CListNode*rootlist=0;
  276.     //  Временный указатель на элемент бинарного дерева
  277.     TreeNode*tmpnode;
  278.     //  Добавление элементов в кольцевой список
  279.     for(n=0;n<256;n++)
  280.     {
  281.         if(stat[n])
  282.         //  Если символы с текущим кодом вообще встречаются в последовательности
  283.         {
  284.             //  Создание и инициализация листа бинарного дерева Хаффмана
  285.             tmpnode=new TreeNode;
  286.             tmpnode->Left=0;
  287.             tmpnode->Rght=0;
  288.             tmpnode->Sign=n;
  289.             tmpnode->Weight=stat[n];
  290.             //  Добавление его в кольцевой список
  291.             AddCListNode(&rootlist,tmpnode);
  292.         };
  293.     };
  294.     if(!rootlist)
  295.     //  Если кольцевой список пуст, то и дерево Хаффмана отсутствует
  296.     {
  297.         *root=0;
  298.     };
  299.     //  Построение бинарного дерева
  300.     while(!isCListNodeAlone(rootlist))
  301.     //  Пока в кольцевом списке более одного элемента
  302.     {
  303.         CListNode*tmp1;
  304.         CListNode*tmp2;
  305.         //  Находим два элемента кольцевого списка, ссылающихся на листы/ветви
  306.         //  бинарного дерева с наименьшими весами
  307.         GetTwoLeastWeightedNodes(rootlist,&tmp1,&tmp2);
  308.         //  Глубины вновь полученных ветвей
  309.         unsigned char dpth1=GetMinTreeDepth(tmp1->TNode);
  310.         unsigned char dpth2=GetMinTreeDepth(tmp2->TNode);
  311.         //  Создание и инициализация ветви бинарного дерева Хаффмана
  312.         tmpnode=new TreeNode;
  313.         tmpnode->Left=tmp2->TNode;
  314.         tmpnode->Rght=tmp1->TNode;
  315.         tmpnode->Sign=0;
  316.         tmpnode->Weight=tmp1->TNode->Weight+tmp2->TNode->Weight;
  317.         //  Удаление первого найденного элемента из кольцевого списка
  318.         RemoveCListNode(&rootlist,&tmp1);
  319.         //  Во втором элементе меняем старый лист/ветвь дерева на новую ветвь
  320.         tmp2->TNode=tmpnode;
  321.     };
  322.     //  Результат работы процедуры
  323.     *root=rootlist->TNode;
  324.     //  Удаление последнего элемента кольцевого списка
  325.     RemoveCListNode(&rootlist,&rootlist);
  326. };
  327.  
  328. //  Удаление дерева Хаффмана
  329. void RemoveHuffmanTree(TreeNode**root)
  330. {
  331.     //  Текущий элемент
  332.     TreeNode*tmp=*root;
  333.     if(tmp->Left!=0)
  334.     //  Если текущий элемент -- ветвь
  335.     {
  336.         //  Удалить левую часть дерева
  337.         RemoveHuffmanTree(&(tmp->Left));
  338.         //  Удалить правую часть дерева
  339.         RemoveHuffmanTree(&(tmp->Rght));
  340.     };
  341.     //  Удалить текущий элемент/ветвь
  342.     delete tmp;
  343.     //  Занулить указатель на удалённый элемент
  344.     *root=0;
  345. };
  346.  
  347. //  Отображение дерева Хаффмана
  348. void DisplayHuffmanTree(TreeNode*root,unsigned char numbits,unsigned long bitfield)
  349. {
  350.     if(root)
  351.     //  Если дерево не пусто
  352.     {
  353.         if(root->Left==0)
  354.         //  Если текущий элемент -- лист
  355.         {
  356.             //  Отобразить вес
  357.             printf("%7d",root->Weight);
  358.             //  Отобразить код символа
  359.             unsigned char tmp=root->Sign;
  360.             printf("%5d    ",tmp);
  361.             //  Отобразить символ
  362.             if(tmp>=14||tmp>=2&&tmp<=6||tmp==11||tmp==12)
  363.             {
  364.                 printf("%c",tmp);
  365.             }
  366.             else
  367.             {
  368.                 printf(" ");
  369.             };
  370.             //  Отобразить длину кода Хаффмана
  371.             printf("%4d  ",numbits);
  372.             //  Отобразить код Хаффмана
  373.             for(int n=0;n<numbits;n++)
  374.             {
  375.                 printf("%d",(bitfield>>(numbits-n-1))&1);
  376.             };
  377.             printf("\n");
  378.         }
  379.         else
  380.         //  Если текущий элемент -- ветвь
  381.         {
  382.             //  Отобразить подветви
  383.             DisplayHuffmanTree(root->Left,numbits+1,bitfield<<1);
  384.             DisplayHuffmanTree(root->Rght,numbits+1,(bitfield<<1)+1);
  385.         };
  386.     };
  387. };
  388.  
  389. //  Отображение дерева Хаффмана 2
  390. void DisplayHuffmanTree2(TreeNode*root)
  391. {
  392.     if(root)
  393.     //  Если дерево не пусто
  394.     {
  395.         if(root->Left==0)
  396.         //  Если текущий элемент -- лист
  397.         {
  398.             printf("0\n");
  399.             unsigned char tmp=root->Sign;
  400.            
  401.             for(int n=0;n<8;n++)
  402.             {
  403.                 printf("%d",(tmp>>n)&1);
  404.             };
  405.            
  406.             //printf("=%d",tmp);
  407.             printf("\n");
  408.         }
  409.         else
  410.         //  Если текущий элемент -- ветвь
  411.         {
  412.             printf("1");
  413.             DisplayHuffmanTree2(root->Left);
  414.             DisplayHuffmanTree2(root->Rght);
  415.         };
  416.     };
  417. };
  418.  
  419. //  Инициализация таблицы
  420. void CreateTable(CodeTableCell**table)
  421. {
  422.     *table=new CodeTableCell[256];
  423.     unsigned long n;
  424.     for(n=0;n<256;n++)
  425.     {
  426.         (*table)[n].Length=0;
  427.         (*table)[n].Bits=0;
  428.         (*table)[n].Weight=0;
  429.     };
  430. };
  431.  
  432. //  Удаление таблицы
  433. void DeleteTable(CodeTableCell**table)
  434. {
  435.     delete*table;
  436.     *table=0;
  437. };
  438.  
  439. //  Преобразование дерева Хаффмана в таблицу кодов Хаффмана
  440. void Tree2Table(TreeNode*root,CodeTableCell*table,unsigned char numbits,unsigned long bitfield)
  441. {
  442.     if(root)
  443.     //  Если дерево не пусто
  444.     {
  445.         if(root->Left==0)
  446.         //  Если текущий элемент -- лист
  447.         {
  448.             //  Сохранить длину
  449.             table[root->Sign].Length=numbits;
  450.             table[root->Sign].Bits=bitfield;
  451.             table[root->Sign].Weight=root->Weight;
  452.         }
  453.         else
  454.         //  Если текущий элемент -- ветвь
  455.         {
  456.             //  Сохранить подветви
  457.             Tree2Table(root->Left,table,numbits+1,bitfield<<1);
  458.             Tree2Table(root->Rght,table,numbits+1,(bitfield<<1)+1);
  459.         };
  460.     };
  461. };
  462.  
  463. //  Возвращает размер закодированных данных в битах
  464. unsigned long GetEncodedDataSize(CodeTableCell*table)
  465. {
  466.     unsigned long tmp=0;
  467.     unsigned long n;
  468.     for(n=0;n<256;n++)
  469.     {
  470.         tmp+=table[n].Weight*table[n].Length;
  471.     };
  472.     return tmp;
  473. };
  474.  
  475. //  Отображение таблицы кодов Хаффмана
  476. void DisplayTable(CodeTableCell*table,unsigned char flg)
  477. {
  478.     unsigned long n;
  479.     for(n=0;n<256;n++)
  480.     {
  481.         if(flg||table[n].Length)
  482.         {
  483.             //  Отобразить вес
  484.             printf("%7d",table[n].Weight);
  485.             //  Отобразить код символа
  486.             printf("%5d    ",n);
  487.             //  Отобразить символ
  488.             if(n>=14||n>=2&&n<=6||n==11||n==12)
  489.             {
  490.                 printf("%c",n);
  491.             }
  492.             else
  493.             {
  494.                 printf(" ");
  495.             };
  496.             //  Отобразить длину кода
  497.             printf("%4d  ",table[n].Length);
  498.             //  Отобразить код Хаффмана
  499.             for(int m=0;m<table[n].Length;m++)
  500.             {
  501.                 printf("%d",(table[n].Bits>>(table[n].Length-m-1))&1);
  502.             };
  503.             printf("\n");
  504.         };
  505.     };
  506. };
  507.  
  508. //  Подсчёт количества листьев дерева
  509. unsigned long CountTreeLeaves(TreeNode*root)
  510. {
  511.     if(root)
  512.     //  Если дерево не пусто
  513.     {
  514.         if(root->Left==0)
  515.         //  Если текущий элемент -- лист
  516.         {
  517.             return 1;
  518.         }
  519.         else
  520.         //  Если текущий элемент -- ветвь
  521.         {
  522.             return CountTreeLeaves(root->Left)+CountTreeLeaves(root->Rght);
  523.         };
  524.     }
  525.     else
  526.     {
  527.         return 0;
  528.     };
  529. };
  530.  
  531. //  Сброс упаковки для нового чтения
  532. void ResetPackage(PackedData*package)
  533. {
  534.     package->ByteCount2=0;
  535.     package->BitCount2=0;
  536. };
  537.  
  538. //  Инициализация упаковки
  539. void CreatePackage(PackedData*package,unsigned long bytesnum)
  540. {
  541.     package->BitCount=0;
  542.     package->ByteCount=0;
  543.     ResetPackage(package);
  544.     package->BuffSize=bytesnum;
  545.     package->Buff=new unsigned char[bytesnum];
  546.     for(unsigned long n=0;n<bytesnum;n++)
  547.     {
  548.         package->Buff[n]=0;
  549.     };
  550. };
  551.  
  552. //  Деинициализация упаковки
  553. void DeletePackage(PackedData*package)
  554. {
  555.     delete package->Buff;
  556.     package->Buff=0;
  557.     package->BitCount=0;
  558.     package->ByteCount=0;
  559.     package->BuffSize=0;
  560.     ResetPackage(package);
  561. };
  562.  
  563. //  Упаковка бита
  564. int PackBit(PackedData*package,unsigned char bit)
  565. {
  566.     if(package->ByteCount<package->BuffSize)
  567.     {
  568.         package->Buff[package->ByteCount]|=(bit&1)<<package->BitCount;
  569.         package->BitCount++;
  570.         if(package->BitCount>7)
  571.         {
  572.             package->BitCount=0;
  573.             package->ByteCount++;
  574.         };
  575.         return 0;
  576.     }
  577.     else
  578.     {
  579.         return-1;
  580.     };
  581. };
  582.  
  583. //  Упаковка байта
  584. int PackByte(PackedData*package,unsigned char byte)
  585. {
  586.     if(package->ByteCount<package->BuffSize-1)
  587.     {
  588.         package->Buff[package->ByteCount]|=(byte)<<package->BitCount;
  589.         package->ByteCount++;
  590.         package->Buff[package->ByteCount]|=(byte)>>(8-package->BitCount);
  591.         return 0;
  592.     }
  593.     else
  594.     {
  595.         return-1;
  596.     };
  597. };
  598.  
  599. //  Упаковка битовой последовательности
  600. int PackBitsField(PackedData*package,unsigned char bitsnum,unsigned long bitsfield)
  601. {
  602.     while(package->ByteCount<package->BuffSize&&        //  Пока есть место в упаковке
  603.         bitsnum>0)                                      //  И есть биты для упаковки
  604.     {
  605.         //  Количество битов, помещающихся в текущем байте упаковки
  606.         unsigned char cbn=8-package->BitCount;
  607.         //  Если оно больше количества битов, оставшихся для упаковки
  608.         if(cbn>bitsnum)
  609.         {
  610.             //  Количество упаковываемых битов равно количеству битов, подлежащих упаковке
  611.             cbn=bitsnum;
  612.         };
  613.         //  Поместить текущую пачку бит в упаковку
  614.         package->Buff[package->ByteCount]|=bitsfield<<package->BitCount;
  615.         //  Инкрементировать счётчик упакованных битов и байтов если надо
  616.         package->BitCount+=cbn;
  617.         if(package->BitCount>7)
  618.         {
  619.             package->BitCount=0;
  620.             package->ByteCount++;
  621.         };
  622.         //  Уменьшить счётчик битов, подлежащих упаковке
  623.         bitsnum-=cbn;
  624.         //  Отбросить упакованные биты
  625.         bitsfield>>=cbn;
  626.     };
  627.     if(package->ByteCount<package->BuffSize&&bitsnum==0)
  628.     {
  629.         return 0;
  630.     }
  631.     else
  632.     //  Если место в упаковке закончилось, а биты упакованы не все
  633.     {
  634.         //  Вернуть ошибку
  635.         return-1;
  636.     };
  637. };
  638.  
  639. //  Распаковка бита
  640. int UnpackBit(PackedData*package,unsigned char*bit)
  641. {
  642.     if(package->ByteCount2<package->BuffSize)
  643.     {
  644.         *bit=(package->Buff[package->ByteCount2]>>package->BitCount2)&1;
  645.         package->BitCount2++;
  646.         if(package->BitCount2>7)
  647.         {
  648.             package->BitCount2=0;
  649.             package->ByteCount2++;
  650.         };
  651.         return 0;
  652.     }
  653.     else
  654.     {
  655.         return-1;
  656.     };
  657. };
  658.  
  659. //  Распаковка байта
  660. int UnpackByte(PackedData*package,unsigned char*byte)
  661. {
  662.     if(package->ByteCount2<package->BuffSize-1)
  663.     {
  664.         *byte=package->Buff[package->ByteCount2]>>package->BitCount2;
  665.         package->ByteCount2++;
  666.         *byte|=package->Buff[package->ByteCount2]<<(8-package->BitCount2);
  667.         return 0;
  668.     }
  669.     else
  670.     {
  671.         return-1;
  672.     };
  673. };
  674.  
  675. //  Упаковка дерева Хаффмана
  676. void PackHuffmanTree(TreeNode*root,PackedData*package)
  677. {
  678.     if(root)
  679.     //  Если дерево не пусто
  680.     {
  681.         if(root->Left==0)
  682.         //  Если текущий элемент -- лист
  683.         {
  684.             PackBit(package,0);
  685.             PackByte(package,root->Sign);
  686.         }
  687.         else
  688.         //  Если текущий элемент -- ветвь
  689.         {
  690.             PackBit(package,1);
  691.             PackHuffmanTree(root->Left,package);
  692.             PackHuffmanTree(root->Rght,package);
  693.         };
  694.     };
  695. };
  696.  
  697. //  Распаковка дерева Хаффмана
  698. void UnpackHaffmanTree(TreeNode**root,PackedData*package)
  699. {
  700.     *root=new TreeNode;
  701.     (*root)->Weight=0;
  702.     unsigned char tmp;
  703.     UnpackBit(package,&tmp);
  704.     if(tmp)
  705.     //  Ветвь
  706.     {
  707.         (*root)->Sign=0;
  708.         UnpackHaffmanTree(&((*root)->Left),package);
  709.         UnpackHaffmanTree(&((*root)->Rght),package);
  710.     }
  711.     else
  712.     //  Лист
  713.     {
  714.         (*root)->Left=0;
  715.         (*root)->Rght=0;
  716.         UnpackByte(package,&tmp);
  717.         (*root)->Sign=tmp;
  718.     };
  719. };
  720.  
  721. //  Отображение содержимого упаковки в двоичной системе (младшие биты сначала)
  722. void DisplayPackage(PackedData*package)
  723. {
  724.     for(unsigned long m=0;m<package->BuffSize;m++)
  725.     {
  726.         //printf("%4X",package.Buff[m]);
  727.         for(int n=0;n<8;n++)
  728.         {
  729.             printf("%d",(package->Buff[m]>>n)&1);
  730.         };
  731.         printf("  ");
  732.     };
  733.     if(package->BuffSize%8)
  734.     {
  735.         printf("\n");
  736.     };
  737. };
  738.  
  739. //  Упаковка данных
  740. void PackData(unsigned long size,unsigned char*data,CodeTableCell*table,PackedData*package)
  741. {
  742.     unsigned long n;
  743.     for(n=0;n<size;n++)
  744.     {
  745.         unsigned tmp=data[n];
  746.         PackBitsField(package,table[tmp].Length,table[tmp].Bits);
  747.     };
  748. };
  749.  
  750. //  Распаковка бита
  751. unsigned char UnpackChar(TreeNode*root,PackedData*package)
  752. {
  753.     if(root->Left)
  754.     {
  755.         unsigned char tmp;
  756.         UnpackBit(package,&tmp);
  757.         if(tmp)
  758.         {
  759.             return UnpackChar(root->Left,package);
  760.         }
  761.         else
  762.         {
  763.             return UnpackChar(root->Rght,package);
  764.         };
  765.     }
  766.     else
  767.     {
  768.         return root->Sign;
  769.     };
  770. };
  771.  
  772. //  Распаковка данных
  773. void UnpackData(TreeNode*root,PackedData*package,unsigned long dsize,unsigned char*data)
  774. {
  775.     ResetPackage(package);
  776.     unsigned long n;
  777.     for(n=0;n<dsize;n++)
  778.     {
  779.         data[n]=UnpackChar(root,package);
  780.     };
  781. };
  782.  
  783. void main()
  784. {
  785.     //  Исходная строка
  786.     //unsigned char data[]="ABRAKADABRA SIMSALABIM";
  787.     unsigned char data[]="Hardly knowing what she did, she picked up a little bit of stick, and held it out to the puppy; whereupon the puppy jumped into the air off all its feet at once, with a yelp of delight, and rushed at the stick, and made believe to worry it; then Alice dodged behind a great thistle, to keep herself from being run over; and the moment she appeared on the other side, the puppy made another rush at the stick, and tumbled head over heels in its hurry to get hold of it; then Alice, thinking it was very like having a game of play with a carthorse, and expecting every moment to be trampled under its feet, ran round the thistle again; then the puppy began a series of short charges at the stick, running a very little way forwards each time and a long way back, and barking hoarsely all the while, till at last it sat down a good way off, panting, with its tongue hanging out of its mouth, and its great eyes half shut.";
  788.     //  Размер строки
  789.     unsigned long datasize=0;
  790.     while(data[datasize])
  791.         datasize++;
  792.     printf("String size: %d\n",datasize);
  793.     printf("String: \"%s\"\n\n",data);
  794.     //  Встречаемость символов
  795.     unsigned long stat[256];
  796.     GetCharsOccurrence(datasize,data,stat);
  797.     //  Указатель на корень дерева Хаффмана
  798.     TreeNode*root;
  799.     //  Создание дерева Хаффмана
  800.     MakeHuffmanTree(stat,&root);
  801.     //  Отображение дерева Хаффмана
  802.     printf("Huffnam tree:\n");
  803.     printf(" Weight Code Char  Sz  Huffman Key\n");
  804.     DisplayHuffmanTree(root,0,0);
  805.     printf("Leaves number: %d\n\n",CountTreeLeaves(root));
  806.     //  Упаковка для дерева Хаффмана
  807.     PackedData tree_package;
  808.     //  Упаковка дерева Хаффмана
  809.     unsigned long ctl=CountTreeLeaves(root);
  810.     CreatePackage(&tree_package,(5*ctl)/4+2);
  811.     //DisplayHuffmanTree2(root);
  812.     PackHuffmanTree(root,&tree_package);
  813.     //  Отображение упакованных данных
  814.     printf("Packed Huffman Tree:\n");
  815.     DisplayPackage(&tree_package);
  816.     printf("Bytes: %d, bits: %d\n\n",tree_package.ByteCount,tree_package.BitCount);
  817.     //  Распаковка дерева
  818.     TreeNode*newroot;
  819.     UnpackHaffmanTree(&newroot,&tree_package);
  820.     printf("Unpacked Huffnam tree:\n");
  821.     printf(" Weight Code Char  Sz  Huffman Key\n");
  822.     DisplayHuffmanTree(newroot,0,0);
  823.     printf("Leaves number: %d\n\n",CountTreeLeaves(newroot));
  824.     CodeTableCell*table;
  825.     //  Работа с таблицей кодов Хаффмана
  826.     CreateTable(&table);
  827.     Tree2Table(root,table,0,0);
  828.     printf("Shortened Huffnam code table:\n");
  829.     printf(" Weight Code Char  Sz  Huffman Key\n");
  830.     DisplayTable(table,0);
  831.     unsigned long eds=GetEncodedDataSize(table);
  832.     printf("Encoded data size: %d byte, last byte: %d bits\n\n",eds/8+(eds%8!=0),eds%8);
  833.     //  Упаковка данных
  834.     PackedData data_package;
  835.     CreatePackage(&data_package,eds/8+(eds%8!=0));
  836.     PackData(datasize,data,table,&data_package);
  837.     printf("Packed Data:\n");
  838.     DisplayPackage(&data_package);
  839.     //  Распаковка данных
  840.     unsigned char*unpackeddata=new unsigned char[datasize+1];
  841.     unpackeddata[datasize]=0;
  842.     UnpackData(newroot,&data_package,datasize,unpackeddata);
  843.     printf("Unpacked string: \"%s\"\n\n",data);
  844.     //  Удаление всего
  845.     DeletePackage(&data_package);
  846.     DeleteTable(&table);
  847.     RemoveHuffmanTree(&newroot);
  848.     DeletePackage(&tree_package);
  849.     RemoveHuffmanTree(&root);
  850. };
  851.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement