Sequential tables store individual data elements in a linear table in sequential order of storage cells, logically adjacent data elements are also adjacent to the physical location. Therefore, it is convenient to find data elements in any one location in a sequential table, which is an advantage of sequential storage. However, when inserting and deleting sequential tables, it is necessary to implement them by moving data elements, which affects the efficiency of operation. Another type of storage structure for linear tables-chained storage (Linked Storage), such as a linear table called a linked list (Linked list). Linked lists do not require logically contiguous data elements to be adjacent to the physical storage location, so there is no need to move data elements when inserting and deleting the linked list, but it also loses the advantage of having the sequential table randomly stored.
The domain called the node that stores the information of the element itself (data domain), which stores the address information of the data element that is adjacent to it, is called the node's Reference field (Reference domain). If the reference field of a node stores only the storage address of the node's immediate successor, the linked list is called a single-linked list (singly Linked list). Call the Reference field next. Consider a single-linked list node as a class with the class name node<t>.
The implementation of the single-Link Table node class is as follows:
Node class public class node<t> { private T data;//store data domain private node<t> next;//store reference domain Public Node (T Val, node<t> node) { data = val; Next = node; } Public Node (T val) { data = val; next = null; } Public node (node<t> node) { next = node; } Public Node () { data = default (T); next = null; } Public T Data { get {return Data;} set {data = value;} } Public node<t> next { get {return next;} set {next = value;}}}
the single-linked list interface is implemented as follows:
Public interface ilistds<t>//single-linked list interface { int getlength ();//length void Clear ();//empty Operation BOOL IsEmpty ( ); void Append (T item); Attach operation void Insert (t item, int i);//insert operation t Delete (int i);//delete operation T Getelem (int i);//take TABLE element int Locate (t val UE); Find void Reverse by value ();//Inverted }
Single Linked list:
As shown by the graph, the single-linked list is referenced by the H uniquely determined. The header refers to the first node of the single-linked list, which is the address of the first node of the single-linked list in H, so H is a variable of Node type. A header reference of NULL indicates an empty table. Consider a single-linked list as a class, called linklist<t>. The Linklist<t> class also implements the interface ilistds<t>. The Linklist<t> class has a field head that represents the header reference for a single-linked list, so the head type is node<t>. Since the storage space of the list is not contiguous, there is no limit to the maximum space, and it is not necessary to determine whether the linked list is full when inserting nodes in the list.
The implementation instructions for the single-linked list class linklist<t> are as follows:
public class Linklist<t>: ilistds<t>//single-linked list class {private node<t> head; Public node<t> Head {get {return head;} set {head = value;} Public linklist () {head = NULL; } public int getlength () {int i = 0; while (head! = null) {head = head. Next; ++i; } return i; public void Clear () {head = NULL; } public bool IsEmpty () {return head = = NULL; The public void Append (T Item)//Adds a new element at the end of the single-linked list {node<t>-q =-node<t> (item); node<t> p = new node<t> (); if (head = = null) {head = q; Return } p = head; while (p.next! = null) {p = p.next; } P.next = q; }//Insert a value of item's node public void Insert (T item, int i) {if (IsEmpty ()) {if () at the position of node I of the single-linked list ; 1) {Console.WriteLine ("List is empty or Position is error!"); Return } if (i = = 1) {node<t> q = new node<t> (item); Q.next = head; head = q; Return } node<t> p = head; node<t> r = new node<t> (); int j = 0; while (P.next! = null && J < i) {++j; r = P; p = p.next; } if (i = = j) {node<t> q = new node<t> (item); Q.next = p; R.next = q; }}//After the position of the first node of the single-linked list, insert a node with the value of item public void Insertpost (T item, int i) {if (iSempty () | | I < 1) {Console.WriteLine ("List is empty or Position is error!"); Return } node<t> p = head; int j = 0; while (P.next! = null && J < i) {p = p.next; ++j; } if (i = = j) {node<t> q = new node<t> (item); Q.next = P.next; P.next = q; }} public T Delete (int i) {if (IsEmpty () | | < 1) {Consol E.writeline ("List is empty or Position is error!"); return default (T); } node<t> p = head; node<t> q = new node<t> (); int j = 0; while (P.next! = null && J < i) {q = p; p = p.next; ++j; } if (i = = j) {q.next = P.next; return p.data; } else {Console.WriteLine ("The ith node is not exist!"); return default (T); }} public T getelem (int i) {if (IsEmpty () | | < 1) {Conso Le. WriteLine ("List is empty or Position is error!"); return default (T); } node<t> p = head; int j = 0; while (P.next! = null && J < i) {p = p.next; ++j; } if (i = = j) {return p.data; } else {Console.WriteLine ("The ith node is not exist!"); return default (T); }} public int Locate (T value) {if (IsEmpty ()) {Console.writel INE ("List is empty!"); return-1; } node<t> p = head; int i = 0; while (!p.data.equals (value) && p.next! = null) {p = p.next; ++i; } return i; } public void Reverse () {node<t> p = head. Next; node<t> q = new node<t> (); Head. Next = null; while (P! = null) {q = p; p = p.next; Q.next = head. Next; Head. Next = q; }}//The establishment of a single linked list linklist<int> createlisthead ()//Header insertion node to create a single linked list {Linklist<int> ; L = new linklist<int> (); int d = int32.parse (Console.ReadLine ()); while (d! =-1) {node<int> p = new node<int> (d); P.next = L.head; L.head = p; D = Int32.Parse (Console.ReadLine ()); } return L; } linklist<int> Createlisttail ()//Create a single-linked list at the end of the insertion node {linklist<int> L = new Linklist<in T> (); node<int> R = L.head; int d = int32.parse (Console.ReadLine ()); while (d! =-1) {node<int> p = new node<int> (d); if (L.head = = null) {l.head = P; } else {r.next = p; } R = P; D = Int32.Parse (Console.ReadLine ()); } if (R! = null) {r.next = null; } return L; } }
But there is a problem: the single linked list described earlier allows direct access to its successor from a node, so the time complexity of finding a direct successor is O (1). However, to find the direct precursor node of a node, you can only start iterating through the nodes from the table's header reference. If Next of a node equals that node, then that node is the direct precursor to that node. In other words, the time complexity of finding the direct precursor node is O (n), and n is the length of the single linked list. Of course, we can also store the address of the direct predecessor node in the reference domain of the node instead of the address of the direct successor node. In this way, the time complexity of finding the direct precursor node is only O (1), but the time complexity of finding the direct successor node is O (n). If you want to find the direct precursor node and the time complexity of the direct successor node is O (1), then, you need to set two reference fields in the node, a direct node to save the address, called Prev, a direct successor node address, called Next, such a list is a doubly linked list (doubly Linked List). This leads to a doubly linked list.
C # single Linked list