zoukankan      html  css  js  c++  java
  • 第三章 线性表(C#实现)

    1、线性表

      概念::零个或多个数据元素的有序序列。

      描述:

    2、线性表的抽象数据类型:

      ADT线性表

      Data:线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType。其中除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素,数据元素之间的关系是一对一的关系。

      Operation

      Init(*L):初始化操作,建立一个空的线性表;

      IsEmpty(*L):判断线性表是否为空,若为空,则返回true,否则返回false;

      Clear(*L):清空线性表;

      GetElem(*L,i):返回线性表位置为i的元素;

      LocateElem(*L,e):返回线性表中与元素i相同值的位置;

      Insert(*L,i,e):在线性表i位置插入元素e;

      Delete(*L,i):删除线性表位置i的元素;

      GetLength(*L):获得当前线性表的长度。

    endADT

    3、线性表的顺序存储结构

      概念:用一段地址连续的存储单元存储线性表的数据元素。

      如图:

        

        算法的C#语言实现

        

      /// <summary>
        /// 线性表的顺序存储结构
        /// </summary>
        public class SequentialStorageLinearList<T>
        {
            //最大存放数量
            private int _maxLength;
    
            /// <summary>
            /// 最大存储数量
            /// </summary>
            public int MaxLength
            {
                get
                {
                    return _maxLength;
                }
            }
    
            // 当前存放位置
            private int _currentLength;
    
            private T[] _LinearList;
    
            //利用构造函数创建一个数组,用来存放数据
            public SequentialStorageLinearList(int maxLength)
            {
                if (maxLength <= 0)
                    throw new Exception("The length can not be less than zero.");
                _maxLength = maxLength;
                _currentLength = 0;
                _LinearList = new T[_maxLength];
            }
    
            /// <summary>
            /// 判断线性表是否为空
            /// </summary>
            /// <returns></returns>
            public bool IsEmpty()
            {
                return _currentLength == 0;
            }
    
            /// <summary>
            /// 清空所有的元素
            /// </summary>
            public void ClearAll()
            {
                if (_currentLength > 0)
                {
                    /*
                     * 在高级语言.net中,我们可以重新创建一个新的数组,将其指向当前的_linearList
                     *由于是托管代码,资源不需要手动释放,会自动释放
                     *但是在c语言中,我们需要手动的释放其占用的空间(free)
                     */
                    _LinearList = new T[0];
                }
            }
    
            /// <summary>
            /// 根据
            /// </summary>
            /// <param name="i"></param>
            /// <returns></returns>
            public T GetElement(int i)
            {
                if (_currentLength == 0 || _currentLength < i || i < 1)
                    throw new Exception("Not find any Element.");
                T t = _LinearList[i];
                return t;
            }
    
            /// <summary>
            /// 查找数据中是否存在元素e
            /// </summary>
            /// <param name="e"></param>
            /// <returns></returns>
            public int IndexOf(T e)
            {
                if (_currentLength == 0)
                    throw new Exception("The array is empty.");
                for (int i = 0; i < _currentLength; i++)
                {
                    T t = _LinearList[i];
                    /*
                     * T可能是引用类型,我们暂时的比较方式,不考虑重写equals
                     */
                    if (t.Equals(e))
                    {
                        return i;
                    }
                }
                return -1;
            }
    
            /// <summary>
            /// 在位置i处插入元素e
            /// </summary>
            /// <param name="e">待插入的元素e</param>
            /// <param name="i">插入位置i</param>
            public void Insert(T e, int i)
            {
                //数组已经存满
                if (_currentLength == _maxLength)
                    throw new Exception("The array is full.");
                //当i位置不在范围内
                if (i < 1 || i > _currentLength + 1)
                    throw new Exception("The location is illegal.");
                //若插入的数据不在表尾,在需要移动插入位置后面的数据一位
                if (i <= _currentLength - 1)
                {
                    for (int j = _currentLength - 1; j > i; j--)
                    {
                        _LinearList[j + 1] = _LinearList[j];
                    }
                }
                _LinearList[i - 1] = e;
                _currentLength++;
            }
    
            /// <summary>
            /// 删除位置i处的元素
            /// </summary>
            /// <param name="i">位置i</param>
            public void Delete(int i)
            {
                if (_currentLength == 0)
                    throw new Exception("The array is Empty.");
                if (i < 1 || i > _currentLength)
                    throw new Exception("The location is illegal.");
                //删除位置i元素后需要将i后面的元素依次递增一位
                if (i < _currentLength)
                {
                    for (int k = k-1; k < _currentLength; k++)
                    {
                        _LinearList[k - 1] = _LinearList[k];
                    }
                }
                _currentLength--;
            }
        }
    

    4、线性表的链式存储结构

      数据域:存储数据元素信息的域;

      指针域:存储直接后继位置的域;

      节点(Node):由数据域和指针域组成的数据元素ai的存储映像;

      我们把由n个节点链结成一个链表,即为线性表的链式存储结构。

      如图:

        

    5、单链表

      链表的每个将结点中只包含一个指针域,我们称为单链表。同时我们把链表中第  一个结点的存储位置称为头指针。同时在链表的第一个结点前附设一个结点,称  为头结点。

      单链表的C#实现:

      

     /// <summary>
        /// 单链表的实现
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class SingleNode<T>
        {
            /// <summary>
            /// 序号
            /// </summary>
            public int Index { get; private set; }
    
            /// <summary>
            /// 头指针
            /// </summary>
            public SingleNode<T> HeadNode { get; private set; }
    
            /// <summary>
            /// 指针域
            /// </summary>
            public SingleNode<T> NextNode { get; set; }
    
            /// <summary>
            /// 数据域
            /// </summary>
            public T Data { get; set; }
    
            public SingleNode()
            {
                HeadNode = new SingleNode<T>();
                Index = 0;
                NextNode = null;
            }
    
            public SingleNode(T t)
            {
                Data = t;
                NextNode = null;
            }
    
            /// <summary>
            /// 判断单链表是否为空
            /// </summary>
            /// <returns></returns>
            public bool IsEmpty()
            {
                return Index == 0;
            }
    
            /// <summary>
            /// 清空所有的元素
            /// </summary>
            public void ClearAll()
            {
                if (Index > 0)
                {
                    NextNode = null;
                    Data = default(T);
                    Index = 0;
                }
            }
    
            /// <summary>
            /// 获得位置为i的元素
            /// </summary>
            /// <param name="i"></param>
            /// <returns></returns>
            public SingleNode<T> GetElement(int i)
            {
                if (Index == 0 || Index < i || i < 1)
                    throw new Exception("Not find any Element.");
                SingleNode<T> head = HeadNode;
                SingleNode<T> next;
                for (int k = 0; k < Index; k++)
                {
                    next = head.NextNode;
                    if (next.Index == i)
                    {
                        return next;
                    }
                    head = next.NextNode;
                }
                return null;
            }
    
            /// <summary>
            /// 查找数据中是否存在元素e
            /// </summary>
            /// <param name="e"></param>
            /// <returns></returns>
            public int IndexOf(T e)
            {
                if (Index == 0)
                    throw new Exception("The array is empty.");
                SingleNode<T> head = HeadNode;
                SingleNode<T> next;
                for (int k = 0; k < Index; k++)
                {
                    next = head.NextNode;
                    if (next.Equals(e))
                    {
                        return next.Index;
                    }
                    head = next.NextNode;
                }
                return -1;
            }
    
            /// <summary>
            /// 在位置i处插入元素e
            /// </summary>
            /// <param name="e">待插入的元素e</param>
            /// <param name="i">插入位置i</param>
            public void Insert(T t, int i)
            {
                /*
                  *1.先判断i是否存在
                 *2.若存在则创建一个空节点,将值t赋给该空节点
                 *3.修改该节点的前驱和后继节点
                  */
                if (i < 1 || i > Index)
                    throw new Exception("The location is illegal.");
                //获得当前位置i的节点
                var preNode = GetElement(i);
    
                //创建空节点
                SingleNode<T> currentNode = new SingleNode<T>(t);
    
                //修改前驱节点指向当前节点
                var nextNode = preNode.NextNode;
                preNode.NextNode = currentNode;
    
                //将新节点的后继节点修改
                currentNode.NextNode = nextNode;
    
                Index++;
            }
    
            /// <summary>
            /// 删除位置i处的元素
            /// </summary>
            /// <param name="i">位置i</param>
            public void Delete(int i)
            {
                /*
                 *1.查找位置为i的节点
                 *2.修改节点的前继节点为查找节点的下一节点
                 */
                //获得当前位置i-1的节点
                if (i < 1 || i > Index)
                    throw new Exception("The location is illegal.");
                var preNode = GetElement(i - 1);
                var nextNextNode = preNode.NextNode.NextNode;
                preNode.NextNode = nextNextNode;
                Index--;
            }
        }
     

    6、循环链表

      将单链表中终端节点的指针端由空指针改为指向头节点,这样整个单链表就成为了一个环,这种头尾相接的单链表称为单循环链表。

      如图:

        

      实现代码类似与单链表。

    7、双向链表

      在单链表的每个节点中,再设置一个指向其前驱节点的指针,从而形成的链表,我们称为双向链表。

      如图:

        

      C#代码实现:

      

    8、链表和线性表的优缺点比较

        如图:

          

    9、参考资料:

       单链表的19种操作: http://www.cnblogs.com/lifuqing/archive/2011/08/20/List.html

        单链表的C#实现:http://www.cnblogs.com/linzheng/news/2011/07/14/2106173.html

  • 相关阅读:
    比较字符串
    angular 兼容ie7 bootstrap2兼容ie6
    angular $watch
    CSS超过指定的宽度加省略号
    出去html中的标签
    andriod自定义视图
    andriod创建用户界面(1)
    安卓Activity生命周期(转)
    迷你版mvc框架执行过程
    【03月04日】A股滚动市盈率PE历史新低排名
  • 原文地址:https://www.cnblogs.com/xiuyuanjing/p/4115254.html
Copyright © 2011-2022 走看看