【数据结构】 List 简单实现

   public class XList<T> : IEnumerable, IEnumerator
    {
        #region List 简单实现

        /// <summary>
        /// 存储数据 数组
        /// </summary>
        private T[] _items;

        /// <summary>
        /// 默认容量
        /// </summary>
        private const int DefaultLength = 4;

        /// <summary>
        /// 插入最后一个元素索引(初始化时没有元素,所以为 -1)
        /// </summary>
        private int _lastIndex = -1;

        /// <summary>
        /// 无参构造
        /// </summary>
        public XList()
        {
            _items = new T[DefaultLength];
        }

        /// <summary>
        /// 带初始容量的构造
        /// </summary>
        /// <param name="length"></param>
        public XList(int length)
        {
            if (length <= 0)
            {
                throw new Exception("长度必须大于0");
            }
            _items = new T[length];
        }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T this[int index]
        {
            get
            {
                CheckIndex(index); // 验证索引越界
                return _items[index];
            }
            set { Insert(index, value); }
        }

        /// <summary>
        /// 添加元素
        /// </summary>
        /// <param name="t"></param>
        public void Add(T t)
        {
            Insert(_lastIndex + 1, t);
        }

        /// <summary>
        /// 插入元素
        /// </summary>
        /// <param name="index"></param>
        /// <param name="t"></param>
        public void Insert(int index, T t)
        {
            if (index < 0)
            {
                throw new Exception("索引不能小于0");
            }
            KeepCapacity();
            if (index <= _lastIndex) // 插入位置已有元素
            {
                T[] temp = new T[Capacity];
                for (int i = 0; i < index; i++)
                {
                    temp[i] = _items[i];
                }
                temp[index] = t;
                for (int i = index; i <= _lastIndex; i++)
                {
                    temp[i + 1] = _items[i];
                }
                _items = temp;
            }
            else if (index == _lastIndex + 1) // 在末尾插入
            {
                _items[++_lastIndex] = t;
            }
            else
            {
                throw new Exception("索引越界");
            }
        }

        /// <summary>
        /// 按 索引 移除元素
        /// </summary>
        /// <param name="index"></param>
        public void Remove(int index)
        {
            CheckIndex(index);
            if (index != _lastIndex) // 移除元素不是最后一个元素
            {
                T[] temp = _items;
                for (int i = index; i < _lastIndex; i++)
                {
                    temp[i] = _items[i + 1];
                }
                _items = temp;
            }
            // 移除元素是最后一个元素,不做处理
            _lastIndex--;
        }

        /// <summary>
        /// 集合存储元素数量
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return _lastIndex + 1;
        }

        /// <summary>
        /// 清空集合
        /// </summary>
        public void Clear()
        {
            _lastIndex = -1;
        }

        /// <summary>
        /// 集合 容量
        /// </summary>
        private int Capacity
        {
            get
            {
                if (_items != null)
                {
                    return _items.Length;
                }
                return -1;
            }
        }

        /// <summary>
        /// 保证容量充足,如果数组容量不够就重置大小,容量扩大一倍
        /// </summary>
        private void KeepCapacity()
        {
            if (Capacity == -1) // 数组为 null 的情况
            {
                _items = new T[DefaultLength];
                return;
            }
            if (_lastIndex < Capacity - 1) // 容量足够
            {
                return;
            }
            // 容量不够
            int length = Capacity * 2;
            T[] temp = new T[length];
            for (int i = 0; i < this.Capacity; i++)
            {
                temp[i] = _items[i];
            }
            _items = temp;
        }

        /// <summary>
        /// 检查索引越界的情况
        /// </summary>
        /// <param name="index"></param>
        private void CheckIndex(int index)
        {
            if (index > _lastIndex)
            {
                throw new Exception("索引越界");
            }
        }

        #endregion

        #region 实现枚举

        #region IEnumerable 成员

        public IEnumerator GetEnumerator()
        {
            return this;
        }

        #endregion

        #region IEnumerator 成员

        private int _position = -1;

        public object Current
        {
            get { return _items[_position]; }
        }

        public bool MoveNext()
        {
            if (_position < _lastIndex)
            {
                _position++;
                return true;
            }
            return false;
        }

        public void Reset()
        {
            _position = -1;
        }

        #endregion

        #endregion
    }

算是比较简单的 List 的实现,暂时先这样,有些地方还得完善,
知识点 : 索引器,枚举器,其他的都比较简单

时间: 2024-08-04 01:18:41

【数据结构】 List 简单实现的相关文章

JavaScript数据结构——实现简单的散列表

散列算法的作用是尽可能快地在数据结构中找到一个值.如果数据很大,但是有需要遍历整个数据结构来查找到该值,花费的时间就太多了.所以散列表在查找方面中比较优势:使用散列函数,就知道具体位置,能够快速检索.散列函数的作用:给定一个key值,返回key值在表中的地址. 1 function HashTable(){ 2 //初始化散列表 3 var table=[]; 4 //散列函数(私有方法) 5 var loseloseHashCode = function(key){ 6 var hash=0;

Redis数据结构之简单动态字符串SDS

Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话,是远远不足以应对面试提问的.本文简单介绍了Redis底层最重要的数据结构 - 简单动态字符串(SDS) Redis使用C语言开发,但并没有使用C语言传统的字符串表示(以空字符结尾的字节数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串的(simple dynamic string,SDS

【数据结构】简单谈一谈二分法和二叉排序树BST查找的比较

二分法查找: 『在有序数组的基础上通过折半方法不断缩小查找范围,直至命中或者查询失败.』 二分法的存储要求:要求顺序存储,以便于根据下标随机访问 二分法的时间效率:O(Log(n)) 二分法的空间效率:原地查询 O(1) 二分法对应的搜索树是确定的. 二叉排序树查找: 『借助二叉排序树进行搜索,但因为所建立的树本身不一定是轴对称的,所以每次比较并不能确保减小一半范围.』 二叉树的存储要求:需要树形结构,相比顺序存储需要占用更多的空间,但也有链接型数据结构灵活可拓展的有点. 二叉排序树查找的时间复

C语言数据结构之 简单选择排序

算法:设所排序序列的记录个数为n.i取1,2,-,n-1,从所有n-i+1个记录(Ri,Ri+1,-,Rn)中找出排序码最小的记录,与第i个记录交换.执行n-1趟 后就完成了记录序列的排序. 编译器:VS2013 代码 #include "stdafx.h"#include<stdlib.h> //函数声明 void SelectSort(int a[], int n); //简单选择排序(从小到大) int main(){ int i,n,a[100]; printf(&

Redis 数据结构之简单动态字符串SDS

几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象.     例如:            set msg "hello world" 则redis在数据库中创建一个新的键值对,键和值都是一个字符串对象,底层实现都是一个sds对象.            rpush fruits "apple" "banana&quo

数据结构之简单排序的三种玩法

本文主要介绍,一个简单排序算法都可以有哪几种玩法(以选择排序为例,代码请在cpp文件下运行) 选择排序...总结为三个步骤就是: 1.在一段区间内找最大/最小元素. 2.将最大/最小元素与区间中的第一个值进行交换 3.缩小查找区间 如果你还没有理解?不用担心,请参考:选择排序_百度百科:http://baike.baidu.com/item/选择排序 玩法1:初窥门径 如果理解了选择排序的算法,想要把它实现成一段代码,对于代码能力比较强的小伙伴来说,并不是一件复杂的事情,因此我们达到的第一重境界

1469:数据结构:简单背包问题

本题难点:简单背包问题递归程序的理解 简单背包问题问题定义:有一个背包重量是S,有n件物品,重量分别是W0,W1...Wn-1问能否从这n件物品中选择若干件放入背包中使其重量之和正好为S 背包问题递归版本解释:其选择只有两种可能,选择一组物品中包含Wn-1 ,此时knap(s,n)的解就是knap(s - Wn-1,n-1)的解如果选择的物品中不包括Wn-1,这样knap(s,n)的解就是knap(s,n-1)的解knap(s,n) = true, 当 s=0时knap(s,n) = false

(hdu step 8.1.6)士兵队列训练问题(数据结构,简单模拟——第一次每2个去掉1个,第二次每3个去掉1个.知道队伍中的人数&lt;=3,输出剩下的人 )

题目: 士兵队列训练问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 56 Accepted Submission(s): 37   Problem Description 某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三

数据结构--排序--简单排序

1 /*插入排序--是基本排序里面性能比较好的(比较适合基本有序的排序) 2 *排序的思想:一个序列,前边是有序的,后边是无序的,拿出一个元素进行插入到已经有序 3 * 的部分(这里就涉及移动的操作)--先找到位置,再移动 4 *特点:一趟排序下来每个元素的位置可能不是固定的 5 *时间复杂度:O(N2) 6 *排序的稳定性:稳定的 7 *使用场景:数据基本有序的情况下 8 * */ 9 public class TestInsertSort { 10 11 public static void

Redis数据结构之简单动态字符串

Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将SDS用作Redis的默认字符串表示.在Redis中,C字符串只会作为字符串字面量,用在一些无需对字符串值进行修改的地方,例如打印日志. 一.SDS的结构定义 示例: 二.SDS与C字符串的区别1. 常数复杂度获取字符串长度C字符串长度计算:遍历整个字符串直至遇到代表字符串结尾的空字符,时间复杂度为O(N).SDS长