I'm trying to learn some basics about single linked lists, so I went with idea of creating some code. Sadly, I have given constructor to follow.
Untill now I've created all methods I've wanted. Unfortunately, seems like my insert doesn't work, so I can't even check if other methods works. Ofc role of insert method is to add number into sorted list L. This number should be put before first number, if it's bigger or put at the end of the list, if there is no such number.
#include <iostream>
#include <cassert>
using namespace std;
struct lnode
{
int key;
lnode* next;
lnode(int k, lnode* n=nullptr):key(k),next(n){}
};
void insert( lnode* &L, int x)
{
while(L)
{
if(x >= L->key)
{
L = L->next;
}
else
{
lnode* temp = L;
L = new lnode(x, nullptr);
L->next = temp;
break;
}
}
}
int main()
{
lnode* t = nullptr;
insert(t,3);
insert(t,4);
insert(t,1);
insert(t,7);
insert(t,-4);
insert(t,9);
insert(t,2);
while(L) {
std::cout << L->key << " ";
}
}
What do I expect? My expectations is to see elements of my list. At this moment there is nothing. No error, no result.
The trick to writing simple singly-linked list modifying code is to use a pointer to the pointer current node to indicate your position:
void insert( lnode* &L, int x)
{
lnode **pos = &L;
while (*pos && (*pos)->key <= x) {
pos = &((*pos)->next);
}
*pos = new lnode(x,*pos);
}
Since you are, as you say, a beginner, maybe you should start with the beginner version:
void insert( lnode* &L, int x)
{
if (!L || L->key > x) {
//insert at head
L = new lnode(x, L);
return;
}
lnode *previous=L;
lnode *current=L->next;
while(current && current->key <= x) {
previous = current;
current = current->next;
}
//insert between previous and current
previous->next = new lnode(x, current);
}
Comparing to the previous one shows the benefit of using lnode ** to track the insert position as you search:
no special case for inserting at the head
no separate variables for previous and next
This code should work. Fixed the compilation error and also the traversing logic while printing on top of Matt's code.
#include <iostream>
#include <cassert>
using namespace std;
struct lnode
{
int key;
lnode* next;
lnode(int k, lnode* n = nullptr) :key(k), next(n) {}
};
void insert(lnode* &L, int x)
{
lnode **pos = &L;
while (*pos && (*pos)->key <= x) {
pos = &((*pos)->next);
}
*pos = new lnode(x, *pos);
}
int main()
{
lnode * t = nullptr;
insert(t, 3);
insert(t, 4);
insert(t, 1);
insert(t, 7);
insert(t, -4);
insert(t, 9);
insert(t, 2);
while (t) {
std::cout << t->key << " ";
t = t->next;
}
}
Related
I am fairly new to programming and I am working on a project that involves shifting nodes. How can I get a node at a particular position denoted by user input and increase its value by one? To better explain:
here is my code...or my attempt:
#include <iostream>
struct Node {
int data;
struct Node* next;
};
class LinkedList {
private:
Node* head;
public:
LinkedList()
{
head = NULL;
}
void print()
{
Node* current = head;
if (head != nullptr)
{
do
{
std::cout << current->data << " ";
current = current->next;
}
while (current != head);
}
}
};
int main()
{
LinkedList link_one;
int nodes;
std::cout << "nodes ";
std::cin >> nodes;
for (int index = 0; index < nodes; index++){
link_one.print();
}
link_one.print();
std::cout << std::endl;
}
try traverse
actually there is no need to write a answer, but...I am a newcomer :)
your function place_node should add a parameter:
int place_node(int idx)
then...traverse from your head node for "idx" times, modify the value of current node, that's it.
here's the complete code for function place_node to achieve your goal:
int place_node(int idx) //no need to return
{
Node* current = head;
int count, index = 0;
for(int i=0;i<idx;++i) current = current->next;
current->data+=1;
return 1; // no need to return
}
I write a code for insertion sort for integer data in linked list in c++, I referred to the algorithms on the Internet, and finally took the following code using array as a basic concept for my version.
however, the sorting always ignore my first element,(but all the other element is ordered well).
I have tried checking my loop statement, checking the pointer address while looping (because my key pointer loop at first time didn't go into the judge pointer loop), checking the shifting mechanism while comparing, but I cannot find my logic problem.
(I know someone would said I doesn't provide enough data for you to help me, but I have been checking these things for two days, including asking friends and searching the solutions existed on website. So I really hope someone can answer me without blame, thank you.)
array version(on the internet)
#include <iostream>
void InsertionSort(int *arr, int size){
for (int i = 1; i < size; i++) {
int key = arr[i];
int j = i - 1;
while (key < arr[j] && j >= 0) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
linked list version(by my own)
Node class used in my version
class Node
{
public:
Node()
{
next = NULL;
pre = NULL;
}
Node(int n)
{
data = n;
next = NULL;
pre = NULL;
}
int getData() { return data; }
Node *getNext() { return next; }
Node *getPre() { return pre; }
void setData(int d) { data = d; }
void setNext(Node *n) { next = n; }
void setPre(Node *p) { pre = p; }
private:
int data;
Node *next, *pre;
};
class List
{
public:
List() { list = NULL; }
List(int n) { generate(n); }
void generate(int n)
{
int j;
list = NULL;
for(j = 0;j < n;j ++)
generate();
}
void generate()
{
Node *buf = new Node(rand());
buf->setNext(list); //list->NODE2.next->NODE1.next->NULL
if(list != NULL)
list->setPre(buf);
list = buf;
}
void insertionSort()
{
bool breakByCompare;
Node* keyptr;
Node* judgeptr;// judge is the value that is going to compare with key
int key;
for(keyptr = list->getNext(); keyptr != NULL;
keyptr = keyptr->getNext()){
//if we set list as 5,7,6 ; 6 is key
key = keyptr->getData();//store the key value for the setting after shifting
breakByCompare = 0;
for(judgeptr = keyptr->getPre() ; judgeptr->getPre()!= NULL;
judgeptr= judgeptr->getPre()){
//list: 5,7,6 ; 7 is judge
if(judgeptr->getData() > key){
// 7>6, so we shift 7 to the position which was for 6
judgeptr->getNext()->setData(judgeptr->getData());// list: 5,7,7 ;
cout << judgeptr->getData() << " , " << keyptr->getData() << endl;
}
else{
break;
}
}
judgeptr->getNext()->setData(key);// list: 5,6,7
}
}
void print()
{
Node *cur = list;
while(cur != NULL)
{
cout<<cur->getData()<<" ";
cur = cur->getNext();
}
cout<<endl;
}
private:
Node *list;
};
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#define SIZE 100
int main()
{
srand(time(NULL));
List *l = new List(10);
l->print();
l->insertionSort();
l->print();
}
One of the most important difference between a linked list and an array is that it is sometimes required to handle the first element as a special case.
Here is a fixed version of your sorting method :
void insertionSort()
{
bool breakByCompare;
Node* keyptr;
Node* judgeptr;
int key;
for(keyptr = list->getNext(); keyptr != NULL; keyptr = keyptr->getNext()){
key = keyptr->getData();
breakByCompare = 0;
// I replaced judgeptr->getPre() by judgeptr in the condition
// to allow the backward loop to go until the root
for(judgeptr = keyptr->getPre() ; judgeptr != NULL; judgeptr= judgeptr->getPre()){
if(judgeptr->getData() > key){
judgeptr->getNext()->setData(judgeptr->getData());
cout << judgeptr->getData() << " , " << key << endl;
}
else break;
}
// Here is the special case : we must support a null judgeptr
// and replace its next element by the list
if (judgeptr) judgeptr->getNext()->setData(key);
else list->setData(key);
}
}
I am tasked with implementing a new class function called bool List::largest_value(int &largest) within a given class List. The instruction is:
If the list is not empty, put the largest value in the largest
parameter and return true. If the list is empty, return false.
My question is, how do I find the largest value within a parameter?
Here is what I have so far for bool List::largest_value(int &largest):
// Fill in the functions at the bottom of this file
//
#include <iostream>
#include <climits>
using namespace std;
#include "list.h"
// on some machines member variables are not automatically initialized to 0
List::List()
{
m_head = NULL;
}
// delete all Nodes in the list
// since they are dynamically allocated using new, they won't go away
// automatically when the list is deleted
// Rule of thumb: destructor deletes all memory created by member functions
List::~List()
{
while (m_head)
{
Node *tmp = m_head;
m_head = m_head->m_next;
delete tmp;
}
}
// always insert at the front of the list
// Note: this works even in the SPECIAL CASE that the list is empty
void List::insert(int value)
{
m_head = new Node(value, m_head);
}
// iterate through all the Nodes in the list and print each Node
void List::print()
{
for (Node *ptr = m_head; ptr; ptr = ptr->m_next)
{
cout << ptr->m_value << endl;
}
}
void List::compare(int target, int &less_than, int &equal, int &greater_than)
{
Node *temp = m_head;
less_than = 0;
equal = 0;
greater_than = 0;
while(temp != NULL)
{
if(temp->m_value > target)
{
greater_than++;
}
else if(temp->m_value < target)
{
less_than++;
}
else if(temp->m_value == target)
{
equal++;
}
temp = temp-> m_next;
}
}
bool List::largest_value(int &largest)
{
Node *temp = m_head;
largest = INT_MIN;
if(temp == NULL)
{
return false;
}
while(temp != NULL)
{
if(temp->m_value > largest)
{
largest = temp->m_value;
}
temp = temp->m_next;
}
return true;
}
Here is the given class List:
class List
{
public:
List();
~List();
void insert(int value); // insert at beginning of list
void print(); // print all values in the list
void compare(int target, int &less_than, int &equal, int &greater_than);
bool largest_value(int &largest);
private:
class Node
{
public:
Node(int value, Node *next)
{m_value = value; m_next = next;}
int m_value;
Node *m_next;
};
Node *m_head;
};
Main.cpp:
#include <iostream>
using namespace std;
#include "list.h"
int main()
{
List list;
int value;
// read values and insert them into list
while (cin >> value)
{
list.insert(value);
}
int largest;
bool result = list.largest_value(largest);
if (result == false)
{
cout << "empty list" << endl;
return 1;
}
else
{
cout << "The largest value you entered is: " << largest << endl;
}
}
My code compiles and runs, however I keep receiving the output empty list. I honestly have no idea what I need to change in my bool List::largest_value(int &largest)function. I am still very new to linked lists. Any help would be appreciated
I have a program where I have a binary tree, represented as a structure with two pointers and a root. I then want to enter n elements (denoted by the br variable) as values of the nodes of the tree. Then I enter these elements using the add(param1,...) function. However when I press return key, after I have entered all of them, the program crashes. I would like to ask why this happens?
// TreeGraph.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
struct elem {
char key;
elem *left, *right;
} *root = NULL;
void add(int n, elem * &t);
int num,br,i;
int main()
{
cout << "Въведете брой елементи\n";
cin >> br;
cout << "Въведете стойнсотите на листата на дървото\n";
while (i != br) {
cin >> num;
add(num, root);
i++;
}
return 0;
}
void add(int n, elem * &t) {
if (t) {
t = new elem;
t->key = n;
t->left = t->right = NULL;
}
else {
if (t->key < n)
add(n, t->right);
else
add(n, t->left);
}
}
The problem is not an infinite loop. You are dereferencing a null pointer, so the program crashes.
In this code:
void add(int n, elem * &t) {
if (t) {
t = new elem;
t->key = n;
t->left = t->right = NULL;
}
else {
if (t->key < n)
add(n, t->right);
else
add(n, t->left);
}
}
Your condition for adding the node is incorrect. It should be if (!t). The location of a new node in a binary search tree must be as the child of a node with at least one null child pointer. To add the node, you need the recursion to get to one of these null pointers and then add the node there.
Think about what happens when you pass the initially-null root to the add function. The condition in the first if statement is false, so when you try to check the condition if (t->key < n), you are attempting to access the key field of a non-existent object.
I am a java programmer teaching myself C++.
While writing a binary tree I found that my program did not "add" values to the tree.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
class BinaryTree {
struct Node {
public:
int val;
Node* left;
Node* right;
Node::Node(int v) {
val = v;
left = nullptr;
right = nullptr;
}
};
public:
BinaryTree() {
root = nullptr;
}
int size = 0;
int length();
bool BinaryTree::add(int v);
void printTree();
private:
void printTree(Node* n);
Node* root;
};
bool BinaryTree::add(int v) {
if (root == nullptr) {
root = new Node(v);
++size;
return true;
}
Node* ref = root;
cout << ref->val;
while (ref != nullptr) {
if (v < ref->val) {
ref = ref->left;
}
else if (v > ref->val) {
ref = ref->right;
}
else if (v == ref->val) {
return false;
}
}
Node *newNode = new Node(v);
ref = newNode;
++size;
return true;
}
void BinaryTree::printTree() {
printTree(root);
}
void BinaryTree::printTree(Node* n) {
if (n == nullptr) {
return;
}
printTree(n->left);
cout << n->val << endl;
printTree(n->right);
}
int BinaryTree::length() {
return size;
}
void main(int i) {
BinaryTree tree = BinaryTree();
tree.add(6);
tree.add(3);
tree.add(5);
tree.add(7);
tree.add(1);
tree.add(0);
tree.add(0);
tree.printTree();
cout << "binary tree sz is " << tree.length() << endl;
while (true) {};
}
I have been unable to find the problem in regards to why the tree doesn't commit new Nodes except the root.
I used "new" in the code when writing (ref = new Node) etc in the adds method because this should prevent the new Node from being destroyed once it leaves the scope.
If anyone can enlighten me on this issue I will be greatly thankful.
To add a node to the tree you have to link it to some existing node, as in
existing_node->{left or right} = new_node;
Once ref becomes nullptr, you don't have a valid existing node anymore, and it is too late to do anything. Instead, traverse the tree as long as ref->{left or right} is valid:
if (v < ref->val) {
if (ref->left) {
ref = ref->left;
} else {
ref->left = newNode;
return true;
}
}
// etc for v > ref->val