We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

Javascript Linked Lists

Andrew Beers
Andrew Beers asked
on
Medium Priority
1,010 Views
Last Modified: 2012-08-13
I know this is a lot of code but it should work but I can't find my syntax error somewhere... It should be an easy enough question to solve, just have to throw it into the cooresponding files and find the error I'm getting:

Object Expected Line 65
and
Object Expected Line 9
and
(Here is where I'm screwing up somewhere)
Expected ')' Line 14

Any help is greatly appreciated!!!


Main file:

<html>

<head>

      <script type="text/javascript" src="double_linked_node.js"></script>

      <script type="text/javascript">
            var trav = new Object();
                  trav = getTail();

            function appendNode(){
                  var i = new node(document.getElementsByTagName('input')[0].value, getTail(), getTail().getPrev());
                  getTail().insertNode(i);
                  updateDisplay();
            }

            function preInsertNode(){
                  var i = new node(document.getElementsByTagName('input')[0].value, trav.getNext(), trav.getPrev());
                  try{
                        trav.insertNode(i);
                  }catch(ex){
                        alert(ex);
                  }
            }

            function updateValue(){
                  try{
                        trav.setValue(document.getElementsByTagName('input')[0].value);
                  }catch(ex){
                        alert(ex);
                  }
                  updateDisplay();
            }

            function preGetHead(){
                  trav = getHead();
                  updateDisplay();
            }

            function preGetTail(){
                  trav = getTail();
                  updateDisplay();
            }

            function preGetNext(){
                  try{
                        trav = trav.getNext();
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function preGetPrev(){
                  try{
                        trav = trav.getPrev();
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function updateDisplay(){
                  var str = "",
                        temp = new Object();
                        temp = getHead();

                  while(temp != null){
                        str += " <-> ";

                        if(temp == trav){
                              str += "<font color='red'>";
                        }

                        if(temp.isHead()){
                              str += "(*)";
                        }else if(temp.isTail()){
                              str += "(*)";
                        }else{
                              str += temp.getValue();
                        }

                        if(temp == trav){
                              str += "</font>";
                        }

                        try{
                              temp = temp.getNext();
                        }catch(ex){
                              break;
                        }
                  }

                  document.getElementById("show").innerHTML = str;
            }


      </script>
</head>

<body onLoad="updateDisplay()">
      <div id="show"></div>
      <input type="text"><br>
      <input type="button" value="Append Node" onClick="appendNode()"><br>
      <input type="button" value="Insert Node" onClick="preInsertNode()"><br>
      <input type="button" value="Update Current Value" onClick="updateValue()"><br>
      <input type="button" value="Get Head" onClick="preGetHead()">
      <input type="button" value="Get Tail" onClick="preGetTail()"><br>
      <input type="button" value="Get Next" onClick="preGetNext()">
      <input type="button" value="Get Previous"  onClick="preGetPrev()"><br>
      <input type="button" value="Alert Value" onClick="alert(trav.getValue)">


</body>

</html>




<double_linked_node.js>

var       head = new node(null, null, null),
      tail = new node(null, null, head);
      
      head.setNext(tail);
      
var      headException = "Head Exception",
      tailException = "Tail Exception",
      removeException = "Remove ",
      insertException = "Insert Before ",
      travException = "Traverse Beyond ",
      updateException = "Update ";

function node(struct, nxt=null, prev=null){
      this.val = struct;
      this.next = nxt;
      this.previous = prev;

      this.setNext = setNext;
      this.setPrev = setPrev;
      this.setValue = setValue;
      this.getNext = getNext;
      this.getPrev = getPrev;
      this.getValue = getValue;
      this.isHead = isHead;
      this.isTail = isTail;
      this.insertNode = insertNode;
      this.removeNode = removeNode;
}

function isHead(){
      if(this.previous == null){
            return true;
      }else{
            return false;
      }
}

function isTail(){
      if(this.next == null){
            return true;
      }else{
            return false;
      }
}

function setNext(n){
      if(this.isTail()){
            throw updateException + tailException;
      }else{
            this.next = n;
      }
}

function setPrev(n){
      if(this.isHead()){
            throw updateException + headException;
      }else{
            this.previous = n;
      }
}

function setValue(n){
      if(this.isTail()){
            throw updateException + tailException;
      }else if(this.isHead()){
            throw updateException + headException;
      }else{
            this.val = n;
      }
}

function getNext(){
      if(this.isTail()){
            throw travException + tailException;
      }else{
            return this.next;
      }
}

function getPrev(){
      if(this.isHead()){
            throw travException + headException;
      }else{
            return this.previous;
      }
}

function getValue(){
      return this.val;
}

function getHead(){
      return head;
}

function getTail(){
      return tail;
}

/*
 *insertNode(new node)
 *Inserts the node object before the current node
 *If the node is the head node the insert will fail and throws an error
 */
function insertNode(nde){
      var prev;
      if(this.isHead()){
            throw insertException + headException;
      }else{
            prev = this.previous;
            prev.setNext(nde);
            this.setPrev(nde);
      }
}

/*
 *remveNode()
 *Removes the current node and returns the next node in line
 *If the current node is the head or tail then the remove will fail and throws an error
 */
function removeNode(){
      if(this.isHead()){
            throw removeException + headException;
      }else if(this.isTail()){
            throw removeException + tailException;
      }else{
            this.next.setPrev(this.previous);
            this.previous.setNext(this.next);
            return this.next;
      }
}



Thank you!
~Aqua
Comment
Watch Question

Commented:
function node(struct, nxt=null, prev=null)?
why is it not like this?
function node(struct, nxt prev){

Commented:
function setNext(n){
     if(this.isTail()){
          throw updateException + tailException;
     }else{
          this.next = n;
     }
}

your useing "throw" then you also need "catch"
well that is what error Im getting

http://www.w3schools.com/js/js_throw.asp
Andrew BeersTechnology Lead

Author

Commented:
....

You were right about one of the errors:
function node(struct, nxt, prev){

doing nxt=null, prev=null is call preloading data... which I thought you could do in Javascript but you obviously can't...

Next you pointing out my error in throwing errors... Haven't coded much in C++ or Java have you?  Functions can throw errors letting you know an error occured which you can later catch without having a throw in the same function.  My error occured here:

head.next = tail;

I used the .setNext function when setting the initial data when I didn't quite need to so I switched it to head.next

Here is the finished product for doing linked list structures in Javascript!

The widget file:

var       head = new node(null, null, null),
      tail = new node(null, null, head);
      
      head.next = tail;
      head.h = true;
      tail.t = true;
      
var      headException = "Head Exception",
      tailException = "Tail Exception",
      removeException = "Remove ",
      insertException = "Insert Before ",
      travException = "Traverse Beyond ",
      updateException = "Update ";

function node(struct, nxt, prev){
      this.previous = prev;
      this.val = struct;
      this.next = nxt;
      h = false;
      t = false;

      this.setNext = setNext;
      this.setPrev = setPrev;
      this.setValue = setValue;
      this.getNext = getNext;
      this.getPrev = getPrev;
      this.getValue = getValue;
      this.isHead = isHead;
      this.isTail = isTail;
      this.insertNode = insertNode;
      this.removeNode = removeNode;
}

function isHead(){
      if(this.h){
            return true;
      }else{
            return false;
      }
}

function isTail(){
      if(this.t){
            return true;
      }else{
            return false;
      }
}

function setNext(n){
      if(this.isTail()){
            throw updateException + tailException;
      }else{
            this.next = n;
      }
}

function setPrev(n){
      if(this.isHead()){
            throw updateException + headException;
      }else{
            this.previous = n;
      }
}

function setValue(n){
      if(this.isTail()){
            throw updateException + tailException;
      }else if(this.isHead()){
            throw updateException + headException;
      }else{
            this.val = n;
      }
}

function getNext(){
      if(this.isTail()){
            throw travException + tailException;
      }else{
            return this.next;
      }
}

function getPrev(){
      if(this.isHead()){
            throw travException + headException;
      }else{
            return this.previous;
      }
}

function getValue(){
      return this.val;
}

function getHead(){
      return head;
}

function getTail(){
      return tail;
}

/*
 *insertNode(new node)
 *Inserts the node object before the current node
 *If the node is the head node the insert will fail and throws an error
 */
function insertNode(nde){
      var prev;
      if(this.isHead()){
            throw insertException + headException;
      }else{
            prev = this.previous;      
            nde.setNext(prev.getNext());
            nde.setPrev(prev);
            prev.setNext(nde);
            this.setPrev(nde);
      }
}

/*
 *remveNode()
 *Removes the current node and returns the next node in line
 *If the current node is the head or tail then the remove will fail and throws an error
 */
function removeNode(){
      if(this.isHead()){
            throw removeException + headException;
      }else if(this.isTail()){
            throw removeException + tailException;
      }else{
            this.next.setPrev(this.previous);
            this.previous.setNext(this.next);
            return this.next;
      }
}


The example code showing how to use it:


<html>

<head>

      <script type="text/javascript" src="double_linked_node.js"></script>
      <script type="text/javascript">
            var trav = getTail();

            function appendNode(){
                  var i = new node(document.getElementsByTagName('input')[0].value, null, null);
                  try{
                        getTail().insertNode(i);
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function preInsertNode(){
                  var i = new node(document.getElementsByTagName('input')[0].value, null, null);
                  try{
                        trav.insertNode(i);
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function updateValue(){
                  try{
                        trav.setValue(document.getElementsByTagName('input')[0].value);
                  }catch(ex){
                        alert(ex);
                  }
                  updateDisplay();
            }

            function preRemoveNode(){
                  try{
                        trav = trav.removeNode();
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function preGetHead(){
                  trav = getHead();
                  updateDisplay();
            }

            function preGetTail(){
                  trav = getTail();
                  updateDisplay();
            }

            function preGetNext(){
                  try{
                        trav = trav.getNext();
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function preGetPrev(){
                  try{
                        trav = trav.getPrev();
                        updateDisplay();
                  }catch(ex){
                        alert(ex);
                  }
            }

            function updateDisplay(){
                  var str = "";
                  var      temp = getHead();

                  while(temp != null){
                        if(!temp.isHead()){
                              str += " <-> ";
                        }

                        if(temp == trav){
                              str += "<font color='red'>";
                        }

                        if(temp.isHead()){
                              str += "(*)";
                        }else if(temp.isTail()){
                              str += "(*)";
                        }else{
                              str += temp.getValue();
                        }

                        if(temp == trav){
                              str += "</font>";
                        }

                        try{
                              temp = temp.getNext();
                        }catch(ex){
                              break;
                        }
                  }

                  document.getElementById("show").innerHTML = str;
            }


      </script>
</head>

<body onLoad="updateDisplay()">
      <div id="show"></div>
      <input type="text"><br>
      <input type="button" value="Append Node" onClick="appendNode()"><br>
      <input type="button" value="Insert Node" onClick="preInsertNode()"><br>
      <input type="button" value="Update Current Value" onClick="updateValue()"><br>
      <input type="button" value="Remove Current Node" onClick="preRemoveNode()"><br>
      <input type="button" value="Get Head" onClick="preGetHead()">
      <input type="button" value="Get Tail" onClick="preGetTail()"><br>
      <input type="button" value="Get Next" onClick="preGetNext()">
      <input type="button" value="Get Previous"  onClick="preGetPrev()"><br>
      <input type="button" value="Alert Value" onClick="alert(trav.getValue)">


</body>

</html>


However if anyone can show me how to preload a value in a js function... Points will be split.

~Aqua
Commented:
"Next you pointing out my error in throwing errors... Haven't coded much in C++ or Java have you?  Functions can throw errors letting you know an error occured which you can later catch without having a throw in the same function.  My error occured here:"

- Im just telling you what mr.IE is telling me if I click "Insert Node" for ex:
-------------------------------------------------------------
Line: 83
Char: 11
Error: Exception thrown and not caught
Code: 0
-------------------------------------------------------------

"However if anyone can show me how to preload a value in a js function... Points will be split."
try this:
function node(struct, nxt, prev){
nxt=nxt||null;
prev=prev||null;
}

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Andrew BeersTechnology Lead

Author

Commented:
o.O;  

the or operation will do that?

What about a binary or?

nxt = nxt|null;
nxt = nxt|null;


I'm not entirely sure what it would pass or if it would complain without the value being preloaded if I left out a parameter... I'll give it a shot though!

~Aqua

Commented:
" binary or "
it seems to work too, thanks
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.