#include <iostream>
using namespace std;
template <class T>
class Chain;
template<class T>
class ChainNode {
friend class Chain<T>;
private:
T data;
ChainNode<T>* link;
};
template <class T>
class Chain {
public:
Chain() { first = nullptr; }
~Chain();
bool isEmpty() const { return first == nullptr; }
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
Chain<T>& Insert(int k, const T& x);
Chain<T>& Delete(int k, T& x);
void Output(ostream& out) const;
Chain<T>& RK(int k); // Function for Partially reversing the list
private:
ChainNode<T>* first;
int listSize=0;
};
template <class T>
Chain<T>::~Chain() {
ChainNode<T>* next;
while (first) {
next = first->link;
delete first;
first = next;
}
}
template <class T>
int Chain<T>::Length() const {
return listSize;
}
template <class T>
bool Chain<T>::Find(int k, T& x) const {
if (k <= 0 || k > listSize) {
return false;
}
ChainNode<T>* current = first;
for (int i = 1; i < k; i++) {
current = current->link;
}
x = current->data;
return true;
}
template <class T>
int Chain<T>::Search(const T& x) const {
ChainNode<T>* current = first;
int i = 1;
while (current != nullptr && current->data != x) {
current = current->link;
i++;
}
if (current == nullptr) {
return -1;
}
else {
return i;
}
}
template <class T>
Chain<T>& Chain<T>::Insert(int k, const T& x) {
if (k < 0 || k > listSize) {
cout << "Invalid position to insert" << endl;
return *this;
}
ChainNode<T>* y = new ChainNode<T>;
y->data = x;
if (k == 0 || isEmpty()) {
y->link = first;
first = y;
}
else {
ChainNode<T>* p = first;
for (int i = 1; i < k; i++) {
p = p->link;
}
y->link = p->link;
p->link = y;
}
listSize++;
return *this;
}
template <class T>
Chain<T>& Chain<T>::Delete(int k, T& x) {
if (k < 1 || k > listSize) {
cout << "Invalid position to delete" << endl;
return *this;
}
ChainNode<T>* p = first;
if (k == 1) {
first = first->link;
}
else {
ChainNode<T>* prev = nullptr;
for (int i = 1; i < k; i++) {
prev = p;
p = p->link;
}
prev->link = p->link;
}
x = p->data;
delete p;
listSize--;
return *this;
}
template <class T>
void Chain<T>::Output(ostream& out) const {
ChainNode<T>* p = first;
while (p != nullptr) {
out << p->data << " ";
p = p->link;
}
}
// Function for partially reversing the linked list
template <class T>
Chain<T>& Chain<T>::RK(int k) {
if (k < 1 || k > listSize) {
cout << "Invalid value of k, no change in list" << endl;
return *this;
}
ChainNode<T>* prev = nullptr;
ChainNode<T>* current = first;
ChainNode<T>* next = nullptr;
ChainNode<T>* subend = nullptr;
ChainNode<T>* subend2 = nullptr;
int count2 = 0;
// Reversing every k-th segment
for (int i = 0; i <= listSize; i += k) {
int count = 0;
if (count2 % 2 == 0 && count2 > 1) {
subend->link = prev;
} else if (count2 % 2 != 0 && count2 > 2) {
subend2->link = prev;
}
if (count2 % 2 == 0) subend = current; else subend2 = current;
if ((listSize - i) < k && (listSize - i) != 0) break;
prev = nullptr;
next = nullptr;
while (current && count < k) {
next = current->link;
current->link = prev;
prev = current;
current = next;
count++;
}
// Resetting first
if (i == 0) first = prev;
count2++;
}
// Joining the remaining elements
if (next) {
if (subend == next) subend2->link = next; else subend->link = next;
}
return *this;
}
int main() {
Chain<int> mylist;
// Inserting elements
mylist.Insert(0, 1);
mylist.Insert(1, 2);
mylist.Insert(2, 3);
mylist.Insert(3, 4);
mylist.Insert(4, 5);
mylist.Insert(5, 6);
mylist.Insert(6, 7);
mylist.Insert(7,8);
mylist.Insert(8,9);
mylist.Insert(9,10);
mylist.Insert(10,11);
mylist.Insert(11,12);
mylist.Insert(12,13);
cout << "Original List: ";
mylist.Output(cout);
cout << endl;
int k = 4;
mylist.RK(k);
if (k<1 || k>mylist.Length()) return 0;
cout << "List after reversing every kth segment of the list with k=" << k << ": ";
mylist.Output(cout);
cout << endl;
return 0;
}