Wednesday, April 18, 2007

3. Doubly-linked list

In addition to the properties of the singly-linked list, each node in a doubly-linked list contains a link to the previous node in the chain.
Program.cs


using System;
using System.Collections.Generic;
using System.Text;

namespace Doubly_LinkedList
{
class Program
{
static void Main(string[] args)
{
char Answer = 'y';
Node n;
Node head = new Node();
Node currNode;
Node TempNode;
currNode = head;

while (Answer == 'y')
{
n = new Node();
Console.Write("Enter Node Data: ");
n.Data = int.Parse(Console.ReadLine());
TempNode = currNode;
currNode.Next = n;
currNode = n;
currNode.Prev = TempNode;

Console.Write("Answer (y/n): ");
Answer = char.Parse(Console.ReadLine());
}

Console.WriteLine("Printing the Node Data: (Forward)");

TempNode = head;
while (TempNode.Next != null)
{

TempNode = TempNode.Next;
Console.WriteLine(TempNode.Data);
}

Console.WriteLine("Printing the Node Data: (BACKward)");

do
{
Console.WriteLine(currNode.Data);
currNode = currNode.Prev;
} while (currNode != head);

Console.Read();
}
}
}


Node.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace Doubly_LinkedList
{
class Node
{
public Node()
{
Data = 0;
Next = null;
Prev = null;
}
public int Data;
public Node Next;
public Node Prev;
}
}

2. Singly-linked list




Each node consists of one data member and one link to the next node. The last node in the chain will always point to a null value.

My implementation consists of two cs files including two classes.

Program.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace myLinkedList
{
class Program
{
static void Main(string[] args)
{
char Answer='y';
Node n;
Node head=new Node();
Node currNode;
currNode = head;

while (Answer == 'y')
{
n = new Node();
Console.WriteLine("Enter Node Data:");
n.Data = int.Parse(Console.ReadLine());
currNode.Next = n;
currNode = n;

Console.WriteLine("Answer (y/n): ");
Answer=char.Parse(Console.ReadLine());
}

Console.WriteLine("Printing the Node Data:");

while (head.Next != null)
{

head = head.Next;
Console.WriteLine(head.Data);
}

Console.Read();


}
}
}


myNode.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace myLinkedList
{
public class Node
{
public Node()
{
Data = 0;
Next = null;
}
public int Data;
public Node Next;

}
}

OVERVIEW:
Although, this program produces the output I desire, it causes a memory leak, doesn't it?

Notice the line: head = head.Next;

There is a virtual head node that is hidden. If we intended to create 3 nodes, the program actually creates 4 nodes. Then it starts printing the data by skipping the first node.

Tuesday, April 17, 2007

ClassLibrary: Creating dll files

As opposed to running a C# application as a Console application, we can define it as a ClassLibrary and include it within the other programs we are gonna implement in the future.

The main differences of a console application is as follows:



  • Console: The compiled file's extension is .exe so it is executable.
  • ClassLibrary: The compiled file's extension is .dll thus it is NOT executable by itself. However, it is well suited for inclusion by other programs.

ClassLibraries may be used in two ways:

  1. Private
  2. Public

for Private ClassLibraries:
Does it happen when we SIGN and explicitly select the .dll file in Visual Studio, under Project properties??

As for the public ClassLibraries:
The .dll file may be published to a global folder under Windows directory. So, any application can use it.


This process can be done as follows:
First of all, the project must be created as a ClassLibrary in Visual Studio.
Then implement the program codes just like I did in InterestCalculation program in the previous post. Compile the program. This will produce the .dll file.
Then go to VS Command Prompt and run this: > sn -k c:\easy.snk
You will get: > Key pair written to c:\easy.snk

  1. Next thing to do is to use .NET GLOBAL ASSEMBLY CACHE utility.
  2. In the command prompt, type: > gacutil -i C:\{Location of the .dll file}\InterestCalculation.dll
  3. This won't work: You'll get the following error: > Failure adding assembly to the cache: Attempt to install an assembly without a strong name.
  4. The reason was because we haven't digitally signed the project of ClassLibrary. This digital signature is a randomly generated key specific to each of the persons. This is what we did in the 1st step above.
  5. Go to Project Properties (Right-click in Solution Explorer) and switch to SIGNING TAB.
  6. Enable checkbox "Sign the Assembly." Choose a strong name key file. Browse and select the key file [C:\easy.snk in this example].
  7. Now re-do the 3rd step above.
  • This procedure required a minor fix in our case. In Visual Studio 2003, we had to correct the line [assembly: AssemblyKeyFile("")] as [assembly: AssemblyKeyFile(@"C:\easy.snk")]
  • I have Visual C# 2005 Express in my computer. Unfortunately, the above correction was NOT successful and now I am not able to install the assembly to global directory. If anybody has a idea about this, please post it to my blog. Thanks!

Overview:

The Global Assembly Cache is so useful to share the previously written program codes. This is a PUBLIC method of sharing the codes among applications. So, what is the PRIVATE method to accomplish this??

Let's assume that two developers Gerry and Jerry are team members for software development. They are responsible for implementing their own part. However, by mistake, they have used SAME namespace names in the implementation! What will happen during compilation of the project??

The Strong Name Tool (SN.exe) enables us to sign our assemblies with strong names. For the example above, even though Gerry and Jerry used same namespaces by mistake, the digital signing of the application will prevent any compile errors and enable each of the developers to use even the same names for namespaces and classes.

1. Interest Calculation

This is the first Console program I have written in the C# & .NET class:

Program.cs


using System;
using System.Collections.Generic;
using System.Text;


namespace Interest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the money (p):");
int p = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the rate of interest (R):");
double R = double.Parse(Console.ReadLine());
Console.WriteLine("Enter the time (T):");
int T = int.Parse(Console.ReadLine());

InterestCalc IC = new InterestCalc();
Console.WriteLine("Simple Interest:");
Console.WriteLine(IC.CalculateSimpleInterest(p, R, T));
Console.WriteLine("Compound Interest:");
Console.WriteLine(IC.CalculateCompoundInterest(p, R, T));
Console.Read();
}
}
}




InterestFunctions.cs



using System;
using System.Collections.Generic;
using System.Text;

namespace Interest
{
class InterestCalc
{
public InterestCalc()
{
}

public double CalculateSimpleInterest(int p, double r, int t)
{
return (p*r*t)/100;
}

public double CalculateCompoundInterest(int p, double r, int t)
{
return p*(1+r/100)*t;
}
}
}




WHAT I HAVE LEARNED?

The organization of the codes in C# consists of two main code blocks:

  1. namespace
  2. class
namespaces can include different classes. We can place the codes of each of the classes in different files.
-In this example, the class including the main program is named class Program{} and saved in Program.cs file.
-On the other hand, the second class including the functions for the interest calculation is named class InterestFunctions{} and is saved in InterestFunctions.cs file.

Both classes are implemented under the SAME namespace called namespace Interest{}.