0
点赞
收藏
分享

微信扫一扫

C#数据结构学习笔记——数组

大沈投资笔记 2022-02-19 阅读 51

1 数组

1.1 C#中的数组

静态数组:int[] float[] double[] char[] string[]

特点:创建后容量无法改变

例如:

​ int[] arr = new int[10]

动态数组:ArrayList List(泛型)

特点:根据元素的数量,动态地调整数组的容量大小

class Program
    {
        static void Main(string[] args)
        {
            //数组
            int[] arr = new int[10];
            for (int i = 0; i < 10; i++)
            {
                arr[i] = i;
                Console.Write(arr[i] + " ");
            }
            Console.WriteLine();

            //动态数组ArrayList
            ArrayList a = new ArrayList(10);
            for (int i = 0; i < 15; i++)
            {
                a.Add(i);
                Console.Write(a[i] + " ");
            }
            Console.WriteLine();

            //泛型动态数组
            List<int> l = new List<int>(10);
            for (int i = 0; i < 15; i++)
            {
                l.Add(i);
                Console.Write(l[i] + " ");
            }

            Console.Read();
        }
}

在这里插入图片描述

1.2 实现一个存储整型元素的动态数组

using System;
using System.Collections.Generic;
using System.Text;

namespace DataStructure
{
    class Array1//编写动态数组框架
    {
        private int[] data;//存储元素的静态数组data
        private int N;//存储元素个数N

        public Array1(int capacity)//有参构造
        {
            data = new int[capacity];
            N = 0;
        }

        public Array1() : this(10) { }//无参构造
        //public Array1()
        //{
        //    data = new int[10];
        //    N = 0;
        //}

        private void ResetCapacity(int newCapacity)//重构数组容量,并把原有元素存储
        {
            int[] newData = new int[newCapacity];
            for (int i = 0; i < N; i++)
                newData[i] = data[i];

            data = newData;
        }

        public int Capacity//获取数组容量
        {
            get { return data.Length; }
        }

        public int Count//获取数组元素个数
        {
            get { return N; }
        }

        public bool IsEmpty//判断数组是否为空
        {
            get { return N == 0; }
        }

        public void Add(int index,int e)//添加元素到数组中的指定索引位置
        {
            if (index < 0 || index > N)//判断索引位置是否合法
                throw new ArgumentException("数组索引越界");

            if (N == data.Length)//判断数组容量是否满了
                ResetCapacity(2 * data.Length);

            for (int i= N-1;i >= index; i--)//从数组末尾向后移动元素
                data[i + 1] = data[i];

            data[index] = e;
            N++;
        }

        public void AddLast(int e)//数组末尾添加元素
        {
            Add(N, e);
        }

        public void AddFirst(int e)//数组头部添加元素
        {
            Add(0, e);
        }

        public int Get(int index)//获取指定索引位置元素
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("数组索引越界");

            return data[index];
        }

        public int GetFirst()//获取首个元素
        {
            return Get(0);
        }

        public int GetLast()//获取末尾元素
        {
            return Get(N - 1);
        }

        public void Set(int index,int newE)//修改指定索引的元素
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("数组索引越界");

            data[index] = newE;
        }

        public bool Contains(int e)//是否包含元素
        {
            for (int i = 0; i < N; i++)
            {
                if (data[i] == e)
                    return true;
            }

            return false;
        }

        public int IndexOf(int e)//搜索元素的索引
        {
            for (int i = 0; i < N; i++)
            {
                if (data[i] == e)
                    return i;
            }

            return -1;//找不到元素,返回-1
        }

        public int RemoveAt(int index)//删除指定索引的元素
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("索引超出了数组界限");

            int del = data[index];

            for (int i = index + 1; i <= N - 1; i++)//元素前移
                data[i - 1] = data[i];

            N--;
            data[N] = default(int);//释放末尾位置元素

            if (N == data.Length / 4)//数组长度只剩原来的四分之一,数组容量缩减
                ResetCapacity(data.Length / 2);

            return del;
        }

        public int RemoveFirst()
        {
            return RemoveAt(0);
        }

        public int RemoveLast()
        {
            return RemoveAt(N - 1);
        }

        public void Remove(int e)//删除指定元素
        {
            int index = IndexOf(e);
            if (index != -1)
                RemoveAt(index);
        }

        public override string ToString()//打印数组
        {
            StringBuilder res = new StringBuilder();
            res.Append(string.Format("Array1: count={0} capacity={1}\n", N, data.Length));
            res.Append("[");
            for (int i = 0; i < N; i++)
            {
                res.Append(data[i]);
                if (i != N - 1)
                    res.Append(", ");
            }
            res.Append("]");
            return res.ToString();
        }

    }
}

Main调用:

namespace DataStructure
{
    class Program
    {
        static void Main(string[] args)
        {
            //动态数组
            Array1 a = new Array1(10);

            for (int i = 0; i < 10; i++)
            {
                a.AddLast(i);
            }
            Console.WriteLine(a);

            a.AddLast(66);
            Console.WriteLine("末尾添加元素");
            Console.WriteLine(a);

            a.Add(2, 77);
            Console.WriteLine("在索引2添加元素");
            Console.WriteLine(a);

            Console.WriteLine("获取头部元素"+a.GetFirst());
            Console.WriteLine("获取尾部元素"+a.GetLast());
            Console.WriteLine("获取索引1的元素"+a.Get(1));

            a.Set(1, 1000);
            Console.WriteLine("修改索引1的元素");
            Console.WriteLine(a);

            a.RemoveAt(2);
            Console.WriteLine("删除索引2的元素");
            Console.WriteLine(a);
            a.Remove(4);
            Console.WriteLine("删除数据元素4");
            Console.WriteLine(a);

            Console.Read();
        }
    }
}

在这里插入图片描述

1.3 装箱和拆箱

装箱:值类型转换为引用类型

拆箱:引用类型转换为值类型

namespace DataStructure
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 10000000;
            Stopwatch t1 = new Stopwatch();//计时器
            Stopwatch t2 = new Stopwatch();
            Stopwatch t3 = new Stopwatch();
            Stopwatch t4 = new Stopwatch();

            Console.WriteLine("测试值类型对象int");
            t1.Start();
            List<int> l = new List<int>();
            for (int i = 0; i < n; i++)
            {
                l.Add(i);//不发生装箱
                int x = l[i];//不发生拆箱
            }
            t1.Stop();
            Console.WriteLine("List'time: " + t1.ElapsedMilliseconds + "ms");

            t2.Start();
            ArrayList a = new ArrayList();
            for (int i = 0; i < n; i++)
            {
                a.Add(i);//发生装箱,提供object实参,int类型转换为引用类型
                int x = (int)a[i];//发生拆箱,object转int,引用类型转换为值类型
            }
            t2.Stop();
            Console.WriteLine("ArrayList'time: " + t2.ElapsedMilliseconds + "ms");
            //频繁装箱拆箱影响性能

            Console.WriteLine("测试引用类型对象string");
            t3.Start();
            List<string> l2 = new List<string>();
            for (int i = 0; i < n; i++)
            {
                l2.Add("x");//不发生装箱
                string x = l2[i];//不发生拆箱
            }
            t3.Stop();
            Console.WriteLine("List'time: " + t3.ElapsedMilliseconds + "ms");

            t4.Start();
            ArrayList a2 = new ArrayList();
            for (int i = 0; i < n; i++)
            {
                a2.Add("X");//不发生装箱
                string x = (string)a2[i];//不发生拆箱,这里是object转换为string,同为引用类型
            }
            t4.Stop();
            Console.WriteLine("ArrayList'time: " + t4.ElapsedMilliseconds + "ms");

            Console.Read();
        }
    }
}

在这里插入图片描述

发生了拆箱装箱,运行时间较长,频繁装箱拆箱会影响性能。

1.4 泛型和非泛型

存储任意类型数据可以使用ArrayList,但是存储int类型 会频繁装箱拆箱,这时候我们可以使用泛型List

泛型数组List有两个优点:

  1. 对于存储值类型数据,性能更优

  2. 使代码清晰和保证类型安全

    List l=new List();

使用泛型实现动态数组,在上面原有Array1类修改

using System;
using System.Collections.Generic;
using System.Text;

namespace DataStructure
{
    class Array2<T>//编写动态数组框架
    {
        private T[] data;//存储元素的静态数组data
        private int N;//存储元素个数N

        public Array2(int capacity)//有参构造
        {
            data = new T[capacity];
            N = 0;
        }

        public Array2() : this(10) { }//无参构造
        //public Array1()
        //{
        //    data = new int[10];
        //    N = 0;
        //}

        private void ResetCapacity(int newCapacity)
        {
            T[] newData = new T[newCapacity];
            for (int i = 0; i < N; i++)
                newData[i] = data[i];

            data = newData;
        }

        public int Capacity//获取数组容量
        {
            get { return data.Length; }
        }

        public int Count//获取数组元素个数
        {
            get { return N; }
        }

        public bool IsEmpty//判断数组是否为空
        {
            get { return N == 0; }
        }

        public void Add(int index, T e)//添加元素到数组中的指定索引位置
        {
            if (index < 0 || index > N)//判断索引位置是否合法
                throw new ArgumentException("数组索引越界");

            if (N == data.Length)//判断数组容量是否满了
                ResetCapacity(2 * data.Length);

            for (int i = N - 1; i >= index; i--)//从数组末尾向后移动元素
                data[i + 1] = data[i];

            data[index] = e;
            N++;
        }

        public void AddLast(T e)//数组末尾添加元素
        {
            Add(N, e);
        }

        public void AddFirst(T e)//数组头部添加元素
        {
            Add(0, e);
        }

        public T Get(int index)//获取指定索引位置元素
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("数组索引越界");

            return data[index];
        }

        public T GetFirst()//获取首个元素
        {
            return Get(0);
        }

        public T GetLast()//获取末尾元素
        {
            return Get(N - 1);
        }

        public void Set(int index, T newE)//修改指定索引的元素
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("数组索引越界");

            data[index] = newE;
        }

        public bool Contains(T e)//是否包含元素
        {
            for (int i = 0; i < N; i++)
            {
                if (data[i].Equals(e))
                    return true;
            }

            return false;
        }

        public int IndexOf(T e)//搜索元素的索引
        {
            for (int i = 0; i < N; i++)
            {
                if (data[i].Equals(e))
                    return i;
            }

            return -1;
        }

        public T RemoveAt(int index)//删除指定索引的元素
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("索引超出了数组界限");

            T del = data[index];

            for (int i = index + 1; i <= N - 1; i++)
                data[i - 1] = data[i];

            N--;
            data[N] = default(T);

            if (N == data.Length / 4)
                ResetCapacity(data.Length / 2);

            return del;
        }

        public T RemoveFirst()
        {
            return RemoveAt(0);
        }

        public T RemoveLast()
        {
            return RemoveAt(N - 1);
        }

        public void Remove(T e)//删除指定元素
        {
            int index = IndexOf(e);
            if (index != -1)
                RemoveAt(index);
        }

        public override string ToString()//打印数组
        {
            StringBuilder res = new StringBuilder();
            res.Append(string.Format("Array1: count={0} capacity={1}\n", N, data.Length));
            res.Append("[");
            for (int i = 0; i < N; i++)
            {
                res.Append(data[i]);
                if (i != N - 1)
                    res.Append(", ");
            }
            res.Append("]");
            return res.ToString();
        }

    }
}

Main调用

namespace DataStructure
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] n = { 1, 2, 3, 4, 5, 6, 7, 8 };
            Array2<int> a = new Array2<int>();
            for (int i = 0; i < n.Length; i++)
                a.AddLast(n[i]);
            Console.WriteLine(a);

            string[] s = { "a", "b", "c", "d" };
            Array2<string> a2 = new Array2<string>();
            for (int i = 0; i < s.Length; i++)
                a2.AddLast(s[i]);
            Console.WriteLine(a2);

            Console.Read();
        }
    }

在这里插入图片描述

举报

相关推荐

0 条评论