How to implement Singly Linked List using AngularJS

Singly Linked List is the collection of elements in which first element called Node contains the reference to the next element in the list. We can divide “Node” into two parts one is data and second is reference part.

In this tutorial, I will show you how you can use this data structure in AngularJS and manipulate the data elements with UI.

Before we begin make sure to setup your environment as discussed in this tutorial. Follow the steps and prepare the environment in order to use AngularJS with RequireJS for Developers tutorial.

Once environment is ready, we can start coding.

Below is the factory which I had created. Factory is a service which can be shared between controllers and you can use the provided methods by that service factory. SingleLinkedList is a factory which contains following function:

add : Nodes can be added with the help of this function.
deleteNodes : Used to delete the given node.
swapNodes : function which takes two nodes and swap them with the links.
traverse : this function provides us the JSON data of the the node elements which you can use in your controller for UI manipulation.

factory/homepage.js
'use strict';

define([ 'app' ], function(app) {
	app.factory('SingleLinkedList', function($window) {

		var Node = function(data) {
			this.data = data;
			this.next = null;
		};

		var SingleLinkedList = function() {
			this._length = 0;
			this.head = null;

			this.add = function(value) {
				var node = new Node(value);
				var currentNode = this.head;

				if (!currentNode) {
					this.head = node;
					this._length++;
					return node;
				}

				while (currentNode.next) {
					currentNode = currentNode.next;
				}

				currentNode.next = node;

				this._length++;
				return node;
			};

			this.deleteNode = function(value) {
				var currentNode = this.head;
				var previousNode = null;

				//For the First Node
				if (currentNode.data == value) {
					//If there is only one node.
					if(this._length == 1) {
						this.head = null;
					} else {
						//If it is first node but not only one. Make currentNode->next element head.
						this.head = currentNode.next;
					}
				} else {
					//For more than one elements.
					while (currentNode) {

						previousNode = currentNode;
						currentNode = currentNode.next;

						if (currentNode.data == value) {
							previousNode.next = currentNode.next;
							break;
						}
					}
				}
			}

			this.swapNodes = function(valueOne, valueTwo) {
				var currentNode = this.head;
				var nodeOne = null, nodeOnePre = null, nodeTwo = null, nodeTwoPre = null;

				if(this._length == 1) {
					return;
				}

				nodeOne = this.head;
				while(nodeOne != null && nodeOne.data != valueOne) {
					nodeOnePre = nodeOne;
					nodeOne = nodeOne.next;
				}

				nodeTwo = this.head;
				while(nodeTwo != null && nodeTwo.data != valueTwo) {
					nodeTwoPre = nodeTwo;
					nodeTwo = nodeTwo.next;
				}

				if(nodeOne == null || nodeTwo == null) {
					return;
				}

				if(nodeOnePre != null) {
					nodeOnePre.next = nodeTwo;
				} else {
					this.head = nodeTwo;
				}

				if(nodeTwoPre != null) {
					nodeTwoPre.next = nodeOne;
				} else {
					this.head = nodeOne;
				}

				var tmp = nodeOne.next;
				nodeOne.next = nodeTwo.next;
				nodeTwo.next = tmp;
			}

			this.traverse = function() {
				var currentNode = this.head;
				var jsonObject = [];

				while (currentNode) {
					jsonObject.push({
						'value' : currentNode.data
					});
					currentNode = currentNode.next;
				}

				return jsonObject;
			}

		};

		return SingleLinkedList;

	});
});
After the Service is ready to use, we can inject that factory to the given controller. So that we can use the factory functions. As you can see in below example

SingleLinkedList” Factory has been injected to the controller. In this controller, I have defined a function “populateViewNodes” which reads the elements from the Factory function traverse in JSON format and populate them on html view.

controllers/homepage.js
'use strict';

define([ 'app' ], function(app) {
	app.controller('HomepageCtrl', [ '$location', '$scope', '$rootScope','$window',
			'SingleLinkedList', function($location, $scope, $rootScope,$window,SingleLinkedList) {

		$scope.singleLinkList = new SingleLinkedList();
		$scope.listElement = null;
		$scope.deleteNodeElement = null;

		$scope.shiftOne = null;
		$scope.shiftTwo = null;

		$scope.addElement = function() {
			if($scope.listElement.length === 0 || typeof $scope.listElement === 'undefined') {
				$window.alert("Please enter node value.");
			} else {
				$scope.singleLinkList.add($scope.listElement);
				$scope.populateViewNodes();
			}
		};

		$scope.deleteElement = function() {
			$scope.singleLinkList.deleteNode($scope.deleteNodeElement);
			$scope.populateViewNodes();
		}

		$scope.swapElements = function() {
			$scope.singleLinkList.swapNodes($scope.shiftOne,$scope.shiftTwo);
			$scope.populateViewNodes();
		}

		$scope.populateViewNodes = function() {
			var nodes = $scope.singleLinkList.traverse();
			var container = document.getElementById("nodes-container");

			angular.element(container).html("");

			angular.forEach(nodes, function(item) {
				var element = angular.element("
<div class='node'>" + item.value + "</div>
");
				angular.element(container).append(element);
			});
		};

	}]);
});
After controller, View is ready to manipulate the elements. Below is the view which contains form and inputs. views/homepage.html
<div class="main-cont">
<div class="left-cont">
<h3>Singly Linked List</h3>
<table class="form-table">
<tr>
<td><label>Add Node</label></td>
</tr>
<tr>
<td><input type="text" ng-model="listElement" /></td>
</tr>
<tr>
<td><input type="button" ng-click="addElement();" value="Add Node" /></td>
</tr>
<tr>
<td><label>Delete Node</label></td>
</tr>
<tr>
<td><input type="text" ng-model="deleteNodeElement" /></td>
</tr>
<tr>
<td><input type="button" ng-click="deleteElement();" value="Delete Node" /></td>
</tr>
<tr>
<td><label>Swap Nodes</label></td>
</tr>
<tr>
<td><input type="text" ng-model="shiftOne" /></td>
</tr>
<tr>
<td><input type="text" ng-model="shiftTwo" /></td>
</tr>
<tr>
<td><input type="button" ng-click="swapElements();" value="Swap Nodes" /></td>
</tr>
</table>
</div>
<div class="right-cont">
<div id="nodes-container"></div>
</div>
</div>
Index page which is the actual AngularJS application. index.html
<!DOCTYPE html>
<html>
<head>
    <base href="/AngPrj/">
	<meta charset="ISO-8859-1">
	<title>Home</title>
    			<link rel="stylesheet" type="text/css" href="css/main.css" />
</head>
<body>
<div class="main-cont" ui-view></div>
<script data-main="app/main" src="lib/requirejs/require.js"></script>
</body>
</html>
it’s done.

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *