Guest User

Untitled

a guest
Mar 23rd, 2012
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.99 KB | None | 0 0
  1. package DataStructures.Lists
  2.  
  3. import DataStructures.MiscellaneousTypes.Version
  4. import annotation.tailrec
  5. import scala.Predef._
  6. import DataStructures.NodeTypes.TemporalNode
  7.  
  8. trait SinglyLinkedTemporal[T] extends DataStructures.NodeTypes.TemporalNode {
  9.   val vrsn: Version;
  10.  
  11.   def right: SinglyLinkedTemporal[T] = super.get(1,vrsn.current).asInstanceOf[SinglyLinkedTemporal[T]]
  12.   def right_=(input: SinglyLinkedTemporal[T]) = super.set(1,input,vrsn++)
  13.  
  14.   // allows me to do something like class.data
  15.   def data: T = {
  16.     super.get(0,vrsn.current) match {
  17.       case x: T => x
  18.       case _ => throw new Exception("Somehow, an invalid type crept into field 1")
  19.     }
  20.   }
  21.  
  22.   // allows me to do something like class.data = 5 with 5 being mapped to input.
  23.   def data_=(input: T) = super.set(0,input,vrsn++)
  24.  
  25.   // changes the version of the list.
  26.   def changeVersion(version: Int) {vrsn.changeVersion(version)}
  27.  
  28.   // tells you what the latest version of the list is.
  29.   def newestVersion = vrsn.newest
  30.  
  31.   // tells you if this is the last node in the list.
  32.   def last = right == null
  33.    
  34.   final def fold[U](z: U)(f: (U, T) => U): U = foldLeft(z)(f)
  35.  
  36.   //@tailrec forces the recursive function below it to be written in a way where
  37.   // it can be called infinitely without causing a stack overflow. The
  38.   // compiler will complain if this condition is not met.
  39.   // foldLeft applies a function to each element in the list in left to right order.
  40.   // An initial value is supplied (z), and that value as the first parameter to
  41.   // the function, while the second is the current element of the list. Can be used
  42.   // to create one line summation functions and other nice features.
  43.   @tailrec
  44.   final def foldLeft[U](z: U)(f: (U, T) => U): U = {
  45.     if (last) f(z,data) else right.foldLeft(f(z, data))(f)
  46.   }
  47. }
  48.  
  49. class SinglyLinkedList[T](d: T, t: SinglyLinkedTemporal[T], version: Version = new Version()) extends
  50.  TemporalNode(Array(d,t).asInstanceOf[Array[AnyRef]]) with SinglyLinkedTemporal[T] {
  51.  
  52.   // Used to keep track of the master version of the list. Each node has a pointer to
  53.   // this object.
  54.   val vrsn = version
  55.  
  56.   // Inserts a node in front of the current node by creating a copy of the current node
  57.   // after this one and rewriting this node to the value supplied.
  58.   def +:(input: T) {
  59.     right = new SinglyLinkedList[T](data,right,vrsn)
  60.     data = input
  61.   }
  62.  
  63.   // Helper function for traversing the list to reach the node specified by position.
  64.   // Could use a recursive function to do this more succinctly, but this is a bit
  65.   // faster.
  66.   private def getNode(position: Int):SinglyLinkedTemporal[T] = {
  67.     var i = position
  68.     var ptr:SinglyLinkedTemporal[T] = this
  69.  
  70.     while(i != 0) {
  71.       ptr = ptr.right
  72.       i-=1
  73.     }
  74.  
  75.     ptr
  76.   }
  77.  
  78.   // Returns data from the position specified.
  79.   def apply(position: Int): T = {
  80.     getNode(position).data
  81.   }
  82.  
  83.   // Lets me do something like List(5) = 6 to change element 5 in a list to the value 6.
  84.   def update(position: Int, input: T) {
  85.     getNode(position).data = input
  86.   }
  87.  
  88.   // Uses fold left to summate the string values of each element of the list, creating a
  89.   // nicely formatted representation of the linked list.
  90.   override def toString: String = {
  91.     val ret = SinglyLinkedList.name
  92.     ret + "(" + foldLeft("")((a, b) => a + b.toString + ", ").stripSuffix(", ") + ")"
  93.   }
  94. }
  95.  
  96. object SinglyLinkedList {
  97.   protected val name = "SinglyLinkedList"        
  98.  
  99.   //Used to instatiate the class. Used like "SinglyLinkedList(1,2,3,4,5)" to instantly
  100.     create a linked list of ints with that structure. Calls the constructor below
  101.     to instatiate a class.
  102.   def apply[T](data: T*): SinglyLinkedList[T] = {
  103.     this(data.toList)
  104.   }
  105.  
  106.   // Another constructor, but this one lets me do "SinglyLinkedList(1 to 15)" instead.
  107.   def apply[T](seq: List[T]): SinglyLinkedList[T] = {
  108.     val version = new Version
  109.     seq.foldRight(null: SinglyLinkedList[T])(new SinglyLinkedList[T](_,_,version))
  110.   }
  111. }
Advertisement
Add Comment
Please, Sign In to add comment