Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doubly Linked List to JSON

I've a three dimensional structure ... actually a doubly linked list with six nodes i.e. left, right, up, down, in, out. if one node is on the right side of other then that node will be defiantly on the left side of the first one. like

2D sample of 3D actual data struture

Actually this is a 3D structure, but for understanding purposes, I've given a 2D example. Now I've to convert it in JSON format, to send this data through WCF to a client, but as it contains loops so it couldn't be converted to JSON. I've these questions

  1. Can this type of doubly linked list be converted to JSON?
  2. Is there another way to do that?
  3. Any Other recommended Data Structure? If this is impossible using Doubly Linked List.

I'm using Json.Net to handle JSON.

My class is

public class Node
{
    public Document document = null;

    public Node left = null;
    public Node right = null;
    public Node up = null;
    public Node down = null;
    public Node inside = null;
    public Node outside = null;
}
like image 762
Zia Kiyani Avatar asked Jun 08 '14 11:06

Zia Kiyani


People also ask

What is doubly linked list in C?

Doubly linked list Doubly linked list is a complex type of linked list in which a node contains a pointer to the previous as well as the next node in the sequence. Therefore, in a doubly linked list, a node consists of three parts: node data, pointer to the next node in sequence (next pointer), pointer to the previous node (previous pointer).

How do you construct a doubly linked list in Python?

The above program constructs a doubly linked list by inserting the nodes using three insertion methods i.e. inserting the node at the front, inserting the node at the end and inserting the node after the given node. Next, we demonstrate the same operation as a Java implementation.

How to insert a node in doubly linked list?

Insertion operation of the doubly linked list inserts a new node in the linked list. Depending on the position where the new node is to be inserted, we can have the following insert operations. Insertion at front – Inserts a new node as the first node. Insertion at the end – Inserts a new node at the end as the last node.

How do you traverse a doubly linked list?

Only the first node (head) has its previous node set to null and the last node (tail) has its next pointer set to null. As the doubly linked list contains two pointers i.e. previous and next, we can traverse it into the directions forward and backward.


2 Answers

Json.Net can handle reference loops if you set the PreserveReferencesHandling option in the settings.

JsonSerializerSettings settings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects,
    Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(rootNode, settings);

This setting will cause the JSON to be written with special $id and $ref properties which allow the JSON to be deserialized back to the original references, assuming you are using Json.Net to deserialize on the client side. With this in place you should be able to use your existing object structure with no problem.

Demo:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        Node center = new Node { Name = "In House" };
        Node north = new Node { Name = "North of House" };
        Node west = new Node { Name = "Front of House" };
        Node east = new Node { Name = "Back of House" };
        Node south = new Node { Name = "South of House" };

        center.East = east;
        east.West = center;

        center.West = west;
        west.East = center;

        east.North = north;
        north.East = east;

        east.South = south;
        south.East = east;

        south.West = west;
        west.South = south;

        west.North = north;
        north.West = west;

        DumpNodes(center);

        Console.WriteLine();

        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
        settings.NullValueHandling = NullValueHandling.Ignore;
        settings.Formatting = Formatting.Indented;

        string json = JsonConvert.SerializeObject(center, settings);
        Console.WriteLine(json);

        Node node = JsonConvert.DeserializeObject<Node>(json, settings);

        Console.WriteLine();

        DumpNodes(node);
    }

    private static void DumpNodes(Node startingNode)
    {
        HashSet<Node> seen = new HashSet<Node>();
        List<Node> queue = new List<Node>();
        queue.Add(startingNode);
        while (queue.Count > 0)
        {
            Node node = queue[0];
            queue.RemoveAt(0);
            if (!seen.Contains(node))
            {
                seen.Add(node);
                Console.WriteLine(node.Name);
                Look("north", node.North, queue, seen);
                Look("west", node.West, queue, seen);
                Look("east", node.East, queue, seen);
                Look("south", node.South, queue, seen);
            }
        }
    }

    private static void Look(string dir, Node node, List<Node> queue, HashSet<Node> seen)
    {
        if (node != null)
        {
            Console.WriteLine("   " + dir + ": " + node.Name);
            if (!seen.Contains(node))
            {
                queue.Add(node);
            }
        }
    }
}

public class Node
{
    public string Name { get; set; }
    public Node North { get; set; }
    public Node South { get; set; }
    public Node East { get; set; }
    public Node West { get; set; }
}

Output:

In House
   west: Front of House
   east: Back of House
Front of House
   north: North of House
   east: In House
   south: South of House
Back of House
   north: North of House
   west: In House
   south: South of House
North of House
   west: Front of House
   east: Back of House
South of House
   west: Front of House
   east: Back of House

{
  "$id": "1",
  "Name": "In House",
  "East": {
    "$id": "2",
    "Name": "Back of House",
    "North": {
      "$id": "3",
      "Name": "North of House",
      "East": {
        "$ref": "2"
      },
      "West": {
        "$id": "4",
        "Name": "Front of House",
        "North": {
          "$ref": "3"
        },
        "South": {
          "$id": "5",
          "Name": "South of House",
          "East": {
            "$ref": "2"
          },
          "West": {
            "$ref": "4"
          }
        },
        "East": {
          "$ref": "1"
        }
      }
    },
    "South": {
      "$ref": "5"
    },
    "West": {
      "$ref": "1"
    }
  },
  "West": {
    "$ref": "4"
  }
}

In House
   west: Front of House
   east: Back of House
Front of House
   north: North of House
   east: In House
   south: South of House
Back of House
   north: North of House
   west: In House
   south: South of House
North of House
   west: Front of House
   east: Back of House
South of House
   west: Front of House
   east: Back of House

Working fiddle here: https://dotnetfiddle.net/EojsFA

like image 53
Brian Rogers Avatar answered Oct 19 '22 04:10

Brian Rogers


What you have is a network. One representation of this is a list of edges. Yours are all bidirectional it seems so it could look like this:

[
    {source:"Left Node", destination:"Center Node"},
    {source:"Center Node", destination:"Up Node"},
    {source:"Center Node", destination:"Down Node"},
    {source:"Center Node", destination:"Right Node"},
    ...
]

You could spit out Json using a traversal of the network. The specific algorithms depend on the specific network you have. However searching on network should give you all the sample code you need.

Doubly linked list is certainly NOT what you need unless you have an extremely specific network that can be traversed in sequence using each edge once only.

Another possibility is that you are really just dealing with Voxels. That is, all your nodes are just coordinates in a 3d cube. The fact that one voxel is adjacent to another then means there is a connection. So if Left Node is at <1,1,1> and Center Node is at <1,2,1> there is a connection because all the coordinates are the same except for Y which differs by only 1. Storage is simply a list of the existing nodes.

Your question mentions a 3D structure, so there seems to be a Voxel representation if nodes are all at a particular distance. If instead the distances are random then you would need to go the network route.

like image 31
Dirk Bester Avatar answered Oct 19 '22 02:10

Dirk Bester