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

2022/5/12 9:47:42

本文主要是介绍【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针指向自己

表示

 

 

 

 

 

 

 

 

 

 

 

 

 


 



这篇关于【C# 数据结构与算法】线性表的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程