C#数据结构之线性表

简介:

一:介绍

线性表是最基本,最简单也是应用最广的数据结构。线性表是线性数据的抽象,其特点是结构中的数据元素之间存在着一对一的线性关系,
是一种数据元素序列的数据结构。

线性表是由n>=0个相同的数据元素构成的有限序列,有限指的是线性表中的数据元素个数是有限的,并且每一个数据元素都有自己的位置。

二:代码实现

1.       线性表的一些通用操作,我们统一为接口:

public interface IListDS<T>
{
        int GetLength();

        void Clear();

        bool IsEmpty();

        void Append(T item);

        void Insert(T item, int i);

        T Delete(int i);

        T GetElem(int i);

        int Locate(T value);

        void Reverse();
}

2.       线性表中常见的有顺序表,单链表,双向链表,循环链表。

3.       顺序表

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text; 

namespace SeqDS

{

    public class SeqList<T>:IListDS<T>

    {

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

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

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

        //索引器

        public T this[int index]

        {

            get { return data[index]; }

            set { data[index] = value; }

        } 

        public int Last

        {

            get { return last; }

        } 

        public int Maxsize

        {

            get{return maxsize;}

            set { maxsize = value; }

        } 

        //构造器

        public SeqList(int size)

        {

            data = new T[size];

            maxsize = size;

            last = -1;

        } 

        //求顺序表的长度

        public int GetLength()

        {

            return last + 1;

        } 

        //清空顺序表

        public void Clear()

        {

            last = -1;

        } 

        //判断顺序表是否为空

        public bool IsEmpty()

        {

            if (last == -1)

                return true;

            else

                return false;

        } 

        //判断顺序表是否为满

        public bool IsFull()

        {

            if (last == maxsize - 1)

                return true;

            else

                return false;

        } 

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

        public void Append(T item)

        {

            if (IsFull())

            {

                Console.WriteLine("List is full");

                return;

            }

            data[++last] = item;

        } 

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

        public void Insert(T item, int 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 (int j = last; j > i - 1; --j)

                {

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

                }

                data[i - 1] = item;

            }

            ++last;

        } 

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

        public T Delete(int 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;

            }

            if (i == last + 1)

            {

                tmp = data[last--];

            }

            else

            {

                tmp = data[i - 1];

                for (int j = i; j <= last; ++j)

                {

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

                }

            }

 

            --last;

            return tmp;

        } 

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

        public T GetElem(int i)

        {

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

            {

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

                return default(T);

            }

 

            return data[i - 1];

        } 

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

        public int Locate(T value)

        {

            if (IsEmpty())

            {

                Console.WriteLine("List is Empty!");

                return -1;

            }

            int i = 0;

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

            {

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

                    break;

            }

            if (i > last)

                return -1;

            return i;

        } 

        public void Reverse()

        {

            T tmp = default(T);

            int length = GetLength();

            for (var i = 0; i < length / 2; i++)

            {

                tmp = data[i];

                data[i] = data[length - i - 1];

                data[length - i - 1] = tmp; 

            }

        } 

    }

}

4.  单向链表 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text; 

namespace SeqDS

{

    public class LinkList<T>:IListDS<T>

    {

        private Node<T> head;

        public Node<T> Head

        {

            get { return head; }

            set { head = value; }

        } 

        public LinkList()

        {

            head = null;

        } 

        public int GetLength()

        {

            Node<T> p = head;

            int len = 0;

            while (p != null)

            {

                ++len;

                p = p.Next;

            }

            return len;

        } 

        public bool IsEmpty()

        {

            if (head == null)

                return true;

            else

                return false;

        } 

        public void Clear()

        {

            head = null;

        } 

        public void Append(T item)

        {

            Node<T> q = new Node<T>(item);

            Node<T> p=new Node<T>();

            if(head==null)

            {

                head=p;

                return;

            }

            p=head;

            while(p.Next!=null)

            {

                p=p.Next;

            }

            p.Next=q;

        } 

        public void Insert(T item, int i)

        {

            if(IsEmpty()||i<1)

            {

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

                return;

            } 

            if (i == 1)

            {

                Node<T> q = new Node<T>(item);

                q.Next = head;

                head = q;

                return;

            }

            Node<T> p = head;

            Node<T> r = new Node<T>();

            int j = 1;

            while (p.Next != null && j < i)

            {

                r = p;

                p = p.Next;

                ++j;

            } 

            if (j == i)

            {

                Node<T> q = new Node<T>(item);

                q.Next = p;

                r.Next = q;

            }

        } 

        public void InsertPost(T item, int i)

        {

            if (IsEmpty() || i < 1)

            {

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

                return;

            }

            if (i == 1)

            {

                Node<T> q = new Node<T>(item);

                q.Next = head.Next;

                head.Next = q;

                return;

            }

            Node<T> p = head;

            int j = 1;

            while (p != null && j < i)

            {

                p = p.Next;

                ++j;

            }

            if (j == i)

            {

                Node<T> q = new Node<T>(item);

                q.Next = p.Next;

                p.Next = q;

            }

        } 

        public T Delete(int i)

        {

            if (IsEmpty() || i < 0)

            {

                Console.WriteLine("Link is empty or Positon is error");

                return default(T);

            }

            Node<T> q = new Node<T>();

            if (i == 1)

            {

                q = head;

                head = head.Next;

                return q.Data;

            }

            Node<T> p = head;

            int j = 1;

            while (p.Next != null && j < i)

            {

                ++j;

                q = p;

                p = p.Next;

            } 

            if (j == i)

            {

                q.Next = p.Next;

                return p.Data;

            }

            else

            {

                Console.WriteLine("The ith node is not exist!");

                return default(T);

            }

        } 

        public T GetElem(int i)

        {

            if (IsEmpty())

            {

                Console.WriteLine("List is empty");

                return default(T);

            } 

            Node<T> p = new Node<T>();

            p = head;

            int j = 1; 

            while (p.Next != null && j < i)

            {

                ++j;

                p = p.Next;

            }

            if (j == i)

            {

                return p.Data;

            }

            else

            {

                Console.WriteLine("the ith node is not exist!");

                return default(T);

            }

        } 

        public int Locate(T value)

        {

            if (IsEmpty())

            {

                Console.WriteLine("List is Empty");

                return -1;

            }

            Node<T> p = new Node<T>();

            p = head;

            int i = 1;

            while (!p.Data.Equals(value) && p.Next != null)

            {

                p = p.Next; ;

                ++i;

            }

            return i;

        } 

        public void Reverse()

        {

            Node<T> p = head.Next;

            Node<T> q = new Node<T>();

            head.Next = null;

            while (p != null)

            {

                q = p;

                p = p.Next;

                q.Next = head.Next;

                head.Next = q;

            }

        }

    } 

    public class Node<T>

    {

        private T data;//数据域

        private Node<T> next;//引用域

 

        public Node(T val, Node<T> p)

        {

            data = val;

            next = p;

        } 

        public Node(Node<T> p)

        {

            next=p;

        }

        public Node(T val)

        {

            data = val;

            next = null;

        }

        public Node()

        {

            data = default(T);

            next = null;

        } 

        public T Data

        {

            get { return data; }

            set { data = value; }

        }

        public Node<T> Next

        {

            get { return next; }

            set { next = value; }

        }       

    }

}

下面实现两个创建链表的函数如下:

//在头部插入结点建立单链表

        static LinkList<int> CreateListHead()

        {

            int d;

            LinkList<int> l = new LinkList<int>();

            d = Int32.Parse(Console.ReadLine());

            while (d != -1)

            {

                Node<int> p = new Node<int>(d);

                p.Next = l.Head;

                l.Head = p;

                d = Int32.Parse(Console.ReadLine());

            }

            return l;

        } 

        //在尾部插入节点建立单链表

        static LinkList<int> CreateListTail()

        {

            Node<int> r = new Node<int>();

            int d;

            LinkList<int> l = new LinkList<int>();

 

            r = l.Head;

            d = Int32.Parse(Console.ReadLine());

 

            while (d != -1)

            {

                Node<int> p = new Node<int>(d);

                if (l.Head == null)

                {

                    l.Head = p;

                }

                else

                {

                    r.Next = p;

                }

                r = p;

                d = Int32.Parse(Console.ReadLine());

            }

            if (r != null)

            {

                r.Next = null;

            }

            return l;

        } 

5.       双向链表

5.1.双向链表的结点实现如下:

public class DbNode<T>

    {

        private T data;

        private DbNode<T> prev;

        private DbNode<T> next;

 

        public DbNode(T val, DbNode<T> p)

        {

            data = val;

            next = p;

        }

        public DbNode(DbNode<T> p)

        {           

            next = p;

        }

        public DbNode(T val)

        {

            data = val;

            next = null;

        }

        public DbNode()

        {

            data = default(T);

            next = null;

        } 

        public T Data

        {

            get { return data; }

            set { data = value; }

        }

        public DbNode<T> Prev

        {

            get { return prev; }

            set { prev = value; }

        }

        public DbNode<T> Next

        {

            get { return next; }

            set { next = value; }

        }

}

5.2. 插入

由于双向链表的结点有两个引用,所以在双向链表中插入和删除结点比单链表要复杂,双向链表中结点的插入也分前插和后插,例如:设p指向某一结点,即p存储的是结点的地址,现将s插入到p前面,插入过程如下图:

clip_image002

对应的操作如下:

p.Next.Prev=s;

s.Prev=p;

s.Next=p.Next;

p.Next=s;

5.3.删除

我们以删除p结点的后面的结点为例,删除过程如下:

clip_image004

操作如下:

p.Next=p.Next.Next;

P.Next.Prev=p.Prev;

双向链表的其他操作与单链表相似。


本文转自生鱼片博客园博客,原文链接http://www.cnblogs.com/carysun/archive/2009/09/13/ds-Seq.html,如需转载请自行联系原作者

相关文章
|
存储 C语言
数据结构中的线性表链式存储介绍及其基本操作
链式存储是线性表的一种重要存储方式,它通过节点和指针的结构,实现了灵活的动态存储管理。本文介绍了单向链表的基本操作,并提供了相应的C语言代码示例。理解和掌握链表的操作对学习和应用数据结构具有重要意义。希望这篇博客能帮助你更好地理解线性表的链式存储。
313 2
|
8月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
207 7
|
8月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
307 5
|
8月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
182 5
|
11月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
125 6
|
11月前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
87 1
|
10月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
11月前
01(数据结构考研)线性表相关操作代码
01(数据结构考研)线性表相关操作代码
147 0
|
11月前
|
存储 C语言
数据结构之线性表的初始化及其操作
数据结构之线性表的初始化及其操作
154 0
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
417 7