数据结构:线性表

线性表

  • 线性表的定义:Linear List是由n个相同类型的数据元素a0,a1,...a(n-1)组成的序列,即表中除首尾元素外,其他元素有且仅有一个直接前驱和直接后继。首元素仅有一个直接后继,尾元素仅有一个直接前驱在这里插入图片描述
  • 表中数据元素的个数称为表的长度
线性表的操作
  • 随机存取:获取或设置指定索引处的数据元素值(支持索引器)
  • 插入操作:将数据元素值插入到指定索引处
  • 移除操作:移除线性表指定索引处的数据元素
  • 查找操作:寻找具有特征值域的结点并返回其下标
  • 得到表长:获取线性表中实际包含数据元素的个数
  • 是否为空:判断线性表中是否包含数据元素
  • 清空操作:移除线性表中的所有数据元素
    在这里插入图片描述
using System;
using System.Collections.Generic;
using System.Text;

namespace DataStruct2020.demo
{
    public interface ILinearList<T>
    {
        int Length { get; }
        T this[int index] { get; set; }
        void Clear();
        void Insert(int index, T data);
        bool IsEmpty();
        void Remove(int index);
        int Search(T data);
    }
}

  • 泛型约束:
    public interface ILinearList<T> where T : IComparable<T>
线性表的存储与实现

顺序存储Sequence List

  • 顺序存储:顺序表,逻辑结构与物理结构相同
    顺序表:
  • 定义:利用顺序存储结构(即利用数组)实现的线性表
  • 特点:逻辑结构与存储结构相同,具有随机存取的特点,但需要一块连续的存储空间
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
//接口比较简单,略
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStruct2020.demo
{
    public class SeqList<T> : ILinearList<T> where T : IComparable<T>
    {
        private T[] _dataset;
        private int _maxSize;
        private int _length;
        public int Length
        {
            get 
            {
                return _length;
            }
        }
        public int MaxSize 
        {
            get 
            {
                return _maxSize;
            }
        }
        public SeqList(int max) 
        {
            if (max <= 0)
                throw new ArgumentOutOfRangeException();
            _maxSize = max;
            _dataset = new T[_maxSize];
            _length = 0;
        }
        public T this[int index] 
        {
            get 
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                return _dataset[index];
            }
            set 
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                _dataset[index] = value;
            } 
        }

        public void Clear()
        {
            _length = 0;
        }

        public void Insert(int index, T data)
        {
            if (index < 0 || index > _length)
                throw new ArgumentOutOfRangeException();
            if (_length == MaxSize)
                throw new Exception("数组存放已满");
            for (int i = _length; i > index; i--) 
            {
                _dataset[i] = _dataset[i - 1]; 
            }
            _dataset[index] = data;
            _length++;
        }

        public bool IsEmpty()
        {
            return _length == 0;
        }

        public void Remove(int index)
        {
            if (index < 0 || index > _length - 1)
                throw new ArgumentOutOfRangeException();
            for (int i = index; i < _length - 1; i++) 
            {
                _dataset[i] = _dataset[i + 1];
            }
            _length--;
        }

        public int Search(T data)
        {
            if (data == null)
                throw new ArgumentNullException();
            int i;
            for (i = 0; i < _length; i++) 
            {
                if (_dataset[i].CompareTo(data) == 0)
                    break;
            }
            return i == _length ? -1 : i;
        }
    }
}

using System;
using DataStruct2020.demo;

namespace DataStruct2020
{
    class Program
    {
        static void Main(string[] args)
        {
            ILinearList<int> lst = new SeqList<int>(200);
            lst.Insert(0, 100);
            lst.Insert(1, 200);
            lst.Insert(2, 300);
            lst.Remove(1);
            for (int i = 0; i < lst.Length; i++) 
            {
                Console.WriteLine(lst[i]);
            }
        }
    }
}
//
100
300
  • 自定义的泛型也要实现Comparable接口
{
    public class Student :IComparable<Student>
    {
        private string _name;
        private int _age;
        private long _id;
        public Student(string name, int age,long id) 
        {
            _name = name;
            _age = age;
            _id = id;
        }

        public int CompareTo([AllowNull] Student other)
        {
            if (other._id == _id)
                return 0;
            return -1;
        }

        public override string ToString()
        {
            return string.Format("Name :{0},Age:{1}" ,_name,_age);
        }
    }

链式存储

  • 链式存储:利用该存储方是实现的线性表称为链表(单链表、循环链表、双链表)。他不要求逻辑上相邻的数据元素在物理位置上也相邻,即:逻辑结构与物理结构可以相同也可以不同
    在这里插入图片描述
  • 除了存储本身的数据外,还要存储下一个结点的地址(可以不用占据大量的存储空间)
  • 单链表:每个结点只含有一个指针域的链表。即:利用单链域的方式存储线性表的逻辑结构
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
//结点类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStruct2020.demo
{
    public class SNode<T>where T : IComparable<T>
    {
        public T Data { get; set; }
        public SNode<T> Next { get; set; }
        public SNode(T data) 
        {
            Data = data;
            Next = null;
        }
        public SNode(T data, SNode<T> next) 
        {
            Data = data;
            Next = next;
        }

        public int CompareTo(T other)
        {
            throw new NotImplementedException();
        }
    }
}

在这里插入图片描述

//单链表的链式存储
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStruct2020.demo
{
    public class SLinkList<T> : ILinearList<T> where T : IComparable<T>
    {
        private SNode<T> _pHead;
        private int _length;
        
        public SNode<T> PHead
        {
            get { return _pHead; }
        }
        
        public T this[int index]
        {
            get
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                return Locate(index).Data;
            }
            set
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                Locate(index).Data = value;
            }
        }

        public int Length
        {
            get
            {
                return _length;
            }
        }
        public SLinkList()
        {
            _pHead = null;
            _length = 0;
        }
        public void InsertAtFirst(T data)
        {
            _pHead = new SNode<T>(data, _pHead);
            _length++;
            //两种方式一样的代码:链表为空,链表非空
            //if (_length == 0)
            //{
            //    _pHead = new SNode<T>(data, null);
            //}
            //else 
            //{
            //    _pHead = new SNode<T>(data, _pHead);
            //}
        }
        public SNode<T> Locate(int index)
        {
            if (index < 0 || index > Length - 1)
                throw new ArgumentOutOfRangeException();
            int i = 0;
            SNode<T> temp = _pHead;
            for (; i < index; i++)
            {
                temp = temp.Next;
            }
            return temp;
        }
        public void InsertAtRear(T data)
        {
            if (_length == 0)
            {
                _pHead = new SNode<T>(data);
            }
            else
            {
                Locate(_length - 1).Next = new SNode<T>(data);
            }
            _length++;
        }
        public void Insert(int index, T data)
        {
            if (index < 0 || index > _length)
                throw new ArgumentOutOfRangeException();
            if (index == 0)
                InsertAtFirst(data);
            else if (index == _length)
                InsertAtRear(data);
            else
            {
                SNode<T> temp = Locate(index - 1);
                temp.Next = new SNode<T>(data, temp.Next);
                //Locate(index - 1).Next = new SNode<T>(data, Locate(index));
                _length++;
            }
        }

        public void Clear()
        {
            _pHead = null;
            _length = 0;
        }
        public bool IsEmpty()
        {
            return _length == 0;
        }

        public void Remove(int index)
        {
            if (index < 0 || index > _length - 1)
                throw new ArgumentOutOfRangeException();
            else if (index == 0)
            {
                _pHead = _pHead.Next;
                _length--;
            }
            else
            {
                SNode<T> temp = Locate(index - 1);
                temp.Next = temp.Next.Next;
                _length--;
            }
        }

        public int Search(T data)
        {
            SNode<T> temp = _pHead;
            int i = 0;
            for (; i < _length; i++)
            {
                if (temp.Data.CompareTo(data) == 0)
                    break;
                temp = temp.Next;
            }
            return i == _length ? -1 : i;
        }
    }
}

  • 循环链表:是一种首尾相连的单链表。即:在单链表中,将尾结点的指针域null改为指向pHead,就得到单链形式的循环链表
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
//循环链表
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStruct2020.demo
{
    public class CLinkList<T> : ILinearList<T> where T : IComparable<T>
    {
        //private SNode<T> _pHead;
        private SNode<T> _pRear;
        private int _length;
        public CLinkList() 
        {
            _length = 0;
            _pRear = null;
        }
        public void InsertAtRear(T data) 
        {
            if (_length == 0)
            {
                _pRear = new SNode<T>(data);
                _pRear.Next = _pRear;
            }
            else
            {
                SNode<T> temp = new SNode<T>(data,_pRear.Next);
                _pRear.Next = temp;
                _pRear = temp;
            }
            _length++;
        }
        public void InsertAtHead(T data) 
        {
            if (_length == 0)
            {
                _pRear = new SNode<T>(data);
                _pRear.Next = _pRear;
            }
            else 
            {
                SNode<T> temp = new SNode<T>(data,_pRear.Next);
                _pRear.Next = temp;
            }
            _length++;
        }
        public SNode<T> Locate(int index) 
        {
            if (index < 0 || index > _length - 1)
                throw new ArgumentOutOfRangeException();
            SNode<T> temp = _pRear.Next;
            for (int i = 0; i < index; i++) 
            {
                temp = temp.Next;
            }
            return temp;
        }
        public void Insert(int index,T data) 
        {
            if (index < 0 || index > _length)
                throw new ArgumentOutOfRangeException();
            if (index == 0)
                InsertAtHead(data);
            else if (index == Length)
                InsertAtRear(data);
            else 
            {
                SNode<T> temp = Locate(index - 1);
                temp.Next = new SNode<T>(data,temp.Next);
                _length++;
            }
        }
        public T this[int index] 
        {
            get 
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                return Locate(index).Data;
            }
            set 
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                Locate(index).Data = value;
            }
        }

        public int Length 
        {
            get { return _length; }
        }

        public void Clear()
        {
            _length = 0;
            _pRear = null;
        }
        public bool IsEmpty()
        {
            return _length == 0;
        }

        public void Remove(int index)
        {
            if (index < 0 || index > _length - 1)
                throw new ArgumentOutOfRangeException();
            if (index == 0)
                _pRear.Next = _pRear.Next.Next;
            else if (index == _length - 1)
            {
                SNode<T> temp = Locate(index - 1);
                temp.Next = _pRear.Next;
                _pRear = temp;
            }
            else if (_length == 1) 
            {
                _pRear = null;
            }
            else
            {
                SNode<T> temp = Locate(index - 1);
                temp.Next = temp.Next.Next;
            }
            _length--;
        }

        public int Search(T data)
        {
            SNode<T> temp = _pRear;//不能使temp是头结点因为_pRear可能为空
            int i;
            for (i = 0; i < _length; i++) 
            {
                if (temp.Next.Data.CompareTo(data) == 0)
                    break;
                temp = temp.Next;
            }
            return i == _length ? -1 : i;
        }
    }
}
//客户端
            ILinearList<Student> lst;
            lst = new CLinkList<Student>();
            lst.Insert(0, new Student("test 01", 10, 10086));
            lst.Insert(1, new Student("test 02", 10, 95588));
            lst.Insert(2, new Student("test 03", 10, 12345));
            lst.Remove(2);
            for (int i = 0; i < lst.Length; i++)
            {
                Console.WriteLine(lst[i]);
            }
            int j = lst.Search(new Student("test 01", 10, 10086));
            Console.WriteLine(j);
//
Name :test 01,Age:10
Name :test 02,Age:10
0
  • 双链表:每个结点含有两个指针域的链表。即:利用双链域的方式存储线性表的逻辑结构
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
//定义结点
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStruct2020.demo
{
    public class DNode<T>where T : IComparable<T>
    {
        private T _data;
        private DNode<T> _prior;
        private DNode<T> _next;
        public T Data 
        {
            get { return _data; }
            set { _data = value; }
        }
        public DNode<T> Prior 
        {
            get { return _prior; }
            set { _prior = value; }
        }
        public DNode<T> Next 
        {
            get { return _next; }
            set { _next = value; }
        }
        /*
        public DNode(T data) 
        {
            _data = data;
            _prior = null;
            _next = null;
        }
        */
        public DNode(T data, DNode<T> prior = null, DNode<T> next = null) 
        {
            _prior = prior;
            _data = data;
            _next = next;
        }
    }
}

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStruct2020.demo
{
    public class DLinkList<T> : ILinearList<T> where T : IComparable<T>
    {
        private DNode<T> _pHead;
        private DNode<T> _pRear;
        private int _length;
        public int Length 
        {
            get { return _length;}
        }

        public DLinkList()
        {
            _pHead = null;
            _pRear = null;
            _length = 0;
        }
        public void InsertAtFirst(T data) 
        {
            if (_length == 0)
            {
                DNode<T> temp = new DNode<T>(data);
                _pHead = temp;
                _pRear = temp;
            }
            else 
            {
                DNode<T> temp = new DNode<T>(data, null, _pHead);
                _pHead.Prior = temp;
                _pHead = temp;
            }
            _length++;
        }
        public void InsertAtRear(T data) 
        {
            if (_length == 0) 
            {
                DNode<T> temp = new DNode<T>(data);
                _pHead = temp;
                _pRear = temp;
            }
            else 
            {
                DNode<T> temp = new DNode<T>(data, _pRear, null);
                _pRear.Next = temp;
                _pRear = temp;
            }
            _length++;
        }
        private DNode<T> Locate(int index) 
        {
            if (index < 0 || index > _length - 1)
                throw new ArgumentOutOfRangeException();
            DNode<T> temp = _pHead;
            for(int i = 0; i < index; i++) 
            {
                temp = temp.Next;
            }
            return temp;
        }
        public void Insert(int index, T data)
        {
            if (index < 0 || index > _length)
                throw new ArgumentOutOfRangeException();
            if (index == 0)
                InsertAtFirst(data);
            else if (index == _length)
                InsertAtRear(data);
            else 
            {
                DNode<T> temp1 = Locate(index);
                DNode<T> temp2 = new DNode<T>(data,temp1.Prior,temp1);
                temp2.Prior.Next = temp2;
                temp2.Next.Prior = temp2;
                _length++;
            }
        }
        public T this[int index] 
        {
            get 
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                return Locate(index).Data;
            }
            set 
            {
                if (index < 0 || index > _length - 1)
                    throw new ArgumentOutOfRangeException();
                Locate(index).Data = value;
            }
        }
        public void Clear()
        {
            _length = 0;
            _pHead = null;
            _pRear = null;
        }
        public bool IsEmpty()
        {
            return _length == 0;
        }
        public void Remove(int index)
        {
            if (index < 0 || index > _length - 1)
                throw new ArgumentOutOfRangeException();
            if (_length == 1) 
            {
                _pHead = null;
                _pRear = null;
            }
            else if (index == 0)
            {
                _pHead = _pHead.Next;
                _pHead.Prior = null;
            }
            else if (index == _length - 1)
            {
                _pRear = _pRear.Prior;
                _pRear.Next = null;
            }
            else 
            {
                DNode<T> temp = Locate(index);
                temp.Prior.Next = temp.Next;
                temp.Next.Prior = temp.Prior;
            }
            _length--;
        }
        public int Search(T data)
        {
            DNode<T> temp = _pHead;
            int i;
            for(i = 0;i < _length; i++) 
            {
                if (temp.Data.CompareTo(data) == 0)
                    break;
                temp = temp.Next;
            }
            return i == _length ? -1 : i;
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值