一:介绍
线性表是最基本,最简单也是应用最广的数据结构。线性表是线性数据的抽象,其特点是结构中的数据元素之间存在着一对一的线性关系,
是一种数据元素序列的数据结构。
线性表是由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前面,插入过程如下图:

对应的操作如下:
- p.Next.Prev=s;
- s.Prev=p;
- s.Next=p.Next;
- p.Next=s;
5.3.删除
我们以删除p结点的后面的结点为例,删除过程如下:

操作如下:
- p.Next=p.Next.Next;
- P.Next.Prev=p.Prev;
双向链表的其他操作与单链表相似。