Use C ++ to implement the Harman Algorithm

Source: Internet
Author: User

I think every computer major student is more or less exposed to the old problems in the data structure. Generally, it is to give some characters, and the occurrence frequency of these characters, so that you can design a binary encoding for these characters, requiring the minimum encoding of the characters with the highest frequency. The solution is to construct a user-defined tree (Binary Tree). The basic idea is to pick out two of these characters with the lowest frequency and construct a new node, point the left and right child pointers of the new node to the two nodes respectively. I think everyone knows this. I will not talk about it much. This article mainly describes the problems I encountered when implementing C ++. First, I defined a Harman Tree node:

Class hNode
{
Public:
Friend bool operator> (hNode n1, hNode n2); // defines a value greater than the symbol for priority queue arrangement.
HNode (string d = "", int I = 0, hNode * l = NULL, hNode * r = NULL): left (l), right (r ), data (d), value (I ){}
HNode * left;
HNode * right;
String data; // The stored string
Int value; // number of times a string appears
};

Bool operator> (hNode n1, hNode n2)
{
Return n1.value> n2.value;
}

Because it is only a small job in the algorithm class, I am not prepared to define a Complete Binary Tree operation for hNode, but only to store data objects, so there is only one constructor, all data member instances are public.

This will cause a lot of trouble when writing this algorithm, mainly because the std: priority_queue container is used. At that time, considering that he had to select two frequencies at a minimum (that is, the minimum number of occurrences, and the value in my hNode was the number of occurrences), he naturally thought of std :: priority_queue container, the priority queue will pop up the element with the highest weight in the queue each time, this feature is undoubtedly the best choice for implementing the Harman algorithm. However, because of the first use of the std: priority_queue container, a lot of problems have occurred. Fortunately, we finally solved them one by one and learned a lot.

The preliminary assumption is that all the hNode objects are first pushed into the priority queue, and then two nodes are popped up each time to form a new node, and then the new nodes are pushed into the queue, repeat this step. When there is only one element in the queue, the user tree will complete. Like this: (it is wrong, don't learn)

While (...)
{
Std: priority_queue .....
HNode h1 = q. top ();
Q. pop ();
HNode h2 = q. top ();
Q. pop ();
HNode r;
R. left = h1;
R. right = h2;
R. value = h1.value + h2.value;
Q. push (r );
}

However, the first problem encountered was that all containers in STL are inserted based on the by value semantics, that is, to generate a copy of the object and put it in the container. The consequence is that the left and right pointers of hNode all point to unknown places. You can try a few pictures to find out what went wrong. After consideration, I found that if the hNode pointer is stored in the queue, this problem will not occur, so I changed it:

HNode * makeTree (priority_queue {
HNode * p1 = NULL;
HNode * p2 = NULL;
HNode * r = NULL;
While (! Pq. empty ())
{
P1 = pq. top ();
Pq. pop ();
If (pq. empty ())
{
R = p1;
Return r;
}
P2 = pq. top ();
Pq. pop ();
R = new hNode;
R-> left = p1;
R-> right = p2;
R-> value = p1-> value + p2-> value;
Pq. push (r );
}
Return NULL;
}

However, I encountered the second problem immediately. Std: priority_queue compares the pointer address directly when determining the priority relationship, rather than the object size relationship pointed to by the pointer. Pointers are not classes, so I cannot rewrite the comparison operation of pointers. The program is in trouble. Std: priority_queue uses the Greater template by default to generate a function object to compare elements, I tried to write a special version of hNode * for Greater to change the comparison of priority queue on hNode *, but it was not successful. When there was no doubt, I suddenly thought why I didn't directly write a function object for the priority queue to replace Greater <> is that okay? Write down the following code:

Struct phNodeComp
{
Bool operator () (const hNode * & left, const hNode * & right) const
{
Return left-> value> right-> value;
}
};

Then change the declaration of std: priority_queue:

Priority_queue

Finally, the problem is solved. It seems that the knowledge obtained only from books is not reliable, so you must practice it to have a real understanding.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.