zoukankan      html  css  js  c++  java
  • 单链表

    带头结点的单链表。

    //Node.cs    结点类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Linklist
    {
        public class Node<T>
        {
            private T data;         //数据域
            private Node<T> next;   //引用域
    
            #region 构造函数
    
            public Node()
            {
                this.data = default(T);
                this.next = null;
            }
    
            public Node(T data)
            {
                this.data = data;
                this.next = null;
            }
    
            public Node(Node<T> next)
            {
                this.next = next;
            }
    
            public Node(T data, Node<T> next)
            {
                this.data = data;
                this.next = next;
            }
    
            #endregion
    
            #region 属性
    
            public T Data
            {
                get { return data; }
                set { data = value; }
            }
    
            public Node<T> Next
            {
                get { return next; }
                set { next = value; }
            }
    
            #endregion
    
        }
    }
    

    //LinkList.cs   单链表类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Linklist
    {
        /// <summary>
        /// 带头结点的单链表
        /// </summary>
        /// <typeparam name="T">泛型T</typeparam>
        public class LinkList<T> where T:IComparable<T>
        {
            private Node<T> head;   //头结点
    
            #region 构造函数
    
            public LinkList()
            {
                head = new Node<T>();
            }
    
            #endregion
    
            #region 属性
    
            public Node<T> Head
            {
                get { return head; }
                set { head = value; }
            }
            #endregion
    
            #region 单链表常规操作
    
            /// <summary>
            /// 求单链表长度
            /// </summary>
            /// <returns>长度</returns>
            public int GetLength()
            {
                Node<T> p = head.Next;
    
                int length = 0;
                while (p != null)
                {
                    length++;
                    p = p.Next;
                }
                return length;
            }
    
            /// <summary>
            /// 清空单链表
            /// </summary>
            public void Clear()
            {
                head.Next= null;
            }
    
            /// <summary>
            /// 判断单链表是否为空
            /// </summary>
            /// <returns>true or false</returns>
            public bool IsEmpty()
            {
                return head.Next == null;
            }
    
            /// <summary>
            /// 在单链表的末尾添加新元素
            /// </summary>
            /// <param name="item">元素</param>
            public void Add(T item)
            {
                Node<T> willToInsert = new Node<T>(item);
                Node<T> currentNode = new Node<T>();
    
                if (head.Next == null)
                {
                    head.Next = willToInsert;
                    return;
                }
    
                currentNode = head.Next;
                while (currentNode.Next != null)
                {
                    currentNode = currentNode.Next;
                }
    
                currentNode.Next = willToInsert;
            }
    
            /// <summary>
            /// 在单链表的第i个结点的位置前插入一个值为item的结点
            /// </summary>
            /// <param name="i">位置,从0开始的索引值</param>
            /// <param name="item">元素值</param>
            public void Insert(int i, T item)
            {
                if (IsEmpty() || i < 0)
                {
                    throw new InvalidOperationException("InvalidOperationException:链表为空或参数小于0,无法执行插入操作");
                }
    
                if (i >= this.GetLength())
                {
                    throw new InvalidOperationException("InvalidOperationException:插入位置超出范围,无法执行插入操作");
                }
    
                if (i == 0)
                {
                    Node<T> willToInsert = new Node<T>(item);
                    willToInsert.Next = head.Next;
                    head.Next = willToInsert;
                    return;
                }
    
                Node<T> currentNode = head.Next;
                Node<T> tmp = new Node<T>();
                int j = 0;
    
                while (currentNode.Next != null && j < i)
                {
                    tmp = currentNode;
                    currentNode = currentNode.Next;
                    j++;
                }
    
                if (j == i)
                {
                    Node<T> willToInsert = new Node<T>(item);
                    willToInsert.Next = currentNode;
                    tmp.Next = willToInsert;
                }
            }
    
            /// <summary>
            /// 在单链表的第i个结点的位置后插入一个值为item的结点
            /// </summary>
            /// <param name="i">位置,从0开始的索引值</param>
            /// <param name="item">元素值</param>
            public void InsertPost(int i, T item)
            {
                if (IsEmpty() || i < 0)
                {
                    throw new InvalidOperationException("InvalidOperationException:链表为空或参数小于0,无法执行向后插入操作");
                }
    
                if (i >= this.GetLength())
                {
                    throw new InvalidOperationException("InvalidOperationException:插入位置超出范围,无法执行向后插入操作");
                }
    
                if (i == 0)
                {
                    Node<T> willToInsert = new Node<T>(item);
                    willToInsert.Next = head.Next.Next;
                    head.Next.Next = willToInsert;
                    return;
                }
    
                Node<T> currentNode = head.Next;
                int j = 0;
    
                while (currentNode != null && j < i)
                {
                    currentNode = currentNode.Next;
                    j++;
                }
    
                if (j == i)
                {
                    Node<T> willToInsert = new Node<T>(item);
                    willToInsert.Next = currentNode.Next;
                    currentNode.Next = willToInsert;
                }
    
            }
    
            /// <summary>
            /// 删除单链表第i个结点
            /// </summary>
            /// <param name="i">索引值,从0开始</param>
            /// <returns>删除的结点的值</returns>
            public T Delete(int i)
            {
                if (IsEmpty() || i < 0)
                {
                    throw new ArgumentException("ArgumentException:参数不合法,无法执行删除操作");
                }
    
                Node<T> tmp = new Node<T>();
                if (i == 0)
                {
                    tmp = head.Next;
                    head.Next = tmp.Next;
                    return tmp.Data;
                }
    
                Node<T> currentNode = head.Next;
                int j = 0;
                while (currentNode.Next != null && j < i)
                {
                    j++;
                    tmp = currentNode;
                    currentNode = currentNode.Next;
                }
    
                if (j == i)
                {
                    tmp.Next = currentNode.Next;
                    return currentNode.Data;
                }
                else
                {
                    throw new InvalidOperationException("InvalidOperationException:结点不存在,无法执行删除操作");
                }
            }
    
            /// <summary>
            /// 获取第i个元素
            /// </summary>
            /// <param name="i">索引值,从0开始</param>
            /// <returns>返回结点的数据域</returns>
            public T GetElem(int i)
            {
                if (IsEmpty() || i < 0 || i > this.GetLength() - 1)
                {
                    throw new ArgumentException("ArgumentException:参数不合法,无法获取元素");
                }
    
                Node<T> currentNode = new Node<T>();
                currentNode = head.Next;
                int j = 0;
                while (currentNode.Next != null && j < i)
                {
                    j++;
                    currentNode = currentNode.Next;
                }
    
                return currentNode.Data;
            }
    
            /// <summary>
            /// 在单链表中查找值为item的结点
            /// </summary>
            /// <param name="item">需要查找的结点值</param>
            /// <returns>元素所在的位置,从0开始的索引值</returns>
            public int Locate(T item)
            {
                if (IsEmpty())
                {
                    throw new InvalidOperationException("InvalidOperationException:单链表为空,无法执行定位操作");
                }
    
                Node<T> currentNode = head.Next;
                int i = 0;
                while (!currentNode.Data.Equals(item) && currentNode.Next!= null)
                {
                    currentNode = currentNode.Next;
                    i++;
                }
                if (currentNode.Data.CompareTo(item)==0)
                    return i;
                else
                    return -1;
            }
    
            /// <summary>
            /// 倒置操作
            /// </summary>
            public void ReversLinkList()
            {
                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;
                }
            }
    
            #endregion
    
            #region 单链表的建立
    
            /// <summary>
            /// 静态方法,在单链表的头部插入结点建立单链表,造成链表中的数据与逻辑顺序相反
            /// </summary>
            /// <param name="items">数组</param>
            /// <returns></returns>
            public static LinkList<T> CreateListHead(T[] items)
            {
                LinkList<T> list = new LinkList<T>();
    
                for (int i = 0; i < items.Count<T>(); i++)
                {
                    Node<T> p = new Node<T>(items[i]);
                    p.Next = list.Head.Next;
                    list.Head.Next = p;
                }
    
                return list;
            }
    
            /// <summary>
            /// 静态方法,在单链表的尾部插入结点建立单链表,一般使用这个方法,符合逻辑
            /// </summary>
            /// <param name="items"></param>
            /// <returns></returns>
            public static LinkList<T> CreateListTail(T[] items)
            {
                Node<T> node = new Node<T>();
                LinkList<T> list = new LinkList<T>();
                node = list.Head.Next;
    
                for (int i = 0; i < items.Count<T>(); i++)
                {
                    Node<T> p = new Node<T>(items[i]);
                    if (list.Head.Next == null)
                    {
                        list.Head.Next = p;
                    }
                    else
                    {
                        node.Next = p;
                    }
                    node = p;
                }
    
                if (node != null)
                {
                    node.Next = null;
                }
    
                return list;
            }
            #endregion
    
    
            #region 合并操作
    
            /// <summary>
            /// 使用该方法的前提条件是,两个链表均以按非递减顺序排列
            /// </summary>
            /// <typeparam name="TItem"></typeparam>
            /// <param name="other"></param>
            /// <returns></returns>
            public LinkList<T> Merge<TItem>(LinkList<T> other) where TItem : T
            {
                LinkList<T> linklist = new LinkList<T>();
                Node<T> p = Head.Next;
                Node<T> q = other.Head.Next;
                Node<T> s = new Node<T>();
    
                linklist.Head = Head;
                linklist.Head.Next = null;
    
                while (p != null && q != null)
                {
                    if (p.Data.CompareTo(q.Data) < 0)
                    {
                        s = p;
                        p = p.Next;
                    }
                    else
                    {
                        s = q;
                        q = q.Next;
                    }
    
                    linklist.Add(s.Data);
    
                }
    
                if (p == null)
                {
                    p = q;
                }
                while (p != null)
                {
                    s = p;
                    p = p.Next;
                    linklist.Add(s.Data);
                }
    
                return linklist;
            }
            #endregion
        }
    }
    

  • 相关阅读:
    Redis 常用模式思路
    MacOS Catalina 10.15 利用shell脚本启动NGINX、MySQL、PHP
    windows上 python有多版本,如何管理,如何区别?
    20180813视频笔记 深度学习基础上篇(1)之必备基础知识点 深度学习基础上篇(2)神经网络模型视频笔记:深度学习基础上篇(3)神经网络案例实战 和 深度学习基础下篇
    20180813视频笔记 深度学习基础上篇(1)之必备基础知识点 深度学习基础上篇(2)神经网络模型
    数据集
    基于深度学习的目标跟踪
    使用GitHub+Hexo建立个人网站,并绑定自己的域名(Ubuntu环境下)
    使用jemdoc制作个人主页
    《2017全球人工智能人才白皮书》发布丨解读世界顶级AI牛人的秘密——腾讯研究院
  • 原文地址:https://www.cnblogs.com/dongliyang/p/2002332.html
Copyright © 2011-2022 走看看