【C# 数据结构与算法】线性表

 

 

 

 

 

 

线性表的实现方式

线性表的实现方式有下面几种

  1. 顺序表 :数组
  2. 单链表:list<>
  3. 单向循环链表
  4. 双向链表:linkedlist<>
  5. 循环链表:

 

 自定义顺序表

public class SequenceList<T>  {      private T[] items;     private int count;     private bool empty;     private bool full;     int capacity;     //列表的元素个数     public int Count { get => count; set => count = value; }     //判断列表是否为空     public bool Empty { get => count == 0; }     public bool Full { get => count == items.Length; }     public int Capacity {          get => capacity; set => capacity = value;                      }      //构造函数     public SequenceList(int count)       {items = new T[count] ;this.count=0;Capacity = count; }      public SequenceList() : this(16) { }               public SequenceList(T[] items)       {       count = items.Length ;         int capacity = count + 16;        this.items =new T[capacity];                for(int i = 0; i < count; i++)         {             this.items[i++] = items[i];         }                }       /// <summary>     /// 扩容数组     /// </summary>     private void AutoExtensionCacpacity()     {         capacity = this.items.Length * 2;         T[] newitems = new T[capacity];          this.items.CopyTo(newitems, 0);         this.items = newitems;      }       /// <summary>     /// 索引     /// </summary>     /// <param name=i></param>     /// <returns></returns>     /// <exception cref=IndexOutOfRangeException></exception>     public T this[int i]     {          get         {             if (i >= 0 && i<items.Length)              return   items[i];             else throw new IndexOutOfRangeException();         }         set         {             if (i > 0 && i < items.Length)                  items[i]=value;             else throw new IndexOutOfRangeException($index out of range in {this.GetType()});          }     }          /// <summary>     /// 查找list是否包含改值     /// </summary>     /// <param name=K></param>     /// <returns></returns>     public bool Contains(T K)     {        return  IndexOf(K) != -1 ? true : false;            }     public int IndexOf(T itme)     {         int  j = 0;         while (j < count && !itme.Equals(items[j]))             j++;         return j>=0 && j <count? j: -1;                       }           /// <summary>     /// 在指定的索引位置插入元素     /// </summary>     /// <param name=j>索引位置</param>     /// <param name=k>item</param>     public void Insert(int j ,T k)     {         if (j > items.Length)         {             AutoExtensionCacpacity();         }         if (j > count)         {             j = count;         }else if(j < 0)         {             j=0;         }         else         {             for(int i=count-1;i>=j && i<= count; i--)             {                 items[i+1] = items[i];             }             items[j] = k;         }         count++;      }           /// <summary>     /// 在尾部添加     /// </summary>     /// <param name=k>要添加item</param>     public void Append(T k)     {         if (count >= items.Length)         {             AutoExtensionCacpacity();         }         items[count] = k;         count++;         }      /// <summary>     /// 删除指定索引的元素     /// </summary>     /// <param name=i>元素的索引</param>     /// <exception cref=IndexOutOfRangeException></exception>     public void RemoveAt(int i)     {         if (i >= 0 && i < count)         {             for (int j=i+1;j<=count;j++)             {                 items[j-1] = items[j];             }                         count--;         }         else         {             throw  new IndexOutOfRangeException( );         }     }     public void Remove(T k)     {        int j= IndexOf(k);         if (j >= 0)         {             RemoveAt(j);         }     }     /// <summary>     /// 打印列表     /// </summary>     public void Show()     {         for(int i = 0; i < count; i++)         {             Console.Write (items[i] + );         }     }  }
View Code

 

单向链表

 

 

 

 

 

对应的C# 代码如下:

编写了如下功能:insert、reverse、Remove、RemoveAt、add

1、读取线程安全

2、未实现序列化功能

 
using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing.Drawing2D; using System.IO; using System.Text; using System.Threading; using System.Xml; using System.Xml.XPath; namespace LinearList; public class Sample {     public static void Main()     {            int[] vs = new int[10];         for (int i = 1; i < 10; i++)         {                           vs[i] = i;         }         CircularList<int> list = new(vs );          Console.WriteLine(list.Length);     }     public class  Node<T>     {         private T? item;         private Node<T>? next;          public T? Item { get => item; set => item = value; }         public Node<T>? Next { get => next; set => next = value; }          public Node(T value)         {                 item = value;                     }         public Node()         {          }                  public override  string ToString()         {             return  item.ToString();         }      }     //读取时线程安全     public class NodeList<T> where T : notnull     {          public  Node<T> Head;                  private int length;          [ThreadStatic] private static Node<T> currntNode;         public  Node<T>  CurrntNode         {             get {                 if (Head.Next == null) currntNode= Head;                                          return currntNode;             }             set {                currntNode = value;                 }         }         /// <summary>         /// 构造头节点,他是开始的标志         /// </summary>         public NodeList()         {             Head=new Node<T>();             currntNode = new();             CurrntNode = Head;         }         public NodeList(Node<T> firstnode) :this()         {             Head.Next = firstnode;         }         public NodeList( T [] array) : this()         {                          for (int i = 0; i < array.Length; i++)             {                                  Node<T> node = new  (array[i]);                                  CurrntNode.Next = node;                 if (i == 0)Head.Next = node;                     CurrntNode = CurrntNode.Next;             }                      }           /// <summary>         ///  列表长度 ,为了方便循环单向链表 继承后修改改方法,所以改方法设置成virtual          /// </summary>          public virtual int Length { get             {                  Node<T>? node = Head;                 length = 0;                 while (node != null)                 {                     node = node.Next;                     length++;                 }                 return length;             }              set => length = value; }         /// <summary>         /// 添加数据项 ,为了方便循环单向链表 继承后修改改方法,所以改方法设置成virtual          /// </summary>         /// <param name=item></param>         public virtual  void Add(T item)         {             Node<T> newNOde = new(item);             if (CurrntNode  == null) { CurrntNode = new(); CurrntNode = newNOde; Head = newNOde; }             else             {                 CurrntNode.Next = newNOde;                 CurrntNode = CurrntNode.Next;              }           }         /// <summary>         /// 输出完整的列表         /// </summary>         public void Print()         {             if (Head.Next != null) CurrntNode = Head.Next;              while (CurrntNode  != null)             {                  Console.WriteLine(CurrntNode.Item);                 CurrntNode = CurrntNode .Next;             }         }         /// <summary>         /// 是否是空列表         /// </summary>         public virtual bool IsEmpty{get{ return Head.Next == null; } }                   /// <summary>         /// suo'y         /// </summary>         /// <param name=item></param>         /// <returns></returns>         /// <exception cref=IndexOutOfRangeException></exception>         public virtual T this[int item]         {             get             {              if(item < 0)throw new IndexOutOfRangeException();              if(Head.Next==null) throw new IndexOutOfRangeException();             CurrntNode = Head.Next;                 int n = 0;              while( n!=item)                 {                     CurrntNode = CurrntNode.Next;                     n++;                 }                 return CurrntNode.Item;             }             set             {                 CurrntNode = Head.Next;                 int n = 0;                 while (n != item)                 {                     CurrntNode = CurrntNode.Next;                     n++;                 }                 CurrntNode.Item= value;             }         }          public override string ToString()         {             if(Head == null) return string.Empty;             CurrntNode = Head;                          StringBuilder str = new();             while (CurrntNode != null)             {                str.Append(CurrntNode.Item+ ) ;                 CurrntNode = CurrntNode.Next;             }             return str.ToString();         }         /// <summary>         /// 在指定的索引位置之后插入元素 ,为了方便循环单向链表 继承后修改改方法,所以改方法设置成virtual          /// </summary>         /// <param name=index>索引位置</param>         /// <param name=item></param>         /// <exception cref=IndexOutOfRangeException></exception>         public virtual void Insert(int index ,T item)         {             Node<T> node=new(item);             if(index<0||index>Length)throw new IndexOutOfRangeException();                          CurrntNode =Head;                            Node<T> nextnode = CurrntNode.Next;              int i = 0;             while (CurrntNode!=null)             {                 if (i == index)                 {                     break;                 }                 CurrntNode = nextnode;                 nextnode = nextnode.Next;                 i++;             }                   node.Next = CurrntNode!.Next;              CurrntNode.Next= node;                        }         /// <summary>         ///  在队列的末尾添加 数据元素         /// </summary>         /// <param name=item></param>         public virtual void Append(T item)         {             Node<T>  node =new(item);             if (Head == null) { Head = node;return; }             CurrntNode = Head;              Node<T> nextnode = CurrntNode.Next;             while (nextnode != null)             {                 CurrntNode = nextnode;             }             CurrntNode.Next = node;          }         /// <summary>         ///  删除出现item的数据元素           /// </summary>         /// <param name=item></param>         public void Remove(T item)         {                         if (Head == null) { throw new ArgumentOutOfRangeException(nameof(item)) ; }             CurrntNode = Head;              Node<T> nextnode = CurrntNode.Next;             if (CurrntNode.Item.Equals(item)) { Head = nextnode; }                         while (nextnode != null)             {                 if (nextnode.Item.Equals(item))                 {                     CurrntNode.Next=nextnode.Next;                     return;                 }                 CurrntNode = nextnode;                 nextnode = nextnode.Next;             }                     Console.WriteLine(  未找到删除的元素);               }         /// <summary>         /// 删除指定索引的元素         /// </summary>         /// <param name=i></param>         /// <exception cref=IndexOutOfRangeException></exception>         public void RemoveAt(int i)         {             if (Head == null || i < 0|| i >Length ) { throw new IndexOutOfRangeException(); }             if (i == 0){ Head = null; return; }             CurrntNode = Head;                       Node<T> nextnode = CurrntNode.Next;             int n = 0;                            while (nextnode != null)             {                 if (i-1==n)                 {                     CurrntNode.Next = nextnode.Next;                     return;                 }                 CurrntNode = nextnode;                 nextnode = nextnode.Next;                 n++;             }             if (Length == i) { CurrntNode = null;return; }             Console.WriteLine(未找到删除的元素);         }         public void Reverse()         {             if (Head.Next == null) return;             CurrntNode = Head.Next;                      Node<T> nextnode = CurrntNode.Next;                        Node<T> prenode;             int n = 0;             while (nextnode != null)             {                                 prenode = CurrntNode;                 if (n == 0) prenode.Next = null;                                  CurrntNode = nextnode;                  nextnode = nextnode.Next;                 CurrntNode.Next = prenode;                                 n++;              }                      Head.Next = CurrntNode;         }      } }
View Code

 


 单向循环单链表

定义:将链表的最后一个节点的指针域指向链表的头节点。

 

 

 

 

 

 对应的C# 代码如下:

 继承单向链表,并且重写其中方法

   public class CircularList<T> : NodeList<T> where T:notnull     {                 public CircularList():base()          {                       }         public CircularList(T[] array ):base()         {             Node<T> node;             CurrntNode = Head;             for (int i = 0; i < array.Length; i++)             {                 node = new(array[i]);                 CurrntNode.Next = node;                 CurrntNode = node;             }             CurrntNode.Next = Head;             }         public override int Length          {                          get             {                 if(Head.Next==null)return 0;                 CurrntNode = Head.Next;                 int n = 0;                 while (CurrntNode != Head )                 {                     n++;                     CurrntNode = CurrntNode.Next;                 }                 return n;             }                  }         public override bool IsEmpty =>Head.Next==null;     }
View Code

 

 

双向链表

 自定义双向链表:功能 add、 remove、 insert、 print

using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing.Drawing2D; using System.IO; using System.Text; using System.Threading; using System.Xml; using System.Xml.XPath; namespace LinearList; public class Sample {       static void Main()     {         DoubleDirectionList<int> doubleDirectionList = new DoubleDirectionList<int>();          for (int i = 0; i < 10; i++)         {             doubleDirectionList.Add(i);         }         doubleDirectionList.Print();         doubleDirectionList.Insert(2, 100);         doubleDirectionList.Print();         doubleDirectionList.RemoveAt(10);         doubleDirectionList.Print();      }       public class DNode<T> where T : notnull     {         private T item;         private DNode<T>? next;         private DNode<T>? prior;         public T Item { get => item; set => item = value; }         public DNode<T>? Next { get => next; set => next = value; }         public DNode<T>? Prior { get => prior; set => prior = value; }         public DNode(T item)         {             this.item = item;             next=prior=null;         }         public DNode()         {             next=prior = null;             item=default;         }     }     public class DoubleDirectionList<T> where T:notnull       {          private DNode<T> head;       [ThreadStatic]  private static  DNode<T> currentNode;         private int lenght;         public DoubleDirectionList ()         {             head = new DNode<T>();             currentNode  = head;         }         public virtual bool IsEmpty => head.Next == null;                   public DNode<T> Head { get => head; set => head = value; }         public DNode<T> CurrentNode { get => currentNode; set => currentNode = value; }         public int Lenght {              get             {                 currentNode = head.Next;                 int n = 0;                 while(currentNode != null)                 {                     currentNode=currentNode.Next;                     n++;                 }                  return n;             } set => lenght = value; }          /// <summary>         /// 添加节点         /// </summary>         /// <param name=item></param>         public virtual void Add(T item )         {             DNode<T> dNode = new(item);             if (head.Next==null)             {                 currentNode = head;                 currentNode.Next = dNode;                 dNode.Prior= currentNode;                 currentNode = currentNode.Next;              }             else             {                 while (currentNode.Next!= null)                 {                     currentNode = currentNode.Next;                 }                 currentNode.Next = dNode;                 dNode.Prior = currentNode ;              }                     }         public virtual void Print()         {             currentNode  = head.Next;             while (currentNode != null)             {                 Console.WriteLine(currentNode.Item);                 currentNode = currentNode.Next;                         }         }         /// <summary>         /// 在当前节点之前插入         /// </summary>         /// <param name=index></param>         /// <param name=item></param>         public virtual void Insert(int index ,T item)         {             currentNode = head.Next;             DNode<T> dNode = new(item);             if (head.Next == null)             {                 currentNode = head;                 currentNode.Next = dNode;                 dNode.Prior = currentNode;                 currentNode = currentNode.Next;              }             else             {                 int n = 0;                 while (n != index)                 {                                         currentNode = currentNode.Next;                     ++n;                 }                 if (n == index)                 {                     DNode<T> prior = currentNode.Prior;                     prior.Next = dNode;                     dNode.Prior = prior;                     currentNode.Prior = dNode;                     dNode.Next = currentNode;                   }                         }           }                  public virtual void RemoveAt(int index)         {             lenght = Lenght;             if (index < 0|| index>lenght) throw new  IndexOutOfRangeException();             if(head.Next == null) throw new OverflowException(list is null);             currentNode=head.Next;               int n = 0;             while(currentNode!=null)             {                  if (n == index)                 {                     if (n == 0 && currentNode.Next == null)                     {                          head.Next.Prior = null; head.Next = null; return;                       }                     DNode<T> priro = currentNode.Prior;                     DNode<T> next = currentNode.Next;                     if (next == null) {priro.Next = null; return; }                     priro.Next =  next;                     next.Prior = priro ;                 }                 currentNode =currentNode.Next;                 n++;             }                              }     }  }
View Code

 

 循环双向链表

 

 功能类似 就不写了。

 

 

 

 

 

空表:头指的next针指向自己

表示