数据结构 线性表

什么是线性表:线性表(List)是由 n(n≥ 0)个相同类型的数据元素构成的有限序列

       线性表中的数据元素之间存在着前后次序的位置关系,将ai-1称为ai的直接前
       驱,将ai 称为ai+1 的直接后继。除a1 外,其余元素只有一个直接前驱,因为a1 是第
        一个元素,所以它没有前驱。除an外,其余元素只有一个直接后继,因为an 是最
        后一个元素,所以它没有后继。
        线性表的形式化定义为:线性表(List)简记为L,是一个二元组,
        L = (D, R)
        其中:D 是数据元素的有限集合。
        R 是数据元素之间关系的有限集合。

View Code
 1 ///定义接口  
 2 public interface IListDS<T>
 3     {
 4         int GetLength();             //求长度 
 5         void Clear();                //清空操作 
 6         bool IsEmpty();              //判断线性表是否为空 
 7         void Append(T item);         //附加操作 
 8         void Insert(T item, int i);  //插入操作 
 9         T Delete(int i);             //删除操作 
10         T GetElem(int i);            //取表元 
11         int Locate(T value);         //按值查找
12     }
View Code
  1 实现接口
  2 public  class SeqList<T>:IListDS<T>
  3     {
  4         private int maxSize;//顺序表的容量
  5 
  6         public int MaxSize
  7         {
  8             get { return maxSize; }
  9             set { maxSize = value; }
 10         }
 11         private int last;//最后一个元素的位置 0开始
 12 
 13         public int Last
 14         {
 15             get { return last; }
 16         }
 17       private T[] date;//数组,用于存储顺序表中的数据元素
 18       public SeqList(int size)
 19       {
 20           maxSize = size;
 21           date = new T[size];
 22           last = -1;
 23       }
 24 
 25       #region IListDS<T> 成员
 26 
 27 
 28         public int GetLength()
 29         {
 30             return last + 1;
 31         }
 32 
 33         public void Clear()
 34         {
 35             last = -1;
 36         }
 37 
 38         public bool IsEmpty()
 39         {
 40             if (last == -1) return true;
 41             else return false;
 42         }
 43 
 44         public void Append(T item)
 45         {
 46             date[++last] = item;
 47         }
 48 
 49         public void Insert(T item, int i)
 50         {
 51             if (i < 1 || i > last + 2)
 52             {
 53                 return;
 54             }
 55             else if (i == last + 2)
 56             {
 57                 date[++last] = item;
 58             }
 59             else
 60             {
 61                 for (int j = last; j <= i - 1; j--)
 62                 {
 63                     date[j + 1] = date[j];
 64                 }
 65                 date[i - 1] = item;
 66             }
 67             ++last;
 68         }
 69 
 70         public T Delete(int i)
 71         {
 72             T tmp = default(T); 
 73             if (i < 1 || i > last + 2)
 74             {
 75                 return;
 76             }
 77             if (i == last + 1)
 78             {
 79                 tmp = data[last--];
 80             }
 81             else
 82             {
 83                 tmp = data[i - 1];
 84                 for (int j = i; j <= last; ++j)
 85                 {
 86                     data[j] = data[j + 1];
 87                 }
 88             }
 89             return tmp;
 90         }
 91 
 92         public T GetElem(int i)
 93         {
 94             if (i < 1 || i > last + 1)
 95             {
 96                 return;
 97             }
 98             return date[i - 1];
 99         }
100 
101         public int Locate(T value)
102         {
103             int i=0;
104             for (i = 0; i < last; i++)
105             {
106                 if (value.Equals(date[i]))
107 
108                 {
109                     break;
110                 }
111             }
112             return i;
113         }
114 
115       #endregion
116     }

1、求顺序表的长度
由于数组是 0 基数组,即数组的最小索引为 0,所以,顺序表的长度就是数
组中最后一个元素的索引 last 加 1。
求顺序表长度的算法实现如下:
数据结构(C#语言版)
2.2 顺序表 30
public int GetLength()
{
return last+1;
}
2、清空操作
清除顺序表中的数据元素是使顺序表为空,此时,last 等于-1。
清空顺序表的算法实现如下:
public void Clear()
{
last = -1;
}
3、判断线性表是否为空
如果顺序表的 last 为-1,则顺序表为空,返回 true,否则返回 false。
判断线性表是否为空的算法实现如下:
public bool IsEmpty()
{
if (last == -1)
{
return true;
}
else
{
return false;
}
}
4、判断顺序表是否为满
如果顺序表为满,last 等于 maxsize-1,则返回 true,否则返回 false。
判断顺序表是否为满的算法实现如下:
public bool IsFull()
{
if (last == maxsize - 1)
{
return true;
}
else
{
return false;
}
}
5、附加操作
附加操作是在顺序表未满的情况下,在表的末端添加一个新元素,然后使顺
序表的last加1。
附加操作的算法实现如下:
public void Append(T item)
数据结构(C#语言版)
2.2 顺序表 31
{
if(IsFull())
{
Console.WriteLine("List is full");
return;
}

data[++last] = item;
}
6、插入操作
顺序表的插入是指在顺序表的第i个位置插入一个值为item的新元素,插入后
使原表长为n的表(a1,a2,…,ai-1,ai,ai+1,…,an)成为表长为n+1 的表
(a1,a2,…,ai-1,item,ai,ai+1,…,an)。i的取值范围为 1≤i≤n+1,i为n+1 时,表示
在顺序表的末尾插入数据元素。
顺序表上插入一个数据元素的步骤如下:
(1)判断顺序表是否已满和插入的位置是否正确,表满或插入的位置不正
确不能插入;
(2)如果表未满和插入的位置正确,则将an~ai依次向后移动,为新的数据
元素空出位置。在算法中用循环来实现;
(3)将新的数据元素插入到空出的第 i 个位置上;
(4)修改 last(相当于修改表长),使它仍指向顺序表的最后一个数据元
素。
图 2.2 为顺序表的插入操作示意图。
插入 30


11 23 36 45 80 60 40 6 …

(a) 插入前


11 23 36 45 80 60 40 6 …

(b) 移动

11 23 36 30 45 80 60 40 6 …

(c) 插入后
图 2.2 顺序表的插入操作示意图
插入操作的算法实现如下,程序中需要注意的是位置变量 i 的初始值为 1
而不是 0:
public void Insert(T item, int i)
{
// 判断顺序表是否已满
if (IsFull())
{
数据结构(C#语言版)
2.2 顺序表 32
Console.WriteLine("List is full");
return;
}

// 判断插入的位置是否正确,
// i小于1表示在第1个位置之前插入,
// i大于last+2 表示在最后一个元素后面的第2个位置插入。
if(i<1 || i>last+2)
{
Console.WriteLine( "Position is error! ");
return;
}

// 在顺序表的表尾插入数据元素
if (i == last +2)
{
data[i-1] = item;
}
else //在表的其它位置插入数据元素
{
// 元素移动
for (int j = last; j>= i-1; --j)
{
data[j + 1] = data[j];
}

//将新的数据元素插入到第i 个位置上
data[i-1] = item;
}

// 修改表长
++last;
}
算法的时间复杂度分析:顺序表上的插入操作,时间主要消耗在数据的移动
上,在第i 个位置插入一个元素,从ai到an都要向后移动一个位置,共需要移动n-i+1
个元素,而i 的取值范围为 1≤i≤n+1,当i等于 1 时,需要移动的元素个数最多,
为n个;当i为n+1 时,不需要移动元素。设在第i 个位置做插入的概率为pi,则平
均移动数据元素的次数为n/2。这说明:在顺序表上做插入操作平均需要移动表
中一半的数据元素,所以,插入操作的时间复杂度为O(n)。
7、删除操作
顺序表的删除操作是指将表中第i个数据元素从顺序表中删除,删除后使原表
长为n的表(a1,a2,…,ai-1,ai, a i+1,…,an)变为表长为n-1 的表
(a1,a2,…,ai-1,ai+1,…,an)。i的取值范围为 1≤i≤n,i为n时,表示删除顺序表末
尾的数据元素。
数据结构(C#语言版)
2.2 顺序表 33
顺序表上删除一个数据元素的步骤如下:
(1)判断顺序表是否为空和删除的位置是否正确,表空或删除的位置不正
确不能删除;
(2)如果表未空和删除的位置正确,则将ai+1 ~an 依次向前移动。在算法中
用循环来实现;
(3)修改 last(相当于修改表长),使它仍指向顺序表的最后一个元素。
图 2.3 为顺序表的删除操作示意图。
删除 45


11 23 36 45 80 60 40 6 …

(a) 删除前

11 23 36 80 60 40 6 …

(b) 删除后
图 2.3 顺序表的删除操作示意图
删除操作的算法实现如下:
public T Delete(int i)
{
T tmp = default(T);

// 判断表是否为空
if (IsEmpty())
{
Console.WriteLine("List is empty");
return tmp;
}

// 判断删除的位置是否正确
// i小于1表示删除第1个位置之前的元素,
// i大于last+1 表示删除最后一个元素后面的第1个位置的元素。
if (i < 1 || i > last+1)
{
Console.WriteLine( "Position is error! ");
return tmp;
}

// 删除的是最后一个元素
if (i == last+1)
{
tmp = data[last--];
return tmp;
}
数据结构(C#语言版)
2.2 顺序表 34
else //删除的不是最后一个元素
{
// 元素移动
tmp = data[i-1];
for (int j = i; j <= last; ++j)
{
data[j] = data[j + 1];
}
}

// 修改表长
--last;
return tmp;
}
算法的时间复杂度分析:顺序表上的删除操作与插入操作一样,时间主要消
耗在数据的移动上。在第i 个位置删除一个元素,从ai+1 到an 都要向前移动一个位
置,共需要移动n-i个元素,而i 的取值范围为 1≤i≤n,当i等于 1 时,需要移动
的元素个数最多,为n-1 个;当i为n时,不需要移动元素。设在第i 个位置做删除
的概率为pi ,则平均移动数据元素的次数为(n-1)/2 。这说明在顺序表上做删除操
作平均需要移动表中一半的数据元素,所以,删除操作的时间复杂度为O(n)。
8、取表元
取表元运算是返回顺序表中第 i 个数据元素,i 的取值范围是 1≤i≤last+1。
由于表是随机存取的,所以,如果 i 的取值正确,则取表元运算的时间复杂度为
O(1)。
取表元运算的算法实现如下:
public T GetElem(int i)
{
if (IsEmpty()|| (i<1) || (i>last+1))
{
Console.WriteLine("List is empty or Position is error!");
return default(T);
}

return data[i-1];
}
9、按值查找
顺序表中的按值查找是指在表中查找满足给定值的数据元素。在顺序表中完成
该运算最简单的方法是:从第一个元素起依次与给定值比较,如果找到,则返回
在顺序表中首次出现与给定值相等的数据元素的序号,称为查找成功;否则,在
顺序表中没有与给定值匹配的数据元素,返回一个特殊值表示查找失败。
按值查找运算的算法实现如下:
public int Locate(T value)
{
// 顺序表为空
数据结构(C#语言版)
2.2 顺序表 35
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;
}
算法的时间复杂度分析:顺序表中的按值查找的主要运算是比较,比较的次
数与给定值在表中的位置和表长有关。当给定值与第一个数据元素相等时,比较
次数为 1;而当给定值与最后一个元素相等时,比较次数为 n。所以,平均比较
次数为(n+1)/2,时间复杂度为 O(n)。
由于顺序表是用连续的空间存储数据元素,所以按值查找的方法很多。比如,
如果顺序表是有序的,则可以用折半查找法,这样效率可以提高很多

posted on 2012-07-15 16:44  席梦天空  阅读(197)  评论(0编辑  收藏  举报

导航