#include <iostream>
using namespace std;
template<class T>
class Double;
template <class T>
class DoubleNode {
friend class Double<T>;
private:
T data;
DoubleNode<T> *left, *right;
};
template <class T>
class Double {
public:
Double() { LeftEnd = RightEnd = nullptr; };
~Double();
int Length() const;
bool CanFormPalindrome();
Double<T>& Insert(int k, const T& x);
void Output(std::ostream& out) const;
void ConstructFromString(const string& S); // New method for constructing from string
private:
DoubleNode<T> *LeftEnd, *RightEnd;
};
template <class T>
Double<T>::~Double() {
while (LeftEnd != nullptr) {
DoubleNode<T>* temp = LeftEnd;
LeftEnd = LeftEnd->right;
delete temp;
}
}
template <class T>
int Double<T>::Length() const {
int len = 0;
DoubleNode<T>* current = LeftEnd;
while (current != nullptr) {
len++;
current = current->right;
}
return len;
}
template <class T>
bool Double<T>::CanFormPalindrome() {
int frequencies[128] = {0}; // Assuming ASCII characters
// Traversing the doubly linked list to count the frequency of each character
DoubleNode<T>* current = LeftEnd;
while (current != nullptr) {
frequencies[current->data]++;
current = current->right;
}
int oddCount = 0;
// Counting the number of characters with odd frequencies
for (int i = 0; i < 128; i++) {
if (frequencies[i] % 2 != 0) {
oddCount++;
if (oddCount > 1) {
return false; // If the count of characters with odd frequencies is greater than one, palindrome cannot be formed
}
}
}
// If the count of characters with odd frequencies is less than equal to one, palindrome can be formed
return true;
}
template <class T>
Double<T>& Double<T>::Insert(int k, const T& x) {
if (k < 1 || k > Length() + 1){
cout << "Invalid position";
return *this;
}
DoubleNode<T>* newNode = new DoubleNode<T>;
newNode->data = x;
if (k == 1) { // Inserting at the beginning
newNode->left = nullptr;
newNode->right = LeftEnd;
if (LeftEnd != nullptr)
LeftEnd->left = newNode;
LeftEnd = newNode;
if (RightEnd == nullptr)
RightEnd = LeftEnd;
} else if (k == Length() + 1) { // Inserting at the end
newNode->right = nullptr;
newNode->left = RightEnd;
RightEnd->right = newNode;
RightEnd = newNode;
} else { // Inserting in the middle
DoubleNode<T>* current = LeftEnd;
for (int i = 1; i < k; i++)
current = current->right;
newNode->right = current;
newNode->left = current->left;
current->left->right = newNode;
current->left = newNode;
}
return *this;
}
template <class T>
void Double<T>::Output(std::ostream& out) const {
DoubleNode<T>* current = LeftEnd;
while (current != nullptr) {
out << current->data << " ";
current = current->right;
}
}
// Function to construct DoublyLinkedList from a given string
template <class T>
void Double<T>::ConstructFromString(const string& S) {
for (char c : S) {
Insert(Length() + 1, c);
}
}
int main() {
Double<char> dl;
string S = "carrace";
cout<<"Given string: "<<S<<endl;
cout<<"Constructing DLL from this string..."<<endl;
dl.ConstructFromString(S);
dl.Output(cout);
cout<<endl;
if(dl.CanFormPalindrome()) {
cout << "The given doubly linked list can be rearranged to form a palindrome." << endl;
} else {
cout << "The given doubly linked list cannot be rearranged to form a palindrome." << endl;
}
return 0;
}