数据结构入门(二)固定容量数组

简介:

注:本文仅供菜鸟和初级入门者参考,欢迎高手指导,切勿拍砖,兄弟身子骨单薄,承受不起。博客园原创文章,转载请注明作者和出处!

下面的代码包装了一个静态数组,它实现了上一节中 IList<T> 接口的全部功能;为了具有排序功能,同时实现了 ISortable<T> 接口。关于 IList<T> 接口和 ISortable<T> 接口请参见上一部分 数据结构入门(一)基本接口的设计。类名起为 FixedList<T> 表明数组的大小在对象构造后就不可改变,可自动扩展大小的数组会在下一节实现。

FixedList<T> 只具有一些最基本的功能。代码都有注释,十分简单。

在客户端测试 FixedList<T> 的时候,为数组设置了一个冒泡排序算法 ,排序的具体实现将在后面给出。

Arrays.cs 文件:

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


namespace  My
{
    
namespace Collections
    
{
        
/// <summary>
        
/// 固定容量数组
        
/// </summary>
        
/// <typeparam name="T">实现了 Equals() 方法的数据类型</typeparam>

        public class FixedList<T> : IList<T>, ISortable<T>
        
{
            
/// <summary>
            
/// 被包装的数组
            
/// </summary>

            private T[] elements;

            
/// <summary>
            
/// 数组的最大容量
            
/// </summary>

            private int capacity;

            
/// <summary>
            
/// 当前数组存储的数据个数
            
/// </summary>

            private int count;

            
/// <summary>
            
/// 选择的排序类,运用策略模式,选择不同的排序类会调用不同的排序方法
            
/// </summary>

            private ISort<T> sort;

            
/// <summary>
            
/// 验证容量是否有效,无效抛出异常
            
/// </summary>
            
/// <param name="capacity">数组的最大容量,应该大于等于零</param>

            private  void CapacityCheck(int capacity)
            
{
                
if (capacity < 0)
                
{
                    
string str = String.Format("无效的数组容量: {0}", capacity);
                    
throw new CollectionsException(str);
                }

            }


            
/// <summary>
            
/// 检查数组是否已满,已满则抛出异常
            
/// </summary>
            
/// <param name="capacity">数组的最大容量,应该大于等于零</param>
            
/// <param name="count">当前数组存储的数据个数,范围从 0 到 capacity - 1</param>

            private void FullCheck(int capacity, int count)
            
{
                
if (count == capacity)
                
{
                    
string str = String.Format("数组已满,无法继续添加数据。当前数组容量为 {0} !", capacity);
                    
throw new CollectionsException(str);
                }

            }


            
/// <summary>
            
/// 检查索引是否有效,无效则抛出异常
            
/// </summary>
            
/// <param name="index">索引,范围从 0 到 count - 1</param>
            
/// <param name="count">当前数组存储的数据个数,范围从 0 到 capacity - 1</param>

            private void IndexCheck(int index, int count)
            
{
                
if ((index > count - 1|| (index < 0))
                
{
                    
string str = String.Format("访问越界:当前数组有 {0} 个元素,试图访问索引为号 {1} 的元素!", count, index);
                    
throw new CollectionsException(str);
                }

            }

            
            
/// <summary>
            
/// 构造函数,申请数组空间
            
/// </summary>
            
/// <param name="capacity">设定数组的最大容量</param>

            public FixedList(int capacity)
            
{
                CapacityCheck(capacity);
                
this.capacity = capacity;
                elements 
= new T[capacity];
                count 
= 0;
            }


            
/// <summary>
            
/// 返回数组容量
            
/// </summary>

            public int Capacity
            
{
                
get return capacity; }
            }


            
/// <summary>
            
///返回当前数组内元素个数 
            
/// </summary>

            public int Count
            
{
                
get return count; }
            }


            
/// <summary>
            
/// 判断数组是否为空
            
/// </summary>

            public bool IsEmpty
            
{
                
get return (count == 0); }
            }


            
/// <summary>
            
/// 判断数组是否已满
            
/// </summary>

            public bool IsFull
            
{
                
get return (count == capacity); }
            }


            
/// <summary>
            
/// 设定一个排序类,数组将会用此类包装的排序方法进行排序
            
/// </summary>

            public ISort<T> Sort
            
{
                
set this.sort = value; }
            }


            
/// <summary>
            
/// 发出排序动作
            
/// </summary>

            public void DoSort()
            
{
                
this.sort.Do(this);
            }


            
/// <summary>
            
/// 遍历数组,将所有元素的值设为默认值
            
/// </summary>

            public void Clear()
            
{
                
for (int i = 0; i < count; i++)
                
{
                    elements[i] 
= default(T);
                }

                count 
= 0;
            }


            
/// <summary>
            
/// 将数据添加到数组的尾部,数组已满则抛出异常
            
/// </summary>
            
/// <param name="data">需要添加的数据</param>

            public void Add(T data)
            
{
                FullCheck(capacity, count);
                elements[count] 
= data;
                count
++;
            }


            
/// <summary>
            
/// 在某一位置插入数据,并向后移动其他数据,数组已满则抛出异常
            
/// </summary>
            
/// <param name="index">数据插入的位置,无效则抛出异常</param>
            
/// <param name="data">需要插入的数据</param>

            public void Insert(int index, T data)
            
{
                FullCheck(capacity, count);
                IndexCheck(index, count);
                System.Array.Copy(elements, index, elements, index 
+ 1, count - index);
                elements[index] 
= data;
                count
++;
            }


            
/// <summary>
            
/// 从位置 fromIndex 开始查找第一个符合的数据,并返回其的位置 
            
/// </summary>
            
/// <param name="data">要查找的数据</param>
            
/// <param name="fromIndex">开始查找的位置</param>
            
/// <returns>找到则返回数据所在位置,没找到则返回 -1</returns>

            private int IndexOf(T data, int fromIndex)
            
{
                IndexCheck(fromIndex, count);
                
for (int i = fromIndex; i < count; i++)
                    
if (data.Equals(elements[i]))
                    
{
                        
return i;
                    }

                
return -1;
            }


            
/// <summary>
            
/// 从头开始查找,直到找到第一个符合的数据,并返回其的位置 
            
/// </summary>
            
/// <param name="data">要查找的数据</param>
            
/// <returns>找到则返回数据所在位置,没找到则返回 -1</returns>

            public int IndexOf(T data)
            
{
                
return IndexOf(data, 0);
            }


            
/// <summary>
            
/// 判断一个数据是否在数组中存在
            
/// </summary>
            
/// <param name="data">要查找的数据</param>
            
/// <returns>找到则返回 true ,没找到则返回 false</returns>

            public bool Find(T data)
            
{
                
return IndexOf(data) >= 0;
            }


            
/// <summary>
            
/// 返回和设置某一位置的数据
            
/// </summary>
            
/// <param name="index">位置</param>
            
/// <returns>数据元素</returns>

            public T this[int index]
            
{
                
get
                
{
                    IndexCheck(index, count);
                    
return elements[index];
                }

                
set
                
{
                    IndexCheck(index, count);
                    elements[index] 
= value;
                }

            }


            
/// <summary>
            
/// 删除某一位置的数据,并前移动其后数据,以填充留出的空位
            
/// </summary>
            
/// <param name="index">要删除数据的位置</param>

            public void RemoveAt(int index)
            
{
                IndexCheck(index, count);
                
if (index < count - 1)
                
{
                    System.Array.Copy(elements, index 
+ 1, elements, index, count - index - 1);
                }

                
// 如果要删除的数据是最后一项,则不需要移动,直接 count-- 丢弃他就行了
                count--;
            }


            
/// <summary>
            
/// 查找第一个符合的数据并删除,并向前移动其后数据,以填充留出的空位 
            
/// </summary>
            
/// <param name="data">要删除的数据</param>

            public void Remove(T data)
            
{
                
int index = IndexOf(data);
                
if (index >= 0) RemoveAt(index);
            }


            
/// <summary>
            
/// 删除所有符合的数据,并前移动其后数据,以填充留出的空位
            
/// </summary>
            
/// <param name="data">要删除的数据</param>

            public void RemoveAll(T data)
            
{
                
int index = IndexOf(data, 0);
                
while (index >= 0)
                
{
                    RemoveAt(index);
                    index 
= IndexOf(data, index);
                }

            }


            
/// <summary>
            
/// 枚举器
            
/// </summary>
            
/// <returns></returns>

            public IEnumerator<T> GetEnumerator()
            
{
                
for (int i = 0; i < count; i++)
                    yield 
return elements[i];
            }


            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            
{
                
throw new Exception("未实现的方法!");
            }


        }

    }

}

客户端测试文件:Client.cs

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

namespace  Client
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            
try
            
{
                FixedList
<int> arr = new FixedList<int>(18);

                arr.Add(
36);
                arr.Add(
16);
                arr.Add(
36);
                arr.Add(
36);
                arr.Add(
27);
                arr.Add(
36);
                arr.Add(
36);
                arr.Add(
36);
                arr.Add(
99);
                arr.Add(
36);
                arr.Add(
16);
                arr.Add(
36);
                arr.Add(
999);
                arr.Add(
1);

                Console.Write(
"显示当前数据:");
                
foreach (int i in arr)
                    Console.Write(i 
+ "  ");
                Console.WriteLine(
"\n");

                Console.WriteLine(
"数组容量:" + arr.Capacity);
                Console.WriteLine(
"元素个数:" + arr.Count);
                Console.WriteLine(
"查找数据27:" + arr.Find(27));
                Console.WriteLine(
"查找数据72:" + arr.Find(72));
                Console.WriteLine(
"定位数据99:" + arr.IndexOf(99));
                Console.WriteLine(
"定位数据123:" + arr.IndexOf(123));

                

                Console.WriteLine(
"删除所有36");
                arr.RemoveAll(
36);

                Console.Write(
"显示当前数据:");
                
foreach (int i in arr)
                    Console.Write(i 
+ "  ");
                Console.WriteLine(
"\n");

                Console.WriteLine(
"删除最后一个数据");
                arr.RemoveAt(arr.Count 
- 1);

                Console.Write(
"显示当前数据:");
                
foreach (int i in arr)
                    Console.Write(i 
+ "  ");
                Console.WriteLine(
"\n");

                Console.WriteLine(
"数组容量:" + arr.Capacity);
                Console.WriteLine(
"元素个数:" + arr.Count);


                
//注意:这里用到了一个 BubleSort<T> 的排序类,
                
//它仅仅是一个包装了冒泡排序算法的类,实现了 ISort<T> 接口,后面将会介绍它
                Console.WriteLine("用冒泡法排序");
                arr.Sort
=new BubbleSort<int>();
                arr.DoSort();

                Console.Write(
"显示当前数据:");
                
foreach (int i in arr)
                    Console.Write(i 
+ "  ");
                Console.WriteLine(
"\n");

                Console.WriteLine(
"当前数组是否为空::" + arr.IsEmpty);
                Console.WriteLine(
"清空数组");
                arr.Clear();
                Console.WriteLine(
"当前数组是否为空::" + arr.IsEmpty);
                Console.Write(
"显示当前数据:");
                
foreach (int i in arr)
                    Console.Write(i 
+ "  ");
                Console.WriteLine(
"\n");
            }

            
catch (Exception e)
            
{
                
                 Console.WriteLine(e.Message );
            }

                    

            Console.Read();
        }

    }



}

运行效果如下:




本文转自左洸博客园博客,原文链接:http://www.cnblogs.com/myqiao/archive/2006/01/21/321141.html,如需转载请自行联系原作者

目录
相关文章
|
存储 Java 程序员
数据结构之 - 深入了解数组数据结构
数据结构之 - 深入了解数组数据结构
303 6
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
917 23
|
存储 算法 搜索推荐
探索常见数据结构:数组、链表、栈、队列、树和图
探索常见数据结构:数组、链表、栈、队列、树和图
723 64
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
343 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
517 5
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
380 4
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
236 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
存储 应用服务中间件 nginx
Nginx入门 -- 基本数据结构中之ngx_str_t,ngx_array_t
Nginx入门 -- 基本数据结构中之ngx_str_t,ngx_array_t
350 1
|
存储
【数据结构OJ题】轮转数组
力扣题目——轮转数组
147 2
【数据结构OJ题】轮转数组
|
应用服务中间件 nginx C语言
Nginx入门 -- 基本数据结构中之ngx_str_t,ngx_array_t
这两种数据结构是Nginx自定义数据类型的例子,它们证明了Nginx设计者在构建一个为高并发和高性能优化的web服务器时的精确和高效。理解这些数据结构是深入学习Nginx内部机制的基础,同时也是扩展和开发Nginx模块不可或缺的一部分知识。
396 1

热门文章

最新文章