included is my entire program...

i know exactly what the problem i am having with this is, i just cant figure out the logic to fix it... ive tried about 10 different things so far.

I have it so you can input which position you start at... then go around the circle, the only problem is that the starting position is the lowest position held then it will repeat other nodes.

ie: if you start at position 5 and have 15 people in a circle... once 15 is hit, it resets back to number 5 ( not 1)... how do i change this so that it will read from say 1 to 15 starting at 5 instead of 5 to 15 starting at 5.

the code snippet where i think the problem is located is at the very bottom.

thanks alot.

#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

	

struct node	{	
	
       	int position;	
       	node * next;
		node * prev;
	
};




class circularll {
		
        public:
	
    		void create (int, int);
			void run (int, int, int);
			node * head;
            node * tail;
			
	   private:
	
};




void circularll::create (int people, int startPos) { 
	
 		int x, y = 1;
		head = tail = NULL;
			
		for (x = startPos; x < (people + startPos); x++) {
	
    		
            if (x == startPos) { 
	
    		    node * temp = new node;
				temp -> prev = NULL;
				temp -> next = NULL;
				temp -> position = x;
				head = tail = temp;
	
    		}

			else {
	
    			node * temp = new node;
				node * curr = head = tail;
				
                while(curr -> next != NULL) {
	
    				curr = curr -> next;
	
    			}

				if (x > people) {
                
                   temp -> position = y;
				   temp -> next = NULL;
				   temp -> prev = curr;
				   curr -> next = temp;		
                                          
                }
    
                else {
                 
                   temp -> position = x;
				   temp -> next = NULL;
				   temp -> prev = curr;
				   curr -> next = temp;
				
               }
            
           
            }
            
           y++;
           
    	}
	
    	node * end = head = tail;
	
    	while (end -> next != NULL) {
	
    		end = end -> next;
	
    	}
	
    	end -> next = head = tail;
		head -> prev = end;
		tail -> prev = end;
	
}



void circularll::run (int people, int passBy, int startPos) {	
	
      	int x, i;
      	node * curr = head = tail;
		
        for (x = 1; x < people; x++) {
	
    		for (i = 1; i <= passBy; i++) { 
	
    		    curr = curr -> next;
	
    		}

			node * out = curr;
			node * before = curr -> prev;
			node * after = curr -> next;
			
            cout << "The person who was sitting at seat " << out -> position << " was killed." << endl;
			
            before -> next = after;
			after -> prev = before;
			curr = after;
			delete out;
	
        }
	    
	    cout << endl;
    	cout << "Josephus was sitting at seat: " << curr -> position << endl << endl;

}




int main() {
	

     int people, passBy, startPos;
	

     menu: // start of menu
     
     cout << "How many people are there? (Maximum of 50) ";
     cin >> people;

     if (people > 50) {

          cout << "Invalid entry" << endl;
          goto menu; // returns you to the beginning of the menu

     }
     
     cout << endl << endl;
     cout << "Which position would you like to start with? " ;
     cin >> startPos;
     cout << endl << endl;
     
     cout << "How many people do you want to skip each round?  ";
     cin >> passBy;
	 cout << endl << endl;

     circularll josephus;
     josephus.create (people, startPos);  
     josephus.run (people, passBy, startPos);

cin >> people;

     return 0;

}
void circularll::create (int people, int startPos) { 
	
 		int x, y = 1;
		head = tail = NULL;
			
		for (x = startPos; x < (people + startPos); x++) {
	
    		
            if (x == startPos) { 
	
    		    node * temp = new node;
				temp -> prev = NULL;
				temp -> next = NULL;
				temp -> position = x;
				head = tail = temp;
	
    		}

			else {
	
    			node * temp = new node;
				node * curr = head = tail;
				
                while(curr -> next != NULL) {
	
    				curr = curr -> next;
	
    			}

				if (x > people) {
                
                   temp -> position = y;
				   temp -> next = NULL;
				   temp -> prev = curr;
				   curr -> next = temp;		
                                          
                }
    
                else {
                 
                   temp -> position = x;
				   temp -> next = NULL;
				   temp -> prev = curr;
				   curr -> next = temp;
				
               }
            
           
            }
            
           y++;
           
    	}
	
    	node * end = head = tail;
	
    	while (end -> next != NULL) {
	
    		end = end -> next;
	
    	}
	
    	end -> next = head = tail;
		head -> prev = end;
		tail -> prev = end;
	
}

Dani AI

Generated

This thread's symptom — starting at position 5 but the sequence wrapping to 5 instead of 1 — comes from two related problems in the original code: building the list with positions starting at startPos instead of always 1..N, and accidentally overwriting pointers when you do chained assignments (for example using node *curr = head = tail; or similar). The fix is simple and robust: always create nodes numbered 1..people, close the ring, then find the start node by advancing (startPos - 1) steps from head. In run() set your working pointer to that start node and then perform the pass/kill loop. Also validate startPos to the range 1..people.

Notes tied to other replies: 's single-linked approach is a good minimal design to find the start node and iterate; is correct to call out memory leaks — every node you new must eventually be deleted when removed (and delete the final node too).

A concise corrected approach (keeps your original semantics: passBy = number of people to advance before removing the current node; passBy==0 removes the start node):

void circularll::create(int people, int startPos) {
    if (people <= 0) { head = tail = nullptr; return; }
    head = tail = nullptr;
    for (int i = 1; i <= people; ++i) {
        node* tmp = new node;
        tmp->position = i;
        tmp->next = tmp->prev = nullptr;
        if (!head) head = tail = tmp;
        else {
            tail->next = tmp;
            tmp->prev = tail;
            tail = tmp;
        }
    }
    tail->next = head;
    head->prev = tail;
}

void circularll::run(int people, int passBy, int startPos) {
    if (!head) return;
    startPos = ((max(1, startPos) - 1) % people) + 1;
    node* curr = head;
    for (int i = 1; i < startPos; ++i) curr = curr->next;
    int left = people;
    while (left > 1) {
        for (int s = 0; s < passBy; ++s) curr = curr->next;
        node* out = curr;
        cout << "The person who was sitting at seat " << out->position << " was killed.\n";
        out->prev->next = out->next;
        out->next->prev = out->prev;
        curr = out->next;
        delete out;
        --left;
    }
    cout << "\nJosephus was sitting at seat: " << curr->position << "\n\n";
    delete curr; // free last node
    head = tail = nullptr;
}

Quick troubleshooting checklist: validate inputs; avoid chained assignments that change head/tail accidentally; test with small N and different passBy values to confirm your counting semantics; and always free nodes you remove.

Recommended Answers

All 4 Replies

thank

nice but there is small problem by y++

I made it like this:

#include <iostream>
#include <conio.h>
using namespace std;

struct s
{
       int info;
       s* next;
};

int main()
{

    int n, i, pos, freq;
    s *ptr, *start, *loc;
    cout<<"Tell the total number of players: ";
    cin>>n;
    ptr= new s;
    start=ptr;
    for(i=1; i<=n; i++)
    {
             if(i<n)
             {
                    ptr->info = i;
                    ptr->next = new s;
                    ptr = ptr->next;
             }
             if(i==n)
             {
                     ptr->info = i;
                     ptr->next = start;
             }
    }

    cout<<"Enter the starting position: ";
    cin>>pos;
    ptr=start;
    i=1;
    while(i!=pos)
    {
                 ptr=ptr->next;
                 i++;
    }
    cout<<"Enter the intermidiate leaving frequency: ";
    cin>>freq;
    cout<<endl;

    while(ptr->next != ptr)
    {
                    for(i=1;i<=freq;i++)
                    {
                                        ptr = ptr->next;
                                        loc = ptr->next;
                    }
                    cout<<"Eliminated: PLAYER "<<loc->info<<endl;
                    ptr->next = loc->next;      //TO ELIMINATE THE PLAYER
                    ptr = ptr->next;   //TO TRANSFER THE CONTROL TO NEXT PLAYER
    }

    cout<<endl<<"Winner is: PLAYER "<<ptr->info;                                

    getch();
    return (0);

}

It's been six years, so I don't think the OP is interested anymore. Also, your code contains huge memory-leaks. If you use new you should delete your memory afterwards.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.