代码改变世界

第3章 线性表的顺序存储c#实现---《大话数据结构》读书笔记

2012-01-04 23:22  海不是蓝  阅读(1081)  评论(5编辑  收藏  举报

线性表的定义

线性表(List):零个或多个数据元素的有限序对。

强调:

1.  线性表是有限的。

2.  元素之间是有顺序的。

3.  若存在多个元素,则第一个元素无前驱,最后一个元素无后继。

4.  其他每个元素都有且只有一个前驱和后继。

 

数学语言定义

若线性表记为(a1,ai-1,ai,ai+1,,an),则表中ai-1领先于aiai领先于ai+1,称ai-1ai的直接前驱元素,ai+1ai的直接后继元素。当i=1,2,n-1时,ai有且仅有一个直接后继,当i=2,3,n时,ai有且仅有一个直接前驱。

 

线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,称为空表。

 

线性表的顺序存储结构

 

顺序存储的定义

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

a1

a2

……

ai-1

ai

……

an

 

顺序表至少需要3个属性

1.  存储空间:一个一维数组,它的存储位置就是存储空间的存储位置。

2.  线性表的最大存储容量:数组长度MaxSize

3.  线性表的当前长度:length

注意

这里有2个概念:“数组的长度”和“线性表的长度“需要区分下

数组的长度是存放线性表的存储空间的长度,存储分配以后这个量是不变的。

线性表的长度是线性表中数据元素的个数,随着线性表的插入和删除等操作的进行,这个量是变化的。

 

地址的计算方法

存储器中每个存储单元都有自己的编号,这个编号称为地址。

假设线性表的每个元素占用c个存储单元,那么线性表中第i+1个数据元素的存储位置和i个数据元素的存储位置满足下列关系(LOC表示获得存储位置的函数)

LOC(ai+1)=LOC(ai)+c;

LOC(ai)=LOC(a1)+(i-1)*c;

--------------------------代码------------------------------

class Program

{

    static void Main(string[] args)

    {

        try

        {

            SeqList<string> list = newSeqList<string>(5);

            Console.WriteLine("IsEmpty={0}", list.IsEmpty());

            Console.WriteLine("插入3个元素");

            list[0] = "a";

            list[1] = "b";

            list[2] = "c";

            Console.WriteLine("IsEmpty={0}", list.IsEmpty());

            ShowList(list);

            Console.WriteLine("----------------------------------");

            Console.WriteLine("删除第2个元素");

            string str = list.Delete(2);

            Console.WriteLine("{0}", str);

            ShowList(list);

            Console.WriteLine("----------------------------------");

            Console.WriteLine("附加一个元素d");

            list.Append("d");

            Console.WriteLine("list长度={0} list最后一个元素索引是={1}", list.GetLength(), list.Last);

            ShowList(list);

            Console.WriteLine("----------------------------------");

            Console.WriteLine("删除第一个元素a,然后在第2个位置插入e");

            list.Delete(1);

            list.Insert("e", 2);

            ShowList(list);

            Console.WriteLine("----------------------------------");

            Console.WriteLine("按值查找c");

            Console.WriteLine("找到值={0},{0}的索引是={1}", list[list.Locate("c")], list.Locate("c"));

            Console.WriteLine("----------------------------------");

            Console.WriteLine("获取第二个元素={0}", list.GetElem(2));

            Console.WriteLine("----------------------------------");

            Console.WriteLine("清空list");

            list.Clear();//这里只是设置了顺序表的可访问的空间为0

            ShowList(list);

            Console.WriteLine("list长度={0} list最后一个元素索引是={1} list IsEmpty={2}", list.GetLength(), list.Last, list.IsEmpty());

 

 

        }

        catch (Exception ex)

        {

            Console.WriteLine(ex.Message);

        }

        Console.Read();

    }

    static void ShowList(SeqList<string> list)

    {

        for (Int32 i = 0; i < list.GetLength(); i++)

            Console.WriteLine(list[i]);

    }

}

public interface IListDS<T>

{

    Int32 GetLength();//求长度

    void Clear();//清空操作

    bool IsEmpty();//判断线性表是否为空

    void Append(T item);//附加操作

    void Insert(T item, Int32 i);//插入操作

    T Delete(Int32 i);//删除操作

    T GetElem(Int32 i);///获取表元

    Int32 Locate(T value);//按值查找

}

public class SeqList<T> : IListDS<T>

{

    private Int32 maxsize;//顺序表的容量

    private T[] data;//数组,用于存储顺序表中的数据元素

    private Int32 last;//指示顺序表最后一个元素的位置

    //索引器

    public T this[Int32 index]

    {

        get

        {

            if (index < 0 || index > last)

                throw new IndexOutOfRangeException("索引超出了数组界限");

            return data[index];

        }

        set

        {

            if (index < 0 || index > maxsize - 1)

                throw new IndexOutOfRangeException("索引超出了数组界限");

            data[index] = value;

            last++;

        }

    }

    //最后一个数据元素的位置属性

    public Int32 Last

    {

        get { return last; }

    }

    //容量属性

    public Int32 Maxsize

    {

        get { return maxsize; }

        set { maxsize = value; }

    }

    //构造器

    public SeqList(Int32 size)

    {

        data = new T[size];

        maxsize = size;

        last = -1;

    }

    //求顺序表的长度

    public Int32 GetLength()

    {

        return last + 1;

    }

    //清空顺序表

    public void Clear()

    {

        last = -1;

    }

    //判断顺序表是否为空

    public bool IsEmpty()

    {

        return last == -1 ? true : false;

    }

    //判断顺序表是否为满

    public bool IsFull()

    {

        return last == maxsize - 1 ? true : false;

    }

    //在顺序表的末尾添加新元素

    public void Append(T item)

    {

        if (IsFull())

        {

            Console.WriteLine("List is full");

            return;

        }

        data[++last] = item;

    }

    //在顺序表的第i个数据元素的位置插入一个数据元素

    public void Insert(T item, Int32 i)

    {

        if (IsFull())

        {

            Console.WriteLine("List is full");

            return;

        }

        if (i < 1 || i > last + 2)

        {

            Console.WriteLine("Position is error");

            return;

        }

        if (i == last + 2)

        {

            data[last + 1] = item;

        }

        else

        {

            for (Int32 j = last; j >= i - 1; --j)

            {

                data[j + 1] = data[j];

            }

            data[i - 1] = item;

        }

        ++last;

    }

    //删除顺序表的第i个数据元素

    public T Delete(Int32 i)

    {

        T tmp = default(T);

        if (IsEmpty())

        {

            Console.WriteLine("List is empty");

            return tmp;

        }

        if (i < 1 || i > last + 1)

        {

            Console.WriteLine("Position is error");

            return tmp;

        }

        else

        {

            tmp = data[i - 1];

            for (Int32 j = i - 1; j < last; ++j)

            {

                data[j] = data[j + 1];

            }

        }

        --last;

        return tmp;

    }

    //获取顺序表的第i个数据元素

    public T GetElem(Int32 i)

    {

        if (IsEmpty() || (i < 1) || (i > last + 1))

        {

            Console.WriteLine("List is empty or Position is error");

            returndefault(T);

        }

        return data[i - 1];

    }

    //在顺序表中查找值为value的数据元素

    public Int32 Locate(T value)

    {

        if (IsEmpty())

        {

            Console.WriteLine("List is empty");

            return -1;

        }

        Int32 i = 0;

        for (i = 0; i <= last; ++i)

        {

            if (value.Equals(data[i]))

                break;

        }

        if (i > last)

            return -1;

        return i;

    }

}

 

-----------------------------------------------------

时间复杂度分析

Int32 GetLength();//求长度

时间复杂度为O(1),这里就是固定的执行last + 1

 

void Clear();//清空操作

时间复杂度为O(1),这里就是固定的执行last = -1;

 

bool IsEmpty();//判断线性表是否为空

时间复杂度为O(1)

 

void Append(T item);//附加操作

时间复杂度为O(1)

 

void Insert(T item, Int32 i);//插入操作

当插入的节点在线性表的最后,那么就是添加一个元素,所以时间复杂度是O(1)

当插入节点在线性表的开头,那么被插入节点的后续都要向后移动。

所以时间复杂度为O(n)

 

 

T Delete(Int32 i);//删除操作

当删除节点在线性表的最后,时间复杂度为O(1)

当删除节点在线性表的开头,那么被删除节点的后续都要向前移动。

所以时间复杂度为O(n)

 

 

T GetElem(Int32 i);//获取表元

这个快,直接索引数组的元素,时间复杂度为O(1)

 

 

Int32 Locate(T value);//按值查找

最坏的情况就是一个for循环,把线性表的元素都循环对比一次,时间复杂度为O(n)

--------------------------------------------------------------------------------

运行截图