// C++ Program for Implementation of Single linked list
#include <iostream>
using namespace std;
// Structure for a node in the linked list
struct Node
{
   int data;
   Node* link;
};
      Node* head = NULL;
// Function to Insert a new node at the beginning of the list
   void insertAtBeginning(int value)
     {
     Node* newNode = new Node();
     newNode->data = value;
     newNode->link = head;
     head = newNode;
   }
// Function Insert a new node at the end of the list
   void insertAtEnd(int value)
     {
     Node* newNode = new Node();
     newNode->data = value;
     newNode->link = NULL;
     // If the list is empty, update the head to the new node
     if (head == NULL)
             {
          head = newNode;
          return;
      }
      // Traverse to the last node
      Node* temp = head;
      while (temp->link != NULL)
         temp = temp->link;
      // Update the last node's link to the new node
      temp->link = newNode;
  }
// Function to Insert a new node at a specific position in the list
   void insertAtPosition(int value, int position)
     {
     if (position < 1) {
         cout << "Position should be >= 1." << endl;
         return;
     }
      if (position == 1) {
          insertAtBeginning(value);
          return;
      }
      Node* newNode = new Node();
      newNode->data = value;
      // Traverse to the node before the desired position
      Node* temp = head;
      for (int i = 1; i < position - 1 && temp !=NULL; ++i)
             {
         temp = temp->link;
      }
      // If the position is out of range, print an error message
      if (temp ==NULL)
              {
          cout << "Position out of range." << endl;
          delete newNode;
          return;
      }
          // Insert the new node at the desired position
      newNode->link = temp->link;
      temp->link = newNode;
  }
// Function to Delete the first node of the list
   void deleteFromBeginning()
     {
     if (head==NULL)
            {
         cout << "List is empty." << endl;
         return;
     }
      Node* temp = head;
      head = head->link;
      delete temp;
  }
// Function to Delete the last node of the list
   void deleteFromEnd()
     {
     if (head==NULL)
            {
         cout << "List is empty." << endl;
         return;
     }
      if (head->link==NULL)
             {
          delete head;
          head = NULL;
          return;
      }
      // Traverse to the second-to-last node
      Node* temp = head;
      while (temp->link->link)
            {
         temp = temp->link;
      }
      // Delete the last node
      delete temp->link;
      // Set the second-to-last node's link to NULL
      temp->link = NULL;
  }
// Function to Delete a node at a specific position in the list
   void deleteFromPosition(int position)
     {
     if (position < 1)
            {
         cout << "Position should be >= 1." << endl;
         return;
     }
      if (position == 1)
             {
          deleteFromBeginning();
          return;
      }
      Node* temp = head;
      for (int i = 1; i < position - 1 && temp !=NULL; ++i)
             {
          temp = temp->link;
      }
      if ((temp==NULL) || (temp->link==NULL))
             {
          cout << "Position out of range." << endl;
          return;
      }
      // Save the node to be deleted
      Node* nodeToDelete = temp->link;
      // Update the link pointer
      temp->link = temp->link->link;
       // Delete the node
      delete nodeToDelete;
  }
// Function to print the nodes value of the linked list
   void display()
     {
     if (head==NULL)
            {
         cout << "List is empty." << endl;
         return;
     }
      Node* temp = head;
      while (temp !=NULL)
           {
        cout << temp->data << " -> ";
        temp = temp->link;
      }
      cout << "NULL" << endl;
  }
int main()
{
   int x,p,k;
    do
    {
    cout<<"=================================="<<endl;
    cout<<"1) Insert element in the Begining"<<endl;
    cout<<"2) Insert element in the End"<<endl;
  cout<<"3) Insert element in the Position"<<endl;
  cout<<"4) Delete element from the Begining"<<endl;
    cout<<"5) Delete element from the End"<<endl;
  cout<<"6) Delete element from the Position"<<endl;
  cout<<"7) Display elements of the List"<<endl;
cout<<"0) Exit"<<endl;
cout<<"Enter your choice : ";
 cin>>k;
 switch (k)
    {
   case 1:{
                 cout<<"Enter value :";
                 cin>>x;
                 insertAtBeginning(x);
                 cout << "Linked list after insertions: ";
            display();
                 break;
                 }
  case 2:{
                 cout<<"Enter value :";
                 cin>>x;
                 insertAtEnd(x);
                 cout << "Linked list after insertions: ";
            display();
            break;
            }
   case 3:{
                 cout<<"Enter value :";
                 cin>>x;
                 cout<<"Enter position to insert :";
                 cin>>p;
                 insertAtPosition(x, p);
                 cout << "Linked list after insertions: ";
            display();
            break;
                   }
        case 4:{
                       deleteFromBeginning();
                  cout << "Linked list after deleting : ";
                  display();
                  break;
                  }
             case 5:{
                       deleteFromEnd();
                       cout << "Linked list after deleting : ";
                  display();
                  break;
                  }
        case 6:{
                  cout<<"Enter position to delete :";
                       cin>>p;
                       deleteFromPosition(p);
                  cout << "Linked list after deleting : ";
                  display();
                       break;
                       }
             case 7:display();
                  break;
             case 8:cout<<"Exit"<<endl;
                  break;
        default: cout<<"Invalid choice"<<endl;
      }
    } while( k != 0);
     return 0;
}