C# 线性表的实现
线性表的基本操作定义如下:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
线性表的基本操作
public interface IListDS<T>
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
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();
void Print();
} (1):顺序表的定义:指内存中用一块连续的空间依次存储线性表的每个元素。因为在C#中数组在内存中占用的存储空间就是一组连续的存储区域,具有随机存储的特点,逻辑上相邻的数据元素物理上也相邻。代码实现如下:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
顺序表的实现
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
{
set { last = value; }
get { return last; }
}
public int MaxSize
{
set { maxSize = value; }
get { return maxSize; }
}
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;
}
public void Insert(T item, int i)
{
if (IsFull())
{
Console.WriteLine("List Is Full!");
return;
}
if (i < 1 || i > last + 2)
{
Console.WriteLine("Position error!");
return;
}
if (i == last + 2)
{
data[++last] = item;
}
else
{
for (int j = last; j >=i-1; j--)
{
data[j + 1] = data[j];
}
data[i - 1] = item;
++last;
}
}
public T Delete(int i)
{
T temp = default(T);
if (IsEmpty())
{
Console.WriteLine("List is empty!");
return temp;
}
if (i < 1 || i > last + 1)
{
Console.WriteLine("Position is error!");
return temp;
}
if (i == last + 1)
{
temp = data[last];
}
else
{
temp = data[i - 1];
for (int j = i-1; j < last; j++)
{
data[j] = data[j + 1];
}
}
--last;
return temp;
}
public T GetElem(int i)
{
if (IsEmpty() || (i < 1) || (i > last + 1))
{
Console.WriteLine("List is empty or position is error!");
return default(T);
}
else
{
return data[i - 1];
}
}
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 temp = default(T);
int len = GetLength()-1;
for (int i = 0; i <= len/2; i++)
{
temp = data[i];
data[i] = data[len - i];
data[len - i] = temp;
}
}
public void Print()
{
for (int i = 0; i <= last; i++)
{
Console.Write(" " + data[i]);
}
Console.WriteLine();
}
} 注释:maxSize表示顺序表的容量,data存储顺序表的元素,last指示最后一个元素的位置。
a.插入操作:判断顺序表是否已满和插入的位置是否正确,表满或者插入的顺序不正确不能插入;如果表满或者插入的位置的正确,咋将a1~~ai依次向后移动,为新的数据元素空出位置,用循环来实现;将新的元素插入到空出的第i位置上;修改last,使它指向顺序表的最后一个元素。插入的时间复杂度O(N)。
b.删除元素:判断顺序表是否为空和删除的位置是否合理,表空或删除的位置不合理,不能删除;如果表不空和删除的位置正确,则将a1~ai依次向前移动,用循环来实现;修改last指针,使它指向顺序表的最后一个元素。时间复杂度为O(N)。
(2):单链表是指用一组任意的存储单元来存储线性表中的数据元素。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
单链表节点的定义
public class Node<T>
{
private T data;
private Node<T> next;
public T Data
{
set { data = value; }
get { return data; }
}
public Node<T> Next
{
set { next = value; }
get { return 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;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
单链表的实现
public class LinkList<T>:IListDS<T>
{
private Node<T> head;
public Node<T> Head
{
set { head = value; }
get { return head; }
}
public LinkList()
{
head = null;
}
public int GetLength()
{
int len = 0;
Node<T> p = head;
while (p != null)
{
++len;
p = p.Next;
}
return len;
}
public void Clear()
{
head = null;
}
public bool IsEmpty()
{
if (head == null)
return true;
else
return false;
}
public void Append(T item)
{
Node<T> q = new Node<T>(item);
Node<T> p = new Node<T>();
if (head == null)
{
head.Next = q;
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("LinkList 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)
{
++j;
r = p;
p = p.Next;
}
if (j == i)
{
Node<T> q = new Node<T>(item);
q.Next = p;
r.Next = q;
}
else
{
Console.WriteLine("Positon is error!");
}
return;
}
public T Delete(int i)
{
if (IsEmpty() || i < 0)
{
Console.WriteLine("LinkList is empty or position 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 = p.Next;
return p.Data;
}
else
{
Console.WriteLine("Position is error!");
return default(T);
}
}
public T GetElem(int i)
{
if (IsEmpty())
{
Console.WriteLine("Linklist is empty!");
return default(T);
}
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("Position is error!");
return default(T);
}
}
public int Locate(T value)
{
if (IsEmpty())
{
Console.WriteLine("LinkList is empty!");
return -1;
}
Node<T> p = head;
int i = 1;
while (!p.Data.Equals(value) && p.Next != null)
{
++i;
p = p.Next;
}
return i;
}
public void Reverse()
{
Node<T> p = head;
Node<T> q = new Node<T>();
Node<T> R = new Node<T>();
while (p != null)
{
q = p;
p = p.Next;
q.Next = R.Next;
R.Next = q;
}
head = R.Next;
R = null;
}
public void Print()
{
Node<T> p = head;
if (p != null)
{
while (p != null)
{
Console.Write(" " + p.Data);
p = p.Next;
}
Console.WriteLine();
}
else
{
Console.WriteLine("LinkList is empty!");
}
}
} 注释:线性表的顺序存储和链式存储各有优缺点,线性表如何存储取决于使用场合。如果不需要经常在线性表中进行插入和删除,那么线性表适合顺序存储;如果线性表需要经常插入和删除,而不经常查找,则应链式存储。
a.插入操作:前插操作和后插操作,时间复杂度:O(N)。
b. 删除操作,时间复杂度O(N)
(3):单链表的创建
1):在单链表的头部插入节点建立
2):在单链表的尾部插入节点建立
(4):双链表
(5):循环链表
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
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
{
set { last = value; }
get { return last; }
}
public int MaxSize
{
set { maxSize = value; }
get { return maxSize; }
}
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;
}
public void Insert(T item, int i)
{
if (IsFull())
{
Console.WriteLine("List Is Full!");
return;
}
if (i < 1 || i > last + 2)
{
Console.WriteLine("Position error!");
return;
}
if (i == last + 2)
{
data[++last] = item;
}
else
{
for (int j = last; j >=i-1; j--)
{
data[j + 1] = data[j];
}
data[i - 1] = item;
++last;
}
}
public T Delete(int i)
{
T temp = default(T);
if (IsEmpty())
{
Console.WriteLine("List is empty!");
return temp;
}
if (i < 1 || i > last + 1)
{
Console.WriteLine("Position is error!");
return temp;
}
if (i == last + 1)
{
temp = data[last];
}
else
{
temp = data[i - 1];
for (int j = i-1; j < last; j++)
{
data[j] = data[j + 1];
}
}
--last;
return temp;
}
public T GetElem(int i)
{
if (IsEmpty() || (i < 1) || (i > last + 1))
{
Console.WriteLine("List is empty or position is error!");
return default(T);
}
else
{
return data[i - 1];
}
}
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 temp = default(T);
int len = GetLength()-1;
for (int i = 0; i <= len/2; i++)
{
temp = data[i];
data[i] = data[len - i];
data[len - i] = temp;
}
}
public void Print()
{
for (int i = 0; i <= last; i++)
{
Console.Write(" " + data[i]);
}
Console.WriteLine();
}
}
a.插入操作:判断顺序表是否已满和插入的位置是否正确,表满或者插入的顺序不正确不能插入;如果表满或者插入的位置的正确,咋将a1~~ai依次向后移动,为新的数据元素空出位置,用循环来实现;将新的元素插入到空出的第i位置上;修改last,使它指向顺序表的最后一个元素。插入的时间复杂度O(N)。
b.删除元素:判断顺序表是否为空和删除的位置是否合理,表空或删除的位置不合理,不能删除;如果表不空和删除的位置正确,则将a1~ai依次向前移动,用循环来实现;修改last指针,使它指向顺序表的最后一个元素。时间复杂度为O(N)。
(2):单链表是指用一组任意的存储单元来存储线性表中的数据元素。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class Node<T>
{
private T data;
private Node<T> next;
public T Data
{
set { data = value; }
get { return data; }
}
public Node<T> Next
{
set { next = value; }
get { return 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;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class LinkList<T>:IListDS<T>
{
private Node<T> head;
public Node<T> Head
{
set { head = value; }
get { return head; }
}
public LinkList()
{
head = null;
}
public int GetLength()
{
int len = 0;
Node<T> p = head;
while (p != null)
{
++len;
p = p.Next;
}
return len;
}
public void Clear()
{
head = null;
}
public bool IsEmpty()
{
if (head == null)
return true;
else
return false;
}
public void Append(T item)
{
Node<T> q = new Node<T>(item);
Node<T> p = new Node<T>();
if (head == null)
{
head.Next = q;
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("LinkList 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)
{
++j;
r = p;
p = p.Next;
}
if (j == i)
{
Node<T> q = new Node<T>(item);
q.Next = p;
r.Next = q;
}
else
{
Console.WriteLine("Positon is error!");
}
return;
}
public T Delete(int i)
{
if (IsEmpty() || i < 0)
{
Console.WriteLine("LinkList is empty or position 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 = p.Next;
return p.Data;
}
else
{
Console.WriteLine("Position is error!");
return default(T);
}
}
public T GetElem(int i)
{
if (IsEmpty())
{
Console.WriteLine("Linklist is empty!");
return default(T);
}
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("Position is error!");
return default(T);
}
}
public int Locate(T value)
{
if (IsEmpty())
{
Console.WriteLine("LinkList is empty!");
return -1;
}
Node<T> p = head;
int i = 1;
while (!p.Data.Equals(value) && p.Next != null)
{
++i;
p = p.Next;
}
return i;
}
public void Reverse()
{
Node<T> p = head;
Node<T> q = new Node<T>();
Node<T> R = new Node<T>();
while (p != null)
{
q = p;
p = p.Next;
q.Next = R.Next;
R.Next = q;
}
head = R.Next;
R = null;
}
public void Print()
{
Node<T> p = head;
if (p != null)
{
while (p != null)
{
Console.Write(" " + p.Data);
p = p.Next;
}
Console.WriteLine();
}
else
{
Console.WriteLine("LinkList is empty!");
}
}
}
a.插入操作:前插操作和后插操作,时间复杂度:O(N)。
b. 删除操作,时间复杂度O(N)
(3):单链表的创建
1):在单链表的头部插入节点建立
2):在单链表的尾部插入节点建立
(4):双链表
(5):循环链表