线性表

本文详细介绍了线性表的两种基本存储结构——顺序存储结构和链式存储结构,并提供了具体的代码实现。对于顺序存储结构,讲解了初始化、插入、删除等基本操作;对于链式存储结构,则以单链表为例进行了深入探讨。

定义:

  n个数据元素的有序列

对于其中的数据元素,必须满足:

一、数据元素具有相同特性

二、相邻数据具有序偶关系:

  1、有唯一的第一和最后元素

  2、除第一元素外,每个元素有且只有唯一一个前序元素

  3、除最后一个元素外,每个元素有且只有唯一一个后序元素

存储结构:

  一、顺序存储结构:用一组地址连续的存储单元依次存储数据表的线性元素

    1、顺序表的基本操作:

      1)、初始化

      2)、插入

      3)、删除

    代码实现:    

    
        private T[] _list;
        public void Init(int maxCapacity = 100)
        {
            if (maxCapacity <= 0) throw new ArgumentException("maxCapcity无效");
            _maxCapcity = maxCapacity;
            _list = new T[maxCapacity];
        }

        private int _length;
        public int Lenght
        {
            get { return _length; }
        }

        private int _maxCapacity;
        public int MaxCapacity
        {
            get { return _maxCapacity; }
        }

        public T this[int index]
        {
            get
            {
                if (index >= Lenght) throw new IndexOutOfRangeException("index");
                return _list[index];
            }
            set
            {
                if (index >= MaxCapacity) throw new IndexOutOfRangeException("index");
                _list[index] = value;
            }
        }

        public void Insert(int location, T data)
        {
            if (_length >= MaxCapacity) throw new Exception("列表已满...");
            if (location < 1 && location > MaxCapacity) throw new ArgumentOutOfRangeException("location");
            var index = location - 1;
            // 将后面的元素往后移一位
            for (int i = MaxCapacity - 1; i > index; i--)
            {
                _list[i] = _list[i - 1];
            }
            _list[index] = data;
            _length++;
        }

        public void Delete(int location)
        {
            if (location < 1 && location > MaxCapacity) throw new ArgumentOutOfRangeException("location");
            var index = location - 1;
            // 将后面的元素往前移一位
            for (int i = index; i < Lenght - 1; i++)
            {
                _list[i] = _list[i + 1];
            }
            _list[Lenght - 1] = default(T);
            _length--;
        }

        public string OutputList()
        {
            var sb = new StringBuilder();
            for (int i = 0; i < MaxCapacity; i++)
            {
                sb.Append(string.Format("[{0}] ", _list[i]));
            }
            return sb.ToString();
        }
View Code

 

   二、链式存储结构:用一组任意的存储单元存储,存储单元不要求是连续的,物理结构反应不出逻辑结构;不可以随机读取,但是插入和删除方便。

  这样需要两个域来存储这些元素,一个存储数据元素本身,另一个需要存储元素之间的关联。那么这两个域就组成了一个节点,一个线性链表的存储结构就是一组节点。

    1、单链表

    代码实现: 

    
    /// <summary>
    /// 单链表
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SingleLinkedList<T> 
    {
        private class Node<TData>
        {
            public TData Data { get; set; }
            public Node<TData> NextNode { get; set; }
        }

        private Node<T> _head;
        public void Init(int maxCapacity = 100)
        {
            if (maxCapacity <= 0) throw new ArgumentException("maxCapacity无效");
            MaxCapacity = maxCapacity;
            _head = new Node<T>();
        }

        private Node<T> GetNodeByLocation(int location)
        {
            var next = _head.NextNode;
            int i = 1;
            while (next != null && i <= Length)
            {
                if (i == location)
                {
                    return next;
                }
                else
                {
                    next = next.NextNode;
                }
                i++;
            }
            return null;
        }

        /// <summary>
        ///<see cref="location"/>位置插入数据<see cref="data"/>
        /// </summary>
        /// <param name="location"></param>
        /// <param name="data"></param>
        public void Insert(int location, T data)
        {
            if (Length >= MaxCapacity) throw new Exception("队列已满");
            if (location < 1 || (Length != 0 && location > Length)) throw new ArgumentException("位置无效");
            if (location == 1)
            {
                _head.NextNode = new Node<T> { Data = data, NextNode = _head.NextNode };
            }
            else
            {
                var index = location - 1;   // 取此节点的前一个节点的索引
                var node = GetNodeByLocation(index);
                node.NextNode = new Node<T> { Data = data, NextNode = node.NextNode };
            }
            Length++;
        }

        public void Delete(int location)
        {
            var preNode = GetNodeByLocation(location - 1);
            if (preNode != null && preNode.NextNode != null)
            {
                // 把当前节点的前节点和当前节点的后节点关联起来
                preNode.NextNode = preNode.NextNode.NextNode;
            }
            Length--;
        }

        /// <summary>
        /// 通过位置取数据
        /// </summary>
        /// <param name="location"></param>
        /// <returns></returns>
        public T GetElementByLocation(int location)
        {
            if (location < 1 || location > Length) throw new ArgumentException("location");
            var node = GetNodeByLocation(location - 1);
            if (node != null) return node.Data;
            return default(T);
        }

        /// <summary>
        /// 包含
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool Contains(T obj)
        {
            if (obj == null) throw new ArgumentNullException("obj");
            var next = _head.NextNode;
            int location = 1;
            while (next != null && location <= Length)
            {
                if (next.Data != null && next.Data.Equals(obj))
                    return true;
                next = next.NextNode;
                location++;
            }
            return false;
        }

        /// <summary>
        /// 定位
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="startLocation"></param>
        /// <returns></returns>
        public int LocationOf(T obj, int startLocation = 1)
        {
            if (obj == null) throw new ArgumentNullException("obj");
            var next = _head.NextNode;
            int location = startLocation;
            while (next != null && location <= Length)
            {
                if (next.Data != null && next.Data.Equals(obj))
                    return location;
                next = next.NextNode;
                location++;
            }
            return -1;
        }

        public string OutputList()
        {
            var sb = new StringBuilder();
            int index = 1;
            var next = _head.NextNode;
            while (next != null && index <= Length)
            {
                sb.Append(string.Format("[{0}] ",next.Data));
                next = next.NextNode;
                index++;
            }
            return sb.ToString();
        }

        public int Length
        {
            get;
            private set;
        }

        public int MaxCapacity
        {
            get;
            private set;
        }
View Code

 

转载于:https://www.cnblogs.com/GuoJinPangZi/p/4162527.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值