I want to construct a expression tree for a multi digit number Like given expression is (122+30) and the post order traversal of this gives "122 30 +"
But this code creates the expression tree and gives post order traversal of a single digit expression only like (1+2)
#include <bits/stdc++.h>
using namespace std;
// Tree Structure
typedef struct node
{
char data;
struct node *left, *right;
} * nptr;
// Function to create new node
nptr newNode(char c)
{
nptr n = new node;
n->data = c;
n->left = n->right = nullptr;
return n;
}
unsigned int getOperand(char ch) {
if(ch >= '0' && ch <= '9'){
return ch - '0';
}
return 0;
}
// Function to build Expression Tree
nptr build(string& s)
{
// Stack to hold nodes
stack<nptr> stN;
// Stack to hold chars
stack<char> stC;
nptr t, t1, t2;
// Prioritising the operators
int p[123] = { 0 };
p['+'] = p['-'] = 1, p['/'] = p['*'] = 2, p['^'] = 3,
p[')'] = 0;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(') {
// Push '(' in char stack
stC.push(s[i]);
}
// Push the operands in node stack
else if (getOperand(s[i]))
{
t = newNode(s[i]);
stN.push(t);
}
else if (p[s[i]] > 0)
{
// If an operator with lower or
// same associativity appears
while (
!stC.empty() && stC.top() != '('
&& ((s[i] != '^' && p[stC.top()] >= p[s[i]])
|| (s[i] == '^'
&& p[stC.top()] > p[s[i]])))
{
// Get and remove the top element
// from the character stack
t = newNode(stC.top());
stC.pop();
// Get and remove the top element
// from the node stack
t1 = stN.top();
stN.pop();
// Get and remove the currently top
// element from the node stack
t2 = stN.top();
stN.pop();
// Update the tree
t->left = t2;
t->right = t1;
// Push the node to the node stack
stN.push(t);
}
// Push s[i] to char stack
stC.push(s[i]);
}
else if (s[i] == ')') {
while (!stC.empty() && stC.top() != '(')
{
t = newNode(stC.top());
stC.pop();
t1 = stN.top();
stN.pop();
t2 = stN.top();
stN.pop();
t->left = t2;
t->right = t1;
stN.push(t);
}
stC.pop();
}
}
t = stN.top();
return t;
}
// Function to print the post order
// traversal of the tree
void postorder(nptr root)
{
if (root)
{
postorder(root->left);
postorder(root->right);
cout << root->data;
}
}
int main()
{
string s ;
getline(cin,s);
nptr root = build(s);
// Function call
postorder(root);
return 0;
}
what changes should I do so that it can handle multi digit expression.
I have a problem with my C++ code. It says that the all the functions starting with isPerfectRec() couldn't be resolved...Why? I tried a lot of things but apparently they don't work. I have a lot of assigments like to verify if the binary search tree is perfect, to find the second largest element in a binary search tree and so on..
#include <stdio.h>
#include<iostream>
#include<stack>
template<typename T> class BinarySearchTree {
public:
BinarySearchTree<T> *root, *left_son, *right_son, *parent;
T *pinfo;
BinarySearchTree() {
left_son = right_son = NULL;
root = this;
pinfo = NULL;
}
void setInfo(T info) {
pinfo = new T;
*pinfo = info;
}
void insert(T x) {
if (pinfo == NULL)
setInfo(x);
else
insert_rec(x);
}
bool isPerfectRec(BinarySearchTree *root, int d, int level = 0)
{
// An empty tree is perfect
if (*root == NULL)
return true;
// If leaf node, then its depth must be same as
// depth of all other leaves.
if (*root->left_son == NULL && root->*right_son == NULL)
return (d == level+1);
// If internal node and one child is empty
if (root->*left_son == NULL || root->*right_son == NULL)
return false;
// Left and right subtrees must be perfect.
return isPerfectRec(root->*left_son, d, level+1) &&
isPerfectRec(root->*right_son, d, level+1);
}
// Wrapper over isPerfectRec()
bool isPerfect(BinarySearchTree *root)
{
int d = findADepth(root);
return isPerfectRec(root, d);
}
int findADepth(BinarySearchTree *node)
{
int d = 0;
while (node != NULL)
{
d++;
node = node->left_son;
}
return d;
}
// A function to find 2nd largest element in a given tree.
void secondLargestUtil(BinarySearchTree *root, int &c)
{
// Base cases, the second condition is important to
// avoid unnecessary recursive calls
if (root == NULL || c >= 2)
return;
// Follow reverse inorder traversal so that the
// largest element is visited first
secondLargestUtil(root->right_son, c);
// Increment count of visited nodes
c++;
// If c becomes k now, then this is the 2nd largest
if (c == 2)
{
std::cout << "2nd largest element is "
<< root->pinfo;
printf("\n___\n");
return;
}
// Recur for left subtree
secondLargestUtil(root->left_son, c);
}
void secondLargest(BinarySearchTree *root)
{
// Initialize count of nodes visited as 0
int c = 0;
// Note that c is passed by reference
secondLargestUtil(root, c);
}
bool hasOnlyOneChild(int pre[], int size)
{
int nextDiff, lastDiff;
for (int i=0; i<size-1; i++)
{
nextDiff = pre[i] - pre[i+1];
lastDiff = pre[i] - pre[size-1];
if (nextDiff*lastDiff < 0)
return false;;
}
return true;
}
BinarySearchTree * readListInter(){
BinarySearchTree* root = NULL;//returning object
BinarySearchTree* temp;
BinarySearchTree* input;//new node to add
int x;
std::cout << "enter number (>0 to stop): ";
std::cin >> x;
while(x>=0){
input = BinarySearchTree(x);
if(root == NULL){//if root is empty
root = input;
temp = root;//temp is use to store value for compare
}
else{
temp = root; //for each new addition, must start at root to find correct spot
while(input != NULL){
if( x < temp->pinfo){//if smaller x to add to left
if(temp->left_son == NULL){//left is empty
temp->left_son = input;
input = NULL;//new node added, exit the loop
}
else{//if not empty set temp to subtree
temp = temp->left_son;//need to move left from the current position
}
}
else{//otherwise x add to right
if(temp->right_son == NULL){//right is empty
temp->right_son = input;
input = NULL;//new node added, exit the loop
}
else{
temp = temp->right_son;//need to move right from the current position
}
}
}
}
std::cin >> x;
}
return root;
}
};
int main() {
BinarySearchTree<int> *r = new BinarySearchTree<int>;
BinarySearchTree<int> *r1 = new BinarySearchTree<int>;
BinarySearchTree<int> *p = new BinarySearchTree<int>;
p = readListInter();
r->insert(6);
r->insert(8);
r->insert(1);
r->insert(9);
r->insert(10);
r->insert(4);
r->insert(13);
r->insert(12);
printf("\n___\n");
r1->insert(6);
r1->insert(8);
r1->insert(1);
r1->insert(9);
r1->insert(10);
r1->insert(4);
r1->insert(13);
r1->insert(12);
printf("\n___\n");
r->isPerfect(r);
int pre[] = {8, 3, 5, 7, 6};
int size = sizeof(pre)/sizeof(pre[0]);
if (hasOnlyOneChild(pre, size) == true )
printf("Yes");
else
printf("No");
s
return 0;
}
I think you need to write BinarySearchTree<T> instead of BinarySearchTree as a datatype in those functions.
I am really stuck in make conversion of special prefix to postfix operation on our task, let me describe the task similarly :
We have such operation to use as operations in our prefixes, here is the method that i am checking them :
bool isOperator(string c)
{
if (c == "log" || c == "exp" || c == "sum" || c == "div" || c == "abs" || c == "sqrt" || c == "sub" || c == "product" || c == "max" || c== "min" || c == "mod" ) // you may add operator here
return true;
return false;
}
Anyway example prefix instructions can have parentheses to make operation precedence, this is what I am stuck at. I know, I need to implement such a recursion, but i can't find a way.
div ( sqrt 5 ) 3
Output should be
5 sqrt 3 div
Another example :
div ( sum ( exp 2 3 ) ( sqrt 5 ) ) 3
Output
2 3 exp 5 sqrt sum 3 div
Every operation, parentheses or number should have space between elements in assumed condition.
My stack implementation
Stack.h
#include<iostream>
using namespace std;
struct node {
string op ;
node *next;
};
struct Stack {
node * head;
void create();
void close();
void push (node *);
node* pop();
node* top();
bool isEmpty();
};
Stack.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "stack.h"
#include <iostream>
#include <stdlib.h>
void Stack::create() {
head = NULL;
}
void Stack::close() {
node *p;
while (head) {
p = head;
head = head->next;
//delete [] p->data;
delete p;
}
}
void Stack::push(node *newdata) {
node *newnode = new node;
newnode = newdata;
newnode->op = newdata->op;
newnode->next = head;
head = newnode;
}
node *Stack::pop() {
if (isEmpty())
return NULL;
node *topnode = head;
head = head->next;
//delete topnode;
return topnode;
}
node *Stack::top() {
if (isEmpty())
return NULL;
node *topnode = head;
//delete topnode;
return topnode;
}
bool Stack::isEmpty() {
return (head == NULL);
}
as #PaulMcKenzie mentioned, i've tried an implementation below, sub_array string array contains the word list without spaces.
bool isLeftParanthesis(string c)
{
if (c == "(" ) // you may add operator here
return true;
return false;
}
bool isRightParanthesis(string c)
{
if (c == ")") // you may add operator here
return true;
return false;
}
int main()
{
string prefix;
getline(cin, prefix);
istringstream iss(prefix);
istringstream iss2(prefix);
int count1 = 0, count2 = 0;
string postfix = "";
Stack *st = new Stack;
string t1, t2;
string sub;
string *sub_array;
while (iss >> sub) {
count1++;
}
sub_array = new string[count1];
while (iss2 >> sub) {
sub_array[count2] = sub;
count2++;
}
int l = count1;
int right_p_count = 0;
for (int i = 0; i < count1; i++)
{
if (isRightParanthesis(sub_array[i]))
{
right_p_count++;
}
}
string *postfixes = new string[right_p_count];
int index_right_p = 0;
for (int i = 0; i < count1; i++) {
while (!isRightParanthesis(sub_array[i]))
{
node *n = new node;
n->op = sub_array[i];
st->push(n);
i++;
if (i == count1)
{
break;
}
}
if( i != count1){
if (isRightParanthesis(sub_array[i])) {
postfix = "";
while (!isLeftParanthesis(st->top()->op))
{
string t = st->pop();
if (!isOperator(t) && !isLeftParanthesis(t) && !isRightParanthesis(t)) {
postfix = t + " " + postfix;
}
else if (isOperator(t)) {
postfix = postfix + " " + t;
}
}
st->pop();
postfixes[index_right_p] = postfix;
index_right_p++;
}
}
postfix = "";
while ( !st->isEmpty() && index_right_p == right_p_count && i == count1)
{
string t = st->pop();
if (!isOperator(t) && !isLeftParanthesis(t) && !isRightParanthesis(t)) {
postfix = t+" "+postfix;
}
else if (isOperator(t)) {
postfix = postfix+""+t;
}
else {
break;
}
}
}
string result = "";
for (int i = 0; i < right_p_count; i++)
{
result = result + "" + postfixes[i];
}
result = result + " " + postfix;
cout << result << endl;
}
Variable postfix refers to output postfix, but my output is not wrong for some of the operations such as :
div ( sqrt 5 ) 3
When i saw a parantheses i am checking if it is left or right, using right one for trigger.
abs ( product -2 -4 -8 )
Expected output is :
-2 -4 -8 product abs
UPDATE : I solved stack problem myself, but found out that, algorithm calculates some expressions wrongly...
Example expression :
3 2 3 exp sum
Expected output :
sum 3 ( exp 2 3 )
My output :
2 3 exp 3 sum
My algorithm which is using right parentheses as triggers calculates it wrongly and I don't know how to implement this control into that, are there any suggestions ?
so heres my header and cpp file.
template<typename T> struct TreeNode
{
TreeNode(const T& value, TreeNode<T>* left = NULL, TreeNode<T>* right = NULL)
{
Value = value;
Left = left;
Right = right;
}
T Value;
TreeNode<T>* Left;
TreeNode<T>* Right;
bool IsLeaf() const
{
return Left == NULL && Right == NULL;
}
};
and now my cpp file
#include "TreeNode.h"
#include <iostream>
#include <string>
using namespace std;
float ValueOf(TreeNode<char>* root);
float ValueOf(TreeNode<char>* root)
{
if (root->IsLeaf())
return root->Value - '0';
float expressionValueL = ValueOf(root->Left);
float expressionValueR = ValueOf(root->Right);
if (root->Value == '+')
return expressionValueL+expressionValueR;
else if (root->Value == '-')
return expressionValueL-expressionValueR;
else if (root->Value == '*')
return expressionValueL*expressionValueR;
else if (root->Value == '/')
return expressionValueL/expressionValueR;
}
void main ()
{
TreeNode<char>* treeRoot = nullptr;
TreeNode<char>* currentNode = treeRoot;
string expr;
cout<<"please input expression to be tested:";
getline (cin, expr);
cout<<endl;
int size = expr.size();
for (int i=0; i<size; i++)
{
char test = expr[i];
if ((test=='1')||(test=='0')||(test=='2')||(test=='3')||(test=='4')||(test=='5')||(test=='6')||(test=='7')||(test=='8')||(test=='9'))
{
TreeNode<char> newLeaf = (expr[i]);
if (currentNode == nullptr)
{
treeRoot=&newLeaf;
currentNode = &newLeaf;
}
else
currentNode->Right = &newLeaf;
}
else if ((expr[i]=='+')||(expr[i]=='-'))
{
TreeNode<char> newRoot = test;
newRoot.Left = treeRoot;
treeRoot = &newRoot;
currentNode = &newRoot;
}
else if (((expr[i]=='*')||(expr[i]=='/'))&&(currentNode->Right==nullptr))
{
TreeNode<char> newRoot = test;
newRoot.Left = treeRoot;
treeRoot = &newRoot;
currentNode = &newRoot;
}
else if (((expr[i]=='*')||(expr[i]=='/'))&&(currentNode->Right!=nullptr))
{
TreeNode<char> newChild = test;
newChild.Left = currentNode->Right;
currentNode->Right = &newChild;
currentNode = &newChild;
}
}
cout<<ValueOf(treeRoot)<<endl;
system("pause");
}
the problem is that every time i run it, and i input something like 3*4-2, all of the digits in the tree gets overwritten to what the last digit inserted was, so its interpreted as 2*2-2 and gives me 2 as an answer, instead of 10 can anyone tell me what my problem is? thanks =).
btw this program assumes wellformed expressions and single digit numbers.
TreeNode<char> newLeaf = (expr[i]); creates an object on stack - it's invalidated when you leave the enclosing scope. You should not store pointers to such objects.
Use TreeNode<char> * newLeaf = new TreeNode<char>(expr[i]); - and corresponding for any other node that you assign to ->Right and ->Left - aka need to keep alive beyond the scope where you create them.
As mentioned by Erik,
TreeNode<char> newLeaf = (expr[i]);
is a local stack variable; instead of do following:
TreeNode<char> *newLeaf = new TreeNode<char>(expr[i]);
And then assign to proper leg. Also, below condition,
if ((test=='1')||(test=='0')||(test=='2')||(test=='3')||(test=='4')||(test=='5')||(test=='6')||(test=='7')||(test=='8')||(test=='9'))
Can be squeezed to,
if(test >= '0' && test <= '9')
In the same way, you can also co-relate the last two else if() statements for better code
Consider a linked list whose nodes are chars, so the list represents a string. How do you write a recursive routine to check whether the string is a palindrome such that
the the said function starts unwinding the stack when it processes the character(s) at the middle of the string?
For example, suppose that my string is "madam". My recursive function looks something like:
bool isPalin(const node *startnode, const node *currentnode, const node *midpoint, ...);
When currentnode->data == 'd', the stack has to unwind.
I was asked this question for an interview; at the moment I can't think of any use for this question except as a very hard puzzle.
First thoughts: A very obvious (if inelegant) way is to:
Compute the midpoint of the list first.
If currentnode is "before" midpoint , push former into a stack manually. This can be decided by maintaining a counter.
Otherwise, unwind the manually maintained stack at every step of the recursion, and compare with the current character.
Any better ideas or fresh insights?
By "linked list", do you mean std::list?
template <typename BiDiIterator>
bool isPalindrome(BiDiIterator first, BiDiIterator last) {
if (first == last) return true;
--last;
if (first == last) return true;
if (*first != *last) return false;
return isPalindrome(++first, last); // tail recursion FTW
}
isPalindrome(mylist.begin(), mylist.end());
I've used the fact that it's possible to iterate back from the end as well as forward from the start. It is not clear whether this is given by the question.
With a singly linked list you can run two iterators, one fast and one slow. On each call, increment the fast one twice and the slow one once. When the fast one reaches the end of the list, the slow one is at the midpoint (um, +/- 1 and taking account of odd-length and even-length lists). At that point, back out of your recursion comparing character values. Θ(n) complexity for runtime and memory use (not tail recursive).
I'd write the code, but it's time for bed here in the UK.
[Edit: morning all
template <typename FwdIterator>
std::pair<FwdIterator, bool> isPalindrome(FwdIterator slow, FwdIterator fast, FwdIterator last) {
if (fast == last) return std::make_pair(slow, true);
++fast;
if (fast == last) return std::make_pair(++slow, true);
++fast;
FwdIterator next = slow;
std::pair<FwdIterator, bool> result = isPalindrome(++next, fast, last);
if (result.second == false) return result;
if (*slow != *(result.first)) return std::make_pair(slow, false);
++(result.first);
return result;
}
...
isPalindrome(mylist.begin(), mylist.begin(), mylist.end()).second;
If, for some bizarre reason, your linked list doesn't provide an iterator, then hopefully the equivalent code with if (fast->next == 0), fast = fast->next, etc, is obvious. And of course you can tidy up the user interface with a wrapper.
I think you can avoid the additional storage if you're allowed to temporarily modify the list, by reversing the list up to "slow" as you descend, then reversing it again as you ascend. That way you don't need to store a copy of slow across the recursive call: instead you can return an extra pointer for the caller to follow. I'm not going to bother, though.
]
Modulo thorny details this one's easy.
First, find the midpoint by calling recursively moving one pointer just one step but other two steps. When two-step pointer reaches end one-step pointer is at middle. Thorny thing: even versus odd length list.
Then back up (returning from the recursive calls), and while backing move midpointer one step forward for each return. Just compare that node's contents with contents available as routine argument during descent.
Cheers & hth.,
If you do feel like using a stack, this is a common exercise in computation theory using nondeterministic pushdown automata. The idea is to push every char onto the stack and at each char, branch off, with one branch skipping a char (in case it's an odd palindrome) and popping each char off the stack while comparing it to one in the remainder of the list, another branch doing the same without skipping that initial char (in case it's an even palindrome), and the third continuing to add elements to the stack (and recursively beginning the branching again with the next char). These three branches could be represented by passing the current state of the stack into each one recursively.
In pseudocode:
function isPalin(* start, * end, stack){
if checkPalin(start, end, stack):
return true;
stack.push(*start);
if checkPalin(start, end, stack):
return true;
if (start == end)
return false;
return isPalin(start.next, end, stack);
}
function checkPalin(* start, * end, stack){
while (stack is not empty && start != end){
start = start.next;
if (*start != stack.pop())
return false;
}
return (stack is empty && start == end);
}
Is the list doubly linked? Then it's a matter of passing in the start and end nodes, compare what they point to. If they're different, return false. If they're the same, call yourself recursively with start+1 and end-1, until start > end.
this is what the asked I think
bool isPalindrom(node* head)
{
if(!head) return true;
node* left = head;
node* mid = head;
return cmp(left, mid, head);
}
bool cmp(node*& left, node*& mid, node* n)
{
node* next = n->next;
if(next == 0)
{
node* lprev = left;
left = left->next;
return lprev->data == n->data;
}
mid = mid->next;
if(next->next == 0)
{
node* lprev = left;
left = left->next->next;
return lprev->data == next->data && lprev->next->data == n->data;
}
if(!cmp(left, mid, next->next)) return false;
if(left == mid) return true;
if(left->data != next->data) return false;
left = left->next;
if(left == mid) return true;
if(left->data != n->data) return false;
left = left->next;
return true;
}
In Java, this solution will compare the string already read against the string that comes recursively. It's not the best solution as even when it's O(n) it's S(n^2) and it should (at least) use StringBuffer to reduce all the concatenations.
It makes use of a wrapper class to pass back the right side of the string along with the boolean.
pros:
only one pass to the list, from head to end.
it doesn't need to know in advance the list length
no extra data structures needed
cons:
uses loads of memory S(n^2)
concatenates strings in an inefficient way
recursive solution, slow.
Code:
boolean palindrome(Node n){
RightSide v = palindromeRec(“”, n);
return v.palindrome;
}
class RightSide{
boolean palindrome;
String right;
}
private RightSide palindromeRec(String read, Node n){
RightSide v = new RightSide();
if(n == null){
v.palindrome = false;
v.right = “”;
return v;
}
v = palindromeRec(n.value + read, n.next);
if(v.palindrome)
return v;
else if(read.equals(v.right) || (n.value+read).equals(v.right)){
v.palindrome = true;
return v;
}
v.right = n.value + v.right;
v.palindrome = false;
return v;
}
Find the length of the total string
Get the node that has the mid (middle) position
Break the List at that node
Reverse the first half
Now do string compare
include "stdafx.h"
include "LinkedList.h"
LinkedList::LinkedList()
{
head = nullptr;
count = 0;
}
void LinkedList::AddItem(char* data)
{
Node node = new Node;
node->Data = (void) malloc(strlen(data) + 1);
strcpy((char*)node->Data, data);
node->Data = data;
node->Next = nullptr;
count++;
if(head == nullptr)
{
head = node;
head->Next = nullptr;
return;
}
Node *temp = head;
while(temp->Next!=nullptr)
{
temp = temp->Next;
}
temp->Next = node;
}
void LinkedList::TraverseList()
{
Node *temp = head;
while(temp !=nullptr)
{
printf("%s \n", temp->Data);
temp = temp->Next;
}
}
Node* LinkedList::Reverse()
{
if(!head || !(head->Next))
{
return head;
}
Node* temp = head;
Node* tempN = head->Next;
Node* prev = nullptr;
while(tempN)
{
temp->Next = prev;
prev= temp;
temp = tempN;
tempN = temp->Next;
}
temp->Next = prev;
head = temp;
return temp;
}
bool LinkedList::IsPalindrome()
{
int len = 0;
Node* temp = head;
while(temp)
{
len = len + strlen((char*)temp->Data);
temp = temp->Next;
}
printf("total string length is %d \n", len);
int i =0;
int mid1 = 0;
temp = head;
while (i < len/2)
{
int templen = strlen((char*)temp->Data);
if(i + strlen((char*)temp->Data) < (len /2))
{
i = i + strlen((char*)temp->Data);
temp = temp->Next;
}
else
{
while(i < len/2)
{
mid1++;
i++;
}
break;
}
}
printf("len:%d, i:%d, mid1:%d mid2:%d \n",len, i, mid1, len-mid1);
Node* secondHalf = temp->Next;
temp->Next = nullptr;
Node *firstHalf = Reverse();
char* str1 = (char*)malloc(sizeof(char) * mid1 + 1);
char* str2 = (char*)malloc(sizeof(char) * mid1 + 1);
memcpy(str1, (char*)firstHalf->Data, mid1);
str1[mid1] = '\0';
int slen = strlen((char*)temp->Data);
if(slen > mid1)
{
memcpy(str2, (char*)firstHalf->Data + mid1, slen-mid1);
str2[slen-mid1] = '\0';
}
else
{
str2[0] = '\0';
}
printf("%s, %s", str1, str2);
str1 = strrev(str1);
if(!*str2)
{
str2 = (char*)secondHalf->Data;
secondHalf = secondHalf->Next;
}
if(*str2 && len%2 == 1)
{
str2++;
if(!*str2)
{
str2 = (char*)secondHalf->Data;
secondHalf = secondHalf->Next;
}
}
while(*str1 && *str2)
{
if(*str1 != *str2)
{
return false;
}
str1++;
str2++;
if(!*str1)
{
retry:
firstHalf = firstHalf->Next;
if(firstHalf)
{
str1 = (char*) malloc(strlen((char*)firstHalf->Data) + 1);
strcpy(str1,(char*)firstHalf->Data);
str1 = strrev(str1);
}
if(!*str1 && firstHalf)
{
goto retry;
}
}
if(!*str2)
{
retrySecondHalf:
temp = secondHalf;
if(temp)
{
str2 = (char*)temp->Data;
secondHalf = secondHalf->Next;
}
if(!*str2 && secondHalf)
{
goto retrySecondHalf;
}
}
}
if(*str1 || *str2)
{
return false;
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
LinkedList* list = new LinkedList();
list->AddItem("01234");
list->AddItem("");
list->AddItem("56");
list->AddItem("789");
list->AddItem("1");
list->AddItem("9");
list->AddItem("");
list->AddItem("876543210");
printf("Is pallindrome: %d \n", list->IsPalindrome());
return 0;
}
To begin, iterate to the end of the list and store a pointer to the last node as end. Then store a pointer to the first node as start.
Then, call a function and supply these values. The function will:
Test if start == end (they point to the same link). If so, it will return true immediately. (An odd number of items in the list and the middle item is the only one left.)
Then it will look at the values represented by start and end. If they are not equal, it will return false immediately. (Not a palindrome.)
Otherwise, it will alter start to point to the next link (presumably start = start->next).
If start == end, return true immediately (handles the case for an even number of links in the list).
Find the link prior to end and set end to it: link i = start; while (i->next != end) i = i->next; end = i;.
Recurse, supplying the new values for start and end.
Following is recursion code, where node has data as integer, just replace it with char. It runns in O(n) time, uses constant space other than implicitly using stack of size O(n). where, n is number of nodes in linkedlist..
package linkedList;
class LinkedList {
class LinkedListNode {
public int data;
public LinkedListNode next;
public LinkedListNode (int d) {
data = d;
next = null;
}
}
class PalinResult {
public boolean done;
public LinkedListNode forward;
public PalinResult (LinkedListNode n) {
forward = n;
done = false;
}
}
LinkedListNode root;
public LinkedList () {
root = null;
}
public LinkedListNode getRoot(){
return root;
}
public boolean add(int d) {
LinkedListNode t = new LinkedListNode (d);
if (root == null) {
root = t;
return true;
}
LinkedListNode curr = root;
while (curr.next != null) {
curr = curr.next;
}
curr.next = t;
return true;
}
/*
* Takes O(n time)
*/
public boolean checkPalindrome() {
PalinResult res = new PalinResult (root);
return checkPalindromeRecur(root, res);
}
private boolean checkPalindromeRecur(LinkedListNode curr, PalinResult res) {
if (curr == null)
return true;
else {
boolean ret = checkPalindromeRecur(curr.next, res);
if (!ret || (res.done))
return ret;
if (curr == res.forward)
res.done = true;
if (curr.data == res.forward.data)
ret = true;
else
ret = false;
res.forward = res.forward.next;
return ret;
}
}
public static void main(String args[]){
LinkedList l = new LinkedList();
l.add(1);
l.add(4);
l.add(1);
System.out.println(l.checkPalindrome());
}
}
So ( My rough idea- please let me know)
We could also
1) Calculate length of LL;
2) Appropriately determine the midpoint
// (for a length 5 the mid point is 3 but for length 4 the midpoint is 2).
3) When at Midpoint- reverse the LL from mid point to the end of the LL;
4)Compare head data with the new mid point data until the head ref iterates to mid and the new mid ref iterates to NULL.