自定义顺序表ArrayList

1.简介

  顺序表 ArrayList 是对数组 object[] 的再次封装

  相比于数组,顺序表的容量是可变的

2.这里我们尝试自己使用数组封装一个顺序表

using System;

namespace DataStructure
{
    /// <summary>
    /// 自定义顺序表
    /// </summary>
    public class ArrayListDS
    {
        private const int _defaulCapacity = 4; //数组的初始容器
        private object[] _items; // 存放数据的数组
        private int _size = 0; // 元素个数

        /// <summary>
        /// 无参构造函数,默认容量为0
        /// </summary>
        public ArrayListDS()
        {
            this._items = new object[0];
        }
        /// <summary>
        /// 带容量初始化构造函数
        /// </summary>
        /// <param name="capacity"></param>
        public ArrayListDS(int capacity)
        {
            if (capacity < 0)
                throw new ArgumentOutOfRangeException("capacity", "数组长度不能为负数");
            this._items = new object[capacity];
        }
        /// <summary>
        /// 元素个数
        /// </summary>
        public virtual int Count
        {
            get { return this._size; }
        }
        /// <summary>
        /// 容量
        /// </summary>
        public virtual int Capacity
        {
            get { return this._items.Length; }
            set
            {
                if (value != this._items.Length)
                {
                    if (value < this._size)
                        throw new ArgumentOutOfRangeException("value", "容量太小了");
                    // 开辟一个新的内存空间存储元素
                    object[] destinationArray = new object[value];
                    if (this._size > 0)
                        Array.Copy(this._items, 0, destinationArray, 0, this._size);
                    this._items = destinationArray;
                }
            }
        }
        /// <summary>
        /// 判断扩容
        /// </summary>
        private void EnsureCapacity()
        {
            // _items.Length是数组容量,_size是数组个数
            if (this._items.Length == this._size)
                this.Capacity = this.Capacity + _defaulCapacity;
        }
        /// <summary>
        /// 判断超出索引
        /// </summary>
        /// <param name="index">索引</param>
        private void OutIndex(int index)
        {
            if (index < 0 || index >= this._size)
                throw new ArgumentOutOfRangeException("index", "索引超出范围");
        }
        /// <summary>
        /// 添加元素
        /// </summary>
        /// <param name="value"></param>
        public virtual void Add(object value)
        {
            EnsureCapacity();
            this._items[this._size] = value;
            this._size++;
        }
        /// <summary>
        /// 索引器,可获取值、修改值、新增值
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns></returns>
        public virtual object this[int index]
        {
            get
            {
                OutIndex(index);
                return this._items[index];//获取值
            }
            set
            {
                if (index < 0 || index > this._size)
                    throw new ArgumentOutOfRangeException("index", "索引超出范围");
                if (index < this._size)//修改值
                    this._items[index] = value;
                if (index == this._size)//新增值
                    Add(value);
            }
        }
        /// <summary>
        /// 裁剪多余容量
        /// </summary>
        public virtual void TrimToSize()
        {
            this.Capacity = this._size;
        }
        /// <summary>
        /// 删除指定索引的元素
        /// </summary>
        /// <param name="index">索引</param>
        public virtual void RemoveAt(int index)
        {
            OutIndex(index);
            if (index < this._size - 1)
            {
                // 使删除元素后的所有元素向前移一位
                Array.Copy(this._items, index + 1, this._items, index, this._size - index - 1);
            }
            // 最后一位置空
            this._items[this._size - 1] = null;
            this._size--;
        }
        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public virtual void Insert(int index, object value)
        {
            if (index < 0 || index > this._size)
                throw new ArgumentOutOfRangeException("index", "索引超出范围");
            EnsureCapacity();
            if (index < this._size)
            {
                // 插入点后面的元素后移一位
                Array.Copy(this._items, index, this._items, index + 1, this._size - index);
            }
            this._items[index] = value;
            this._size++;
        }
    }
}

3.ArrayList 和 List<T> 优劣对比

  了解了ArrayList 的底层,我们知道它使用的是 object数组,会有装箱和拆箱的消耗

  List<T> 使用了泛型,类型安全,比ArrayList 性能更优,不过在使用的过程中 只能指定一种类型。

猜你喜欢

转载自www.cnblogs.com/wskxy/p/10898473.html
今日推荐