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.
Related
This program is basically just suppose to shuffle a deck of cards. The cards are stored in a doubly linked list, so 52 nodes. I'm getting a read access error in the getNode function, but I'm pretty sure my loop is correct, so I think the error is stemming from somewhere else. Maybe the swap function. My first step is getting pointers to the nodes that I'm trying to swap.
So I made a function, and I'm pretty sure it's right, except I'm wondering if I should be returning *traverseP instead of just traverseP. I don't think so, because I want to return a pointer to the node, not the value inside the node.
template<class T>
typename ReorderableList<T>::Node *ReorderableList<T>::getNode(int i) const
{
int count = 0;
for (Node *traverseP = firstP; traverseP != NULL; traverseP = traverseP->nextP) {
if (count == i)
return traverseP;
count++;
}
return NULL;
}
Next I made a swap function that take two ints, they represent the values I'm passing into the getNode function
template<class T>
void ReorderableList<T>::swap(int i, int j)
{
// Get pointers to ith and jth nodes.
Node *iPtr = getNode(i);
Node *jPtr = getNode(j);
//create temp Node and store the pointers
Node *temp = new Node;
temp = iPtr->prevP;
temp = iPtr->nextP;
//adjust the iPtr next/prev pointers
iPtr->prevP = jPtr->prevP;
iPtr->nextP = jPtr->nextP;
//adjust the jPtr next/prev pointers
jPtr->prevP = temp->prevP;
jPtr->nextP = temp->prevP;
//I'm a little unclear on these lines. I think they're checking if
//iPtr and jPtr have null pointers. I've tried making them equal jPtr and
//iPtr and that strangly didn't make any difference.
if (iPtr->prevP)
iPtr->prevP->nextP = jPtr;
if (iPtr->nextP)
iPtr->nextP->prevP = jPtr;
if (jPtr->prevP)
jPtr->prevP->nextP = iPtr;
if (jPtr->nextP)
jPtr->nextP->prevP = iPtr;
delete temp;
}
This is the shuffle function where this whole shabang kicks off
template<class T>
void randomShuffle(ReorderableList<T> &list, int n)
{
int randNum = 0;
for (int i = n-1; i > 0; i--)
{
randNum = (rand() & (i + 1));
if (randNum > i)
std::swap(randNum, i);
list.swap(randNum, i);
}
}
I've checked a couple different resources for the swap function and found two that both claimed they were correct, but they looked different to me.
Resource 1
Resource 2
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.
I have a short recursive function to write, and I am having an issue with my function returning seg fault 11 when I run it through g++. I am pretty bad at recursion, and just starting to learn it. Please let me know if you have any suggestions! The goal is to count how many nodes have a value larger than the inputed value "m" .Here is my code:
int LinkedList::countOccurrencesMoreThanRec(int m)
{
// first do the base cases that do not require recursion
if (head == NULL)
return -1;
int answer = 0;
if ((head -> getNext()) == NULL)
{
if ((head -> getValue()) > m)
answer ++;
return answer;
}
// if none of those were true, call the recursive helper method
Node *BatMan = head;
answer = countOccurrencesMoreThan(BatMan, m);
return answer;
}
/* countOccurrencesMoreThan
*
* private recursive method.
* TODO: fill in this method
*/
int LinkedList::countOccurrencesMoreThan(Node *h, int m)
{
// check for the base case(s)
int answer = 0;
if ((h -> getNext()) == NULL)
{
if ((h -> getValue()) > m)
answer++;
return answer;
}
// smaller case
Node *Bane = h;
answer = countOccurrencesMoreThan(Bane, m);
return answer;
// general case
}
Your comments are lying.
// smaller case
Node *Bane = h;
Here, you're setting Bane to the same value that was passed in to your function. You're not actually testing the next item in the list, you're doing the same list again.
This isn't the only problem in your code, but it will at least help with the question you asked.
One of the first questions with recursion should always be, do I need recursion? When iterating elements of a LinkedList there is absolutely no need to recurse.
Secondly, I strongly advise against rolling your own linked list class as the time it takes to write your own would be better spent learning libraries such as the STL which give you great data structures out of the box for free (that other colleagues understand!).
However to accomplish what you are trying to achieve recursively, you could either make the "answer" int a class member, a global variable (shudder) or pass the answer to each invocation of the function (passing zero in the first instance), but I cannot stress enough that the recursive approach is not the right approach for this problem. The answer variable has no place in a LinkedList class for a start, global variables are almost always evil, and passing around a value you're simply incrementing is inefficient and confusing.
int LinkedList::countOccurrencesMoreThan(Node *h, int m, int answer)
{
if( h->getValue() > m ) {
++answer;
}
if (h -> getNext() == NULL)
{
return answer;
}
countOccurrencesMoreThan( h->getNext(), m, answer);
}
Here is a better non recursive implementation with a simple LinkedList class:
void LinkedList::countOccurrencesMoreThan(int value) {
Node* node = this->head;
int occurrences = 0;
while(node != NULL) {
if( node->getValue() > v ) {
++occurrences;
}
node = node->getNext();
}
std::cout << "occurrences = " << occurrences << std::endl;
}
I want to make an implementation of stack, I found a working model on the internet, unfortunately it is based on the idea that I know the size of the stack I want to implement right away. What I want to do is be able to add segments to my stack as they are needed, because potential maximum amount of the slots required goes into 10s of thousands and from my understanding making the size set in stone (when all of it is not needed most of the time) is a huge waste of memory and loss of the execution speed of the program. I also do not want to use any complex prewritten functions in my implementation (the functions provided by STL or different libraries such as vector etc.) as I want to understand all of them more by trying to make them myself/with brief help.
struct variabl {
char *given_name;
double value;
};
variabl* variables[50000];
int c = 0;
int end_of_stack = 0;
class Stack
{
private:
int top, length;
char *z;
int index_struc = 0;
public:
Stack(int = 0);
~Stack();
char pop();
void push();
};
Stack::Stack(int size) /*
This is where the problem begins, I want to be able to allocate the size
dynamically.
*/
{
top = -1;
length = size;
z = new char[length];
}
void Stack::push()
{
++top;
z[top] = variables[index_struc]->value;
index_struc++;
}
char Stack::pop()
{
end_of_stack = 0;
if (z == 0 || top == -1)
{
end_of_stack = 1;
return NULL;
}
char top_stack = z[top];
top--;
length--;
return top_stack;
}
Stack::~Stack()
{
delete[] z;
}
I had somewhat of a idea, and tried doing
Stack stackk
//whenever I want to put another thing into stack
stackk.push = new char;
but then I didnt completely understand how will it work for my purpose, I don't think it will be fully accessible with the pop method etc because it will be a set of separate arrays/variables right? I want the implementation to remain reasonably simple so I can understand it.
Change your push function to take a parameter, rather than needing to reference variables.
To handle pushes, start with an initial length of your array z (and change z to a better variable name). When you are pushing a new value, check if the new value will mean that the size of your array is too small (by comparing length and top). If it will exceed the current size, allocate a bigger array and copy the values from z to the new array, free up z, and make z point to the new array.
Here you have a simple implementation without the need of reallocating arrays. It uses the auxiliary class Node, that holds a value, and a pointer to another Node (that is set to NULL to indicate the end of the stack).
main() tests the stack by reading commands of the form
p c: push c to the stack
g: print top of stack and pop
#include <cstdlib>
#include <iostream>
using namespace std;
class Node {
private:
char c;
Node *next;
public:
Node(char cc, Node *nnext){
c = cc;
next = nnext;
}
char getChar(){
return c;
}
Node *getNext(){
return next;
}
~Node(){}
};
class Stack {
private:
Node *start;
public:
Stack(){
start = NULL;
}
void push(char c){
start = new Node(c, start);
}
char pop(){
if(start == NULL){
//Handle error
cerr << "pop on empty stack" << endl;
exit(1);
}
else {
char r = (*start).getChar();
Node* newstart = (*start).getNext();
delete start;
start = newstart;
return r;
}
}
bool empty(){
return start == NULL;
}
};
int main(){
char c, k;
Stack st;
while(cin>>c){
switch(c){
case 'p':
cin >> k;
st.push(k);
break;
case 'g':
cout << st.pop()<<endl;
break;
}
}
return 0;
}
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)
}