数据结构线性表之单链表

单链表

  线性表的另外一种存 储结构——链式存储(Linked Storage),这样的线性表叫链表(Linked List)。链表不 要求逻辑上相邻的数据元素在物理存储位置上也相邻,因此,在对链表进行插入 和删除时不需要移动数据元素,但同时也失去了顺序表可随机存储的优点。

单链表的定义

  链表是用一组任意的存储单元来存储线性表中的数据元素(这组存储单元可 以是连续的,也可以是不连续的)。在存储数据元素时,除 了存储数据元素本身的信息外,还要存储与它相邻的数据元素的存储地址信息。 这两部分信息组成该数据元素的存储映像(Image),称为结点(Node)。把存储据元 素本身信息的域叫结点的数据域(Data Domain),把存储与它相邻的数据元素的存 储地址信息的域叫结点的引用域(Reference Domain)。

  如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链 表(Singly Linked List)。把该引用域叫 next。

  把单链表结点看作是一个类,类名为 Node。单链表结点类的实现如下 所示。 

 

 

 

public class Node<T> 
 { 
     private T data; //数据域
     private Node<T> next; //引用域
     //构造器
     public Node(T val, Node<T> p) 
     { 
         data = val; 
         next = p; 
     } 
     //构造器
     public Node(Node<T> p) 
     { 
         next = p; 
     } 
    //构造器
    public Node(T val) 
    { 
         data = val; 
         next = null; 
    } 
    //构造器
    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; 
        } 
    } 
 }

 

 

 

   把单链表看作是一个类,类名叫 LinkList。LinkList类也实现了接口 IListDS。LinkList类有一个字段 head,表示单链表的头引用,所以 head 的类型为 Node。

  单链表类 LinkList的实现说明如下所示。

    public class LinkList<T> : IListDS<T>
    {
        private Node<T> head; //单链表的头引用
                              //头引用属性
        public Node<T> Head
        {
            get
            {
                return head;
            }
            set
            {
                head = value;
            }
        }
        //构造器
        public LinkList()
        {
            head = null;
        }
        //求单链表的长度
        public int GetLength()
        {
            Node<T> p = head;
            int len = 0;
            while (p != null)
            {
                ++len;
                p = p.Next;
            }
            return len;
        }
        //清空单链表
        public void Clear()
        {
            head = null;
        }
        //判断单链表是否为空
        public bool IsEmpty()
        {
            if (head == null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //在单链表的末尾添加新元素
        public void Append(T item)
        {
            Node<T> q = new 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;
        }
        //在单链表的第i个结点的位置前插入一个值为item的结点
        public void Insert(T item, int i)
        {
            if (IsEmpty() || i < 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 = 1;
            while (p.Next != null && j < i)
            {
                r = p;
                p = p.Next;
                ++j;
            }
            if (j == i)
            {
                Node<T> q = new Node<T>(item);
                q.Next = p;
                r.Next = q;
            }
        }
        public void InsertPost(T item, int i)
        {
            if (IsEmpty() || i < 1)
            {
                Console.WriteLine("List is empty or Position is error!");
                return;
            }

            if (i == 1)
            {
                Node<T> q = new Node<T>(item);
                q.Next = head.Next;
                head.Next = q;
                return;
            }
            Node<T> p = head;
            int j = 1;
            while (p != null && j < i)
            {
                p = p.Next;
                ++j;
            }
            if (j == i)
            {
                Node<T> q = new Node<T>(item);
                q.Next = p.Next;
                p.Next = q;
            }
        }
        //删除单链表的第i个结点
        public T Delete(int i)
        {
            if (IsEmpty() || i < 0)
            {
                Console.WriteLine("Link is empty or Position is
               error!"); 
            return default(T);
            }
            Node<T> q = new Node<T>();
            if (i == 1)
            {
                q = head;
                head = head.Next;
                return q.Data;
            }
            Node<T> p = head;
            int j = 1;
            while (p.Next != null && j < i)
            {
                ++j;
                q = p;
                p = p.Next;
            }
            if (j == i)
            {
                q.Next = p.Next;
                return p.Data;
            }
            else
            {
                Console.WriteLine("The ith node is not exist!");
                return default(T);
            }
        }
        //获得单链表的第i个数据元素
        public T GetElem(int i)
        {
            if (IsEmpty())
            {
                Console.WriteLine("List is empty!");
                return default(T);
            }
            Node<T> p = new Node<T>();
            p = head;
            int j = 1;
            while (p.Next != null && j < i)
            {
                ++j;
                p = p.Next;
            }
            if (j == i)
            {
                return p.Data;
            }
            else
            {
                Console.WriteLine("The ith node is not exist!");
                return default(T);
            }
        }
        //在单链表中查找值为value的结点
        public int Locate(T value)
        {
            if (IsEmpty())
            {
                Console.WriteLine("List is Empty!");
                return -1;
            }
            Node<T> p = new Node<T>();
            p = head;
            int i = 1;
            while (!p.Data.Equals(value) && p.Next != null)
            {
                P = p.Next;
                ++i;
            }
            return i;
        }
    }

 (1)在单链表的头部插入结点建立单链表。 建立单链表从空表开始,每读入一个数据元素就申请一个结点,然后插在链 表的头部。图 2.11 展现了线性表(a1,a2,a3,a4)的链表建立过程。因为是在链表的 头部插入,读入数据的顺序和链表中的逻辑顺序是相反的。

 

 在头部插入结点建立单链表的算法如下:

    LinkList<int> CreateLListHead()
    {
        int d;
        LinkList<int> L = new LinkList<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;
    } 

(2)在单链表的尾部插入结点建立单链表。 头部插入结点建立单链表简单,但读入的数据元素的顺序与生成的链表中元 素的顺序是相反的。若希望次序一致,则用尾部插入的方法。因为每次是将新结 点插入到链表的尾部,所以需加入一个引用 R 用来始终指向链表中的尾结点,以 便能够将新结点插入到链表的尾部。图 2.12 展现了在链表的尾部插入结点建立 单链表的过程。

 

 在尾部插入结点建立单链表的算法如下:

    LinkList<int> CreateListTail()
    {
        Node<int> R = new Node<int>();
        int d;
        LinkList<int> L = new LinkList<int>();
        R = L.Head;
        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;
    }

 

posted @ 2021-10-14 16:33  JackYgy  阅读(186)  评论(0)    收藏  举报