Building Huffman encoding tree from ordered list - c++

I am building a huffman encoding tree from an ordered linked list (sorted by frequency of letters) that begins with the lowest frequency. After creating the tree, I traversed it and it appears that the tree was implemented incorrectly. When I traversed the tree, some of the nodes from the ordered linked list appeared to have be left out. (I don't think it was because my traversal is wrong.) Here is my code for the tree:
//My class for the nodes in the ordered linked list that will be converted to a tree
class fList{
public:
fList();
int frequency;
char letter;
fList* next;
fList* left;
fList* right;
};
fList::fList(){
frequency = 0;
letter = NULL;
next = NULL;
left = NULL;
right = NULL;
}
fList* head = NULL;
.
.
.
.
.
//Create the huffman encoding tree from the linked list stored in head
while(head->next != NULL){
fList *tree = new fList();
fList *temp = new fList();
fList *trail = new fList();
/* Take the first two frequency numbers, add them, create a new node
* with the total frequency number and have new node point to the first
* two nodes (right child and left child)
*/
total = (head->frequency + head->next->frequency);
tree->frequency = total;
//Set a new head node
tree->left = head;
tree->right = head->next;
head = head->next->next;
tree->left->next = NULL;
tree->right->next = NULL;
//place tree node in its correct place in sorted list
temp = head;
trail = temp;
if(head->frequency >= tree->frequency){
tree->next = head;
head = tree;
}
else if(temp->next != NULL){
while(temp != NULL){
if(temp->frequency >= tree->frequency){
tree->next = temp;
trail->next = tree;
break;
}
else{
trail = temp;
temp = temp->next;
}
}//while
//insert at the end of list
if(temp == NULL){
temp = tree->next;
trail->next = tree;
}
}//else if !=NULL
else if(head == NULL || head->next == NULL) head = tree;
}

At the end of the piece of code you posted, in the line
else if(temp->next = NULL && head != NULL) head = tree;
you inadvertently truncate the tree by setting temp->next = NULL where you probably meant to ask whether temp->next == NULL. This may be why some of the entries (the ones linked to by temp) are left out from the final result.

Related

Linked List is Palindrome or not

I'm new to Linked List and I was trying to solve this question where we have to return true or false on the basis of whether given linked List is palindrome or not.
Given a pointer to the 1st node.
bool isPalindrome(Node *head)
{
//Your code here
Node *startsecond = NULL;//will act as pointer to second Linked list
Node *temp2 = head;
Node *temp1 = head;
//Split LINKED LIST IN 2 PARTS
while(1){
temp2 = temp2->next->next;
if(temp2->next==NULL){//if linked list has odd no of elements
startsecond = temp1->next->next;
break;
}else{
startsecond = temp1->next;
break;
}
temp1 = temp1->next;
}
temp1->next=NULL;
//REVERSE THE SECOND LINKED LIST
Node *current = startsecond;
Node *prev = NULL, *next = NULL;
while(current!=NULL){
next = current->next;
current->next = prev;
prev=current;
current=next;
}
startsecond = prev;
while(head!=NULL && startsecond!=NULL){
if(startsecond->data == head->data){
head = head->next;
startsecond = startsecond->next;
}
else
return false;
}
return true;
}
I'm not able to understand it gives segmentation error. It says:
Runtime Error:
Runtime ErrorSegmentation Fault (SIGSEGV)
Here I'm first splitting the Linked List into 2 equal halves and then reverse the second half and then compare the elements to 2 one by one.
Can someone please help debug.
You have a typo here:
Node *temp2 = head, // , instead of ;
Node *temp1 = head;
Notice the , instead of a ;.
You need:
Node *temp2 = head;
Node *temp1 = head;
or
Node *temp2 = head, *temp1 = head;

Problem with inserting into a doubly linked list in ascending order

i need to make a function to sum 2 piecewise linear functions (both decreasing or increasing) and insert them into a third list in an ascending order based on the x-axis coordinates of each point. So i have created multiple functions, all seem to check out except this one yet i do not know what's the problem. It's not inputting anything at all.
struct coords has double x,y;
dList has : coords pt;
node has : node *head, *tail;
node *prev, *next;
dList insert(dList L, coords point) {
node *temp;
temp = new node;
if (temp == NULL) {
cout << "error";
exit(1);
}
temp->next = NULL;
temp->prev = NULL;
temp->pt = point;
if (L.head == NULL || L.tail == NULL) {
L.head = temp;
L.tail = temp;
return L;
}
if (L.head->pt.x > temp->pt.x) {
temp->next = L.head;
L.head->prev = temp;
L.head = temp;
return L;
}
if (L.tail->pt.x < temp->pt.x) {
temp->prev = L.tail;
L.tail->next = temp;
L.tail = temp;
return L;
}
node *cur;
cur = L.head->next;
while (cur->pt.x < temp->pt.x)
cur = cur->next;
temp->next = cur->next;
temp->prev = cur;
cur->next->prev = temp;
cur->next = temp;
return L;
}
The case in which the node to be inserted is in the middle is the problem. You should be looking one node ahead instead of looking at the current one. Try working it out on paper and you will see how that makes a difference:
node * cur;
// also start at head here
cur=L.head;
while(cur->next->pt.x<temp->pt.x)
cur=cur->next;
temp->next=cur->next;
temp->prev=cur;
cur->next->prev=temp;
cur->next=temp;
You should also consider passing a dList L as a pointer to the function and also returning it as a pointer:
// this way you won't be making a copy of it, you may run into trouble if you don't have your copy constructor implemented
dList* insert(dList* L,coords point)
I hope that this helps you.

how to insert a linked list after a particular node inside head? c++

I wrote the following code to insert an integer to a linked list, but in a sorting approach.
I commented where my problem is and explained it below:
void LLL::insertSorted(int r) {
node * temp = NULL;
node * current = NULL;
if (head == NULL) {
head = new node;
head->data = r;
head->next = NULL;
} else {
temp = new node;
temp->data = r;
current = head;
while (temp->data > current->data && current != NULL) {
current = current->next;
}
temp->next = current;
/*
* Assume that I have head points to this list: { 3 -> 5 -> 8 -> NULL }
* And I want to insert {6} (temp) to the list just after 5; then what
* I've done so far on my previous code I made temp = {6 -> 8 -> NULL}.
* NOW!! How can correctly insert temp to ((head)) just after {5}??!
*/
}
}
void LLL::insertSorted(int r) {
node * cur = head;
node * prev = NULL;
while((cur != NULL) && (r > cur->data)){//find the location to insert
prev = cur;
cur = cur->next;
}
node *new_node = new node;
new_node->data = r;
new_node->next = cur;
if(prev == NULL){//new first one
head = new_node;
}else{
prev->next = new_node;
}
}
You need to remember which node you are inserting after, and have that node link to the new one.
For example, in your loop to find the node that comes after temp, current, have another variable, say prev, and do pre = current just before current = current->next.
you need a new node when insert
I think just make a new node after the previous one you want insert, like 5 in your comment
This is the final result: (it works!)
It handles the following cases:
case 1: head is empty.
case 2: the new element is the smallest in the list.
case 3: the new element is somewhere in the middle of the list.
case 4: the new element is the largest.
void LLL::insertSorted(int r) {
node * temp = NULL;
node * current = NULL;
node * previous = NULL;
if (head == NULL) {
head = new node;
head->data = r;
head->next = NULL;
} else {
temp = new node;
temp->data = r;
temp->next = NULL;
current = head;
if (temp->data < current->data) {
temp->next = head;
head = temp;
} else {
while (current != NULL && temp->data >= current->data) {
previous = current;
current = current->next;
}
temp->next = current;
previous->next = temp;
}
}
}

Implementing fa unction that adds and sorts data in a singly linked list (addsort)?

I'm very new to C++ so it's a bit hard to understand the syntax sometimes. Anyways, I'm supposed to implement a function that adds and sorts the data given into a linked list. For example if I pass 2 into the list [1,4,5] then I should get [1,2,4,5]
Here is what I have written so far, and no it does not work, I keep getting "blah blah not declared in this scope"
void addSorted(Data * ){
temp = 0;
if (head == NULL) {
head = new LinkNode(newData);
}
else {
LinkNode * current = head;
while (current->next != NULL) {
current = current->next;
}
if(current->data > current->next->data){
temp = current->data;
current->data = current->next->data;
current->next->data = temp;
}
current->next = new LinkNode(newData);
}
}
Someone please help me, I'm using the struct LinkNode I think which is already given, in addition to a bunch of other functions like add, insert, remove, get, and size
I'm not looking to just get the answer, I need to know why what I have isn't working.
Hope that you have really put your effort in it..I am posting the whole function for inserting data into list in sorted order which I had written long time back
void addData(node * head, int data){
if(head == NULL) { // First node
node * temp = new node;
temp -> data = data;
temp -> next = NULL;
head = temp;
root = head;
}else{
node * prev = NULL;
while(head -> next != NULL){ // Sorted Addition Logic is HERE
if(data >= head -> data){
prev = head;
head = head -> next;
continue;
}else{
node * temp = new node;
temp -> data = data;
temp -> next = head;
if(prev != NULL)
prev -> next = temp;
else
head = temp;
break;
}
}
if(head -> next == NULL){
node * temp = new node;
temp -> data = data;
head -> next = temp;
temp -> next = NULL;
}
}
}
Seeing your code, it seems that your logic itself is wrong...you are always ending on the last node (while loop) and in the next if statment you are trying to compare the data of the next node which is not present

C++ Add to linked list in sorted order

Hi I have a linked list using structs. Right now I got it to add every element at the end. However I'd like to add each element in sorted order based on the ID. The struct has two elements: string name, and long ID.
node* temp = new node;
temp->name = nameRead;
temp->id = idRead;
//check if first item, if so add as head
if(head == NULL)
{
head = temp;
}
else
{
node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
node* temp = new node;
temp->name = nameRead;
temp->id = idRead;
node* temp2 = head;
node** temp3 = &head;
while(temp2 != null && temp2->id < temp->id)
{
temp3 = &temp2->next;
temp2 = temp2->next;
}
*temp3 = temp;
temp->next = temp2;
EDIT: Explanation: The 'temp3' pointer points to where 'temp' would need to go. Initialize temp2 to head, and keep looping until we reach the end of the list, or until temp2's id is >= than temp's id. In each iteration of the loop, advance both temp3 and temp2.
At the end of the loop, 'temp3' will hold the address of the pointer where temp should be. So assign *temp3 to point to temp, and assign temp->next to point to temp2 (which at this point would either be null, or would point to the item that has larger id than temp->id).
Taken from my student notebook:
void addSorted(node * head, int id){
node* newNode = new node;
newNode->number = n;
newNode->next = NULL;
if(head == NULL || head->number >= id ){
newNode->next = head;
head = newNode;
return;
}else if(head->next != NULL && head->next->id >= id){
node * nextNode = head->next;
newNode->next = nextNode;
head->next = newNode;
return;
}else{
node * left;
node * right = head;
while(right != NULL && right->next->id <= id){
left = right;
right = right->next;
}
left->next=newNode;
newNode->next = right;
}
}
Most of the modification to the code is pretty trivial -- just add a comparison based on the ID so you only walk through the list until you get to a node with an ID larger then the new one you need to insert (or reach the end of the list).
This is where things get slightly tricky: before you "realize" you've reached the right spot in the list, you've already gone one node too far (and in a singly linked list, there's no way to go back). The trick to fix that is pretty simple: allocate a new (empty) node and insert it after the too-large node you found. Copy that too-large node's contents into the new one you just inserted, and then copy the data for the new node into the spot it just vacated.
I should add, however, that all of this is mostly a moot point. If you want a sorted collection of items, a linked list is usually a really lousy choice. Unless you're doing something like homework where you have no choice but to do whatever brain-dead crap you've been assigned, look up std::set [Edit: or std::multiset, if duplicates are allowed -- or possibly std::map or std::multimap, if you want to be able to find a node based on an ID] and forget about implementing it yourself.