Linked list within a linked list (2D linked list?) - c++

I have a txt file that contains a matrix of chars(1 or 2 at each position in matrix)
C P O Hr S A
N Hw N L Z R
W T O O Ta A
I O S S E T
Something like this. What I managed to do is to create a linked list and store every element of this matrix in that list (separately).
struct DataNode{
char data[3];
struct DataNode *nextData;
};
void initNode(DataNode *head, char x[3]) {
for(int i=0; i<3; i++)
head->data[i]=x[i];
head->nextData=NULL;
}
void addNode(DataNode *head, char x[3]) {
DataNode *newNode = new DataNode;
for(int i=0; i<3; i++)
newNode->data[i]=x[i];
newNode->nextData=NULL;
DataNode *curr = head;
while(curr) {
if(curr->nextData==NULL) {
curr->nextData = newNode;
return;
}
curr = curr->nextData;
}
}
int main() {
char input[3];
if(in.is_open()) {
in>>input;
initNode(head,input);
for(int i=0; i<3; i++)
dieSide[i]=input[i];
while(in>>input) {
addNode(head,input);
}
in.close();
}
}
So far, this works as it should, and I guess I'm happy with it.
What I need now, it another linked list, where the elements would still be char[3] types, but there has to be first a list containing a row of 6 elements, and then, another list, containing all of those 6 element lists.
I hope I made myself clear about my wishes.
I'm thinking about creating another struct, with next pointers to each of two active lists, but still not sure about that idea.
How would you recommend me to go about doing this?
EDIT
Just a little help, please...
I have re-implemented all of the functions to suit the struct you (#Daniel) suggested, and they appear to work. However, I need a way to "reset" the DataNode* I want to use for creating small lists. This way I only get entire matrix printed as many times as there are lines in the file.
What I have is>
char input[3];
int counter=0;
struct DataNode *head = new DataNode; //creates a list of all elements
struct DataNode *head_side = new DataNode; //want to use this one to create smaller lists
struct DieSideNode *head_die = new DieSideNode; //creates a list of smaller lists
if(in.is_open()) {
in>>input;
initNode(head,input);
initNode(head_side, input);
counter++;
while(in>>input) {
addNode(head,input);
addNode(head_side, input);
counter++;
if( counter == 6 ) {
initSide(head_die, head_side);
head_side=0;
}else if(counter%6==0) {
addSide(head_die, head_side);
head_side=0;
}
}
in.close();
}
This code successfully extracts first six elements, and puts it as a first element of the list, but then it stops working there.

I'll give you a little hint to get started. As you know, a linked-list node contains some data and a pointer to the next element of the list. What you call a "2-d linked list" would actually simply be implemented as a linked-list of linked-lists. Each node in the list points to another linked list. So you will need to define a new type:
struct ListNode {
DataNode* dataRowHead;
struct ListNode* nextRow;
};
What you are trying to do would have 6 ListNodes connected as a linked-list. Each ListNode contains a pointer to a DataNode which is the head of a linked-list for the row that corresponds to the ListNode that points to it.
I will leave the implementation up to you.

Related

Linked list without struct

Can anyone help me with a singly linked list? I know how to do it with struct, but now i wanna know how to do it with only arrays and pointers without struct or nodes.Algorithms please thank you.
#include <iostream>
using namespace std;
const int size=5;
int data[size];
int *mem;
int add[size];
int top = -1;
void AddLast(int value)
{
if(top==-1)
{
top=data[value];
}
else
{
top++;
top=data[value];
}
}
void print()
{ cout << "Queue: ";
for(int i = 0; i != top; i = (i + 1) % size)
{
cout << data[i] << "->";
}
cout << endl;
}
int main()
{
AddLast(2);
print();
AddLast(3);
print();
AddLast(4);
print();
cin.get();
return 0;
}
I want to addlast, addfirst, and add sorted... is this the way?
You can't do it with only one array, you need at least two: One for the data and one for the links. If you don't want to use structures at all (though I don't really see the reason for it) you could have multiple data arrays.
The data array contains the actual data, it's nothing special with it. The link array contains indexes to the data array, where each index is a "next" pointer.
For example, lets say you want to have a linked list of integers, and you have three integers in the list (their values are irrelevant), lets call that data array d, then you have d[0], d[1] and d[2]. The first node in the list is d[1], followed by d[0] and last d[2]. Then you need a head variable, which tells which index is the head of the list, this head variable is initialized to 1 (and "points" to d[1]). Then we have the link array, lets call it l, since the head is "pointing" to 1 we fetch l[1] to get the next node, the contents of l[1] is 0 which tells us the next node is d[0]. To get the next node we check l[0] which gives us 2 for d[2]. The next link, l[2] could be -1 to mark the end of the list.
Of course, the data array(s) and the link array needs to be of the same size.
An array s of structs with members A, B, C, can be emulated by three arrays a, b and c, where e.g. a[i] represents s[i].A, and so forth. So that's your requirement of no structs. Then doing a linked list with arrays, i.e. with indices instead of pointers, is mere notation; the concepts are exactly the same. But you might look up the technique of using a free list, a list of available logical nodes; this allows you to free nodes as well as allocate them, in a simple way.
There is a (ugly) way to do a linked list with arrays.
Here is an example of how you might do something with arrays but I would never recommend even thinking about doing it.
template<class T>
typedef char[sizeof(T) + sizeof(uintptr_t)] listNode;
template<class T>
listNode<T>* getNext(const listNode<T>& x){
return (listNode<T>*)(((char*)x)[sizeof(T)]); //notice how you have to increment the pointer address
}
template<class T>
T& getValue(listNode<T>& x){
return (T) x;
}
That's way too many casts. It's less ugly if you make an array of two pointers and just cast the first value in a pointer on what you care about but that's still not what I would recommend.
This is a hack of sorts might help with your curiosity.
It is similar in implementation to how linked lists are typically implemented with struct.
#include<stdio.h>
#include<stdlib.h>
int * base = NULL;
int ** current = NULL;
void add(int num)
{
if(base==NULL)
{
base = (int*)malloc(sizeof(int)*3);
base[0] = num;
current = (int**)(base+1);
current[0] = NULL;
}
else
{
current[0] = (int*)malloc( sizeof(int)*3 );
current[0][0] = num;
current = (int**)(*current+1);
current[0] = NULL;
}
}
void show()
{
if(base != NULL)
{
int * data = base;
int ** tmp = (int**)(base+1);
if(tmp[0]==NULL)
printf("%d\n",data[0]);
else
{
do
{
printf("%d ",data[0]);
data = tmp[0];
tmp = (int**)(data+1);
}while(tmp[0]!=NULL);
printf("%d\n",data[0]);
}
}
}
int main()
{
int choice,num;
do
{
scanf("%d",&choice);
switch(choice)
{
case 1:scanf("%d",&num);
add(num);
break;
case 2:show();
}
}while(1);
return 0;
}
It is possible to add other function like addFirst() or addSorted() but will require some more pointer manipulation, for which I don't possess the dedication right now.

Knights tour passing arrays to linked list and more

I am currently working on the knights tour project. My goal ultimately is to create this project using backtracking (by implementing stack) and Warnsdorff's heuristic. I am not allowed to use any libraries that has stack functions already created such as push and pop. I am also not allowed to resolve the problem using recursion. With that being said, I am pretty stuck right now and my next big milestone would be to solve the problem by only backtracking.
I am not going to sugar coat this at all, but right now my code is one big mess. I have pretty much created all the tools I need to make the program run, but now I just need to put all the pieces together.
The following is my code:
#include<iostream>
using namespace std;
class linkedList{
struct node
{
int data;
node *next;
};
node *top;
public:
linkedList()
{
top = NULL;
}
void push(int coordinates)
{
node *p = new node;
p -> data = coordinates;
p -> next = top;
top = p;
}
int pop()
{
node *temp = top;
top = temp -> next;
return temp -> data;
}
int display()
{
cout<<"\n"<< top -> data;
top = top-> next;
}
};
// Linked List ================================================
class Board{
public:
int next;
int status[8][8];
Board();
void print();
};
Board::Board(){
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
status[i][j] = -1;
}
}
}//constructor
void Board::print(){
for (int j=0; j<8; j++){
for(int i=0; i<8;i++){
cout << status[i][j] << " ";
}
cout << endl << endl;
}
}
//BOARD========================================================
class Knight {
private:
public:
int vertical[8] = {2,-2,1,-1,2,-2,1,-1}; // possible knight moves x coordinate
int horizontal[8] = {1,1,2,2,-1,-1,-2,-2}; // possible knight move y coordinate
int counter;
int currentPos[2];
Knight();
};
Knight::Knight(){
currentPos[0] = 7; // x-coordiante
currentPos[1] = 7; // y-coordinate
counter = 0;
}//constructor
/* Use this later
int Knight::changePos(int i,int j){
Knight::currentPos[0] = (Knight::currentPos[0] + i);
Knight::currentPos[1] = (Knight::currentPos[1] + j);
counter++;
return counter;
*/
int main(){
Board b;
Knight k;
b.status[k.currentPos[0]][k.currentPos[1]] = k.counter;
b.print();
linkedList obj;
int coordinates;
}
So my idea at this point is to do the following:
Create a loop that will change the current position of the knight using the horizontal and vertical array (the possible moves of the knight). Once the position has changed, the counter will increment and the -1 will be replaced with the current counter value. When the knight has been moved, the information of the new coordinates needs to be passed to the linked list using the push function I created. In order to do this, I need to figure out a way to pass an array (x,y) or multiple values to push. I will also need to create some bound checking which I am currently working on (make sure the knight doesn't move to a spot that he has been to and doesn't go off the board). Then finally if the knight does get stuck, I need to use the pop function I created to go back a step and try to continue with a different move.
I really really appreciate any help, corrections, places to start or other suggestions that are given! I am so stuck..
Let me get this straight. You're having difficulty implementing the Stack structure that allows you to undo moves.
C++ isn't really my forte but here's how I'd approach the Stack
Define a struct that stores the coords (and possibly backtracking info)
Update 'node' to store a pointer to an instance of your new struct.
Update the 'push()' definition to use it.
Update the 'pop()' definition to return it.
Profit...

Returning Objects in C++ (Binary Tree)

Disclaimer: This is for an assignment. I would like pointers in the right direction (no pun intended) rather than straight code solutions.
I'm attempting to implement a max winner tree (a binary tree in which the node's value is the max of it's children's values, so that the root eventually has the max value of all the bottom leaves). My current MaxWinnerTree initializes a tree full of -1s, just as place holders for values to be inserted later on.
MaxWinnerTree.cpp
#include "MaxWinnerTree.h"
MaxWinnerTree::MaxWinnerTree(int elements)
{
int size = 1;
while (size<elements)
size = size * 2; //gets closest power of 2 to create full bottom row
*a = new Node[size];
for (int i = (2*elements-1); i>0; i--)
{
if (i > elements-1) //leaf
{
//Create new nodes with data -1, store pointer to it in array
*a[i] = (newNode(i,-1,NULL,NULL,NULL));
}
else // not leaf
{
//Create node with data = max of children, store pointer
*a[i] = newNode(i,-1,a[i*2],a[i*2 +1], NULL); //create
a[i]->data = max(a[i*2]->data, a[i*2+1]->data); //gets max
a[i]->right->parent = a[i];
a[i]->left->parent = a[i];
}
}
}
Node MaxWinnerTree::newNode(int key, int data, Node *left, Node *right, Node *parent)
{
Node *n = new Node;
key = key;
data = data;
left = left;
right = right;
parent = parent;
return *n;
}
In my Main, I attempt to create a MaxWinnerTree object to perform actions on (insertion, etc), but I know the way I'm doing it is incorrect. My MaxWinnerTree method doesn't return a value, and the only objects I'm creating are an array and then a linked mess of nodes. As I type this, I'm going to go back and attempt to return a linked list as my tree and go from there, but is this the direction that I should be going in?
Main.cpp
int main (){
bool quit;
int command, elements, binSize;
cout<<"Welcome to assignment 6!"<<endl;
while (!quit)
{
cout<<"Choose an option for the test: 1-> First fit, 2-> Best Fit, 3-> Quit"<<endl;
cin>>command;
if(command==1)
{
cout<<"First Fit!";
cout<<"Enter number of objects: ";
cin>> elements;
cout<<"\n Enter capacities of bins: ";
cin>> binSize;
cout<<"\n";
MaxWinnerTree* tree = new MaxWinnerTree(elements); //Throws x86 error, also throws error when not decared as a pointer
tree->insert(7);
//Irrelevant rest of non-applicable code
In essence, what do I need to do differently to get a tree object that I can operate on after calling my constructor?
Also: I'm shaky on pointers, so if something looks off or bad practice, please let me know.

singly linked chain printing c++

I am trying to pick my chain in the format {1,2,3,4,etc}. You can find the header file below which will have the layout of the nodes. I am just confused on how I should go about cycling through my list to print out Item.
Any guidance would be greatly appreciated!
set.h
using namespace std;
#include <iostream>
class Set
{
private:
struct Node
{
int Item; // User data item
Node * Succ; // Link to the node's successor
};
unsigned Num; // Current count of items in the set
Node * Head; // Link to the head of the chain
public:
// Return information about the set
//
bool is_empty() const { return Num == 0; }
unsigned size() const { return Num; }
// Initialize the set to empty
//
Set();
// Insert a specified item into the set, if possible
//
bool insert( int );
// Display the set
//
void display( ostream& ) const;
};
Here are two recommendations: 1) Sort the list first, then print all nodes; 2) Create another list (indices) to the data and sort those links (don't need data in those nodes).
Sorting List First
An often used technique is to order the nodes in the order you want them printed. This should involve changing the link fields.
Next, start at the head node and print each node in the list (or the data of each node in the list).
Using an Index list
Create another linked list without the data fields. The links in this list point to the data fields in the original list. Order the new list in the order you want the nodes printed.
This technique preserves the order of creation of the first list and allows different ordering schemes.
Changing Links
Since you're writing your own Linked List, the changing of the links is left as an exercise as I'm not getting paid to write your code. There are many examples on SO as well as the web for sorting and traversing linked lists.
You just want to do something like this:
void Set::display(ostream &out) const {
for(int i=0; i<Num; i++) {
out << Pool[i] << " ";
}
out << endl;
}
An ostream behaves as cout would.
It's hard to get your question. If you want to print the array to screen you should consider writing a display() like:
#include <iostream>
#include <iterator>
void Set::display() const {
ostream_iterator<int> out_it (cout," ");
copy(Pool,Pool+Num,out_it);
cout << endl;
}
or if you want to write to a ostream& (as it is pointed out in the answer by #alestanis)
#include <iostream>
#include <iterator>
void Set::display(ostream &out) const {
ostream_iterator<int> out_it (out," ");
copy(Pool,Pool+Num,out_it);
out << endl;
}
Without testing, I'd do something like this. (Assumes the last node has Succ set to NULL, as I would recommend it does.)
void LoopList(struct Node *head)
{
for (struct Node *p = head; p != null; p = p->Succ)
{
// Do whatever with this node
Print(p);
}
}
I think I was over thinking it. Anyway here is what I ended up doing. Now I just need to add some formatting for the commas and im all set.
Node * Temp;
Temp = new (nothrow) Node;
Temp = Head;
out << "{";
while(Temp->Succ)
{
out << Temp->Item;
Temp = Temp->Succ;
}
out << '}' << endl;
Suppose your list is cyclical, you can use this:
struct Node *n = begin;
if (n != NULL) {
//do something on it
...
for (n = begin->Succ; n != begin; n = n->Succ) {
}
}
or
struct Node *n = begin;
if (n != NULL) {
do {
//do something
...
n = n->Succ;
} while (n != begin)
}

Constructor for LinkedList to receive an array C++

Attempting to write a constructor for LinkedList to be initialised with an array of integers.
The program would call linked(array); which will add all the values within the array in to a linkedlist.
LinkedList::LinkedList(int array[])
{
headPtr->setData(array[0]); //setData method stores the integer at position 0 inside headPtr
Node *currentPtr = headPtr;
for (int i = 0; i < array.length(); ++i) //for loop to add the integers to the next node
{
currentPtr->setNext(new Node(array[i])); //creates a new node with the integer value of array position i
}
}
the trouble is the array.length (coming from Java) and I don't think the array length can be obtained this way?
I would suggest you to use iterator idiom, and make the constructor a templated constructor as:
class LinkedList
{
//...
public:
template<typename FwdIterator>
LinkedList(FwdIterator begin, FwdIterator end)
{
for (;begin != end; ++begin)
{
//treat begin as pointer, and *begin as dereferenced object
}
}
//...
};
And then you can use it as:
int arr[] = {1,2,3,4,5,6,7,8,9,10};
LinkedList lnklist(arr, arr+10);
Not only that. If you've std::vector<int>, then you can also use it to construct the linked list, as:
std::vector<int> v;
//..
LinkedList lnklist(v.begin(), v.end());
So using iterator idiom gives you this much power and flexibility. :-)
As Nawaz explained, going with iterator solution is better. But if you want to go with array ( static one though), then compiler can automatically deduce the size for you.
template<size_t size>
LinkedList::LinkedList(int (&array)[size])
{
headPtr->setData(array[0]); //setData method stores the integer at position 0 inside headPtr
Node *currentPtr = headPtr;
for (int i = 0; i < size++i) //for loop to add the integers to the next node
{
currentPtr->setNext(new Node(array[i])); //creates a new node with the integer value of array position i
}
}
Can be called as shown below.
int arr[] = {1,2,3,4,5,6,7,8,9,10};
LinkedList lnklist(arr);
Like others have said, it is not only important but vital that you get a good introductory C++ book and read it from front to back, simultaneously trying to forget what you know about Java while in C++ mode. They are not remotely similar.
Now to your problem, it can be solved by using std::vector and using its size method:
// put this with the other includes for your file
#include <vector>
LinkedList::LinkedList(const std::vector<int>& array)
{
headPtr->setData(array[0]); //setData method stores the integer at position 0 inside headPtr
Node *currentPtr = headPtr;
for (int i = 0; i < array.size(); ++i) //for loop to add the integers to the next node
{
currentPtr->setNext(new Node(array[i])); //creates a new node with the integer value of array position i
}
}
If you don't want to use vector, you have to pass in the size of the array to the function:
LinkedList::LinkedList(int array[], int arrlen)
{
headPtr->setData(array[0]); //setData method stores the integer at position 0 inside headPtr
Node *currentPtr = headPtr;
for (int i = 0; i < arrlen; ++i) //for loop to add the integers to the next node
{
currentPtr->setNext(new Node(array[i])); //creates a new node with the integer value of array position i
}
}
But it is recommended to use the vector version.