一.线性表的逻辑结构
1.线性表的长度:线性表中数据元素的个数。
空表:长度等于零的线性表,记为:L=( )。
非空表记为:L=(a1,线性表:简称表,是n(n≥0)个具有相同类型的数据元素的有限序列。
a2 , …, ai-1, ai , …, an)
2.线性表的特性:有限性.相同性.顺序性
3. ADT List
Data
线性表中的数据元素具有相同类型,
相邻元素具有前驱和后继关系
Operation
InitList
前置条件:表不存在
输入:无
功能:表的初始化
输出: 无
后置条件:建一个空表
DestroyList
前置条件:表已存在
输入:无
功能:销毁表
输出:无
后置条件:释放表所占用的存储空间
Length
前置条件:表已存在
输入:无
功能:求表的长度
输出:表中数据元素的个数
后置条件:表不变
Get
前置条件:表已存在
输入:元素的序号i
功能:在表中取序号为i的数据元素
输出:若i合法,返回序号为i的元素值,否则抛出异常
后置条件:表不变
Locate
前置条件:表已存在
输入:数据元素x
功能:在线性表中查找值等于x的元素
输出:若查找成功,返回x在表中的序号,否则返回0
后置条件:表不变
Insert
前置条件:表已存在
输入:插入i;待插x
功能:在表的第i个位置处插入一个新元素x
输出:若插入不成功,抛出异常
后置条件:若插入成功,表中增加一个新元素
Delete
前置条件:表已存在
输入:删除位置i
功能:删除表中的第i个元素
输出:若删除成功,返回被删元素,否则抛出异常
后置条件:若删除成功,表中减少一个元素
Empty
前置条件:表已存在
输入:无
功能:判断表是否为空
输出:若是空表,返回1,否则返回0
后置条件:表不变
ADT
二.顺序表的顺序存储结构及实现
1.线性表的顺序存储结构称为顺序表
2.顺序表类的声明
const int MaxSize=100;
template <class DataType> //模板类
class SeqList
{
public:
SeqList( ) ; //构造函数
SeqList(DataType a[ ], int n);
~SeqList( ) ; //析构函数
int Length( );
DataType Get(int i);
int Locate(DataType x );
void Insert(int i, DataType x);
DataType Delete(int i);
private:
DataType data[MaxSize];
int length;
};
3.顺序表有参构造函数
template <class DataType>
SeqList<DataType> ::SeqList(DataType a[ ], int n)
{
if (n > MaxSize) throw "参数非法";
for (i = 0; i < n; i+ +)
data[i] = a[i];
length = n;
}
4.顺序表插入算法
template <class DataType>
void SeqList<DataType>::Insert(int i, DataType x)
{
if (length >= MaxSize) throw "上溢";
if (i < 1 || i > length + 1) throw "位置";
for (j = length; j >= i; j--)
data[j] = data[j-1];
data[i-1] = x;
length++;
}
三.线性表的链接存储结构及实现
1.单链表是用一组任意的存储单元存放线性表的元素。
2.存储特点:逻辑次序和物理次序不一定相同。
元素之间的逻辑关系用指针表示。
3. 单链表的结点结构
template <class DataType>
struct Node
{
DataType data;
Node<DataType> *next;
};
4.单链表类的声明
template <class DataType>
class LinkList
{
public:
LinkList( );
LinkList(DataType a[ ], int n);
~LinkList( );
int Length( );
DataType Get(int i);
int Locate(DataType x);
void Insert(int i, DataType x);
DataType Delete(int i);
void PrintList( );
private:
Node<DataType> *first;
};
5.单链表按值查找算法
template <class DataType>
int LinkList<DataType> :: Locate(DataType x)
{
p = first->next; count = 1;
while (p != NULL)
{
if (p->data == x) return count; //查找成功,返回序号
p = p->next;
count++;
}
return 0; //退出循环表明查找失败
}
6.单链表插入算法
template <class DataType>
void LinkList<DataType> :: Insert(int i, DataType x)
{
p = first ; count = 0; //工作指针p应指向头结点
while (p != NULL && count < i - 1) //查找第i – 1个结点
{
p = p->next;
count++;
}
if (p == NULL) throw "位置"; //没有找到第i – 1个结点
else {
s = new Node; s->data = x; //申请一个结点s
s->next = p->next; p->next = s; //结点s插入结点p之后
}
}
7.单链表删除算法
template <class DataType>
DataType LinkList<DataType> :: Delete(int i)
{
p = first ; count = 0;
while (p != NULL && count < i - 1)
{
p = p->next;
count++;
}
if (p == NULL || p->next == NULL) throw "位置";
else {
q = p->next; x = q->data;
p->next = q->next;
delete q; return x;
}
}
8. 算法设计的一般步骤:
第一步:确定入口(已知条件)、出口(结果);
第二步:根据一个小实例画出示意图;
第三步:① 正向思维:选定一个思考问题的起点,逐步提出问题、解决问题;② 逆向思维:从结论出发分析为达到这个结论应该先有什么;③ 正逆结合;
第四步:写出顶层较抽象算法,分析边界情况;
第五步:验证第四步的算法;
第六步:写出具体算法;
第七步:进一步验证,手工运行
四.循环链表
1. 将单链表的首尾相接,将终端结点的指针域由空指针改为指向头结点,构成单循环链表,简称循环链表。
2.循环链表插入算法
template <class DataType>
void LinkList<DataType> ::Insert(int i, DataType x)
{
p = first ; count = 0;
while (p != first && count < i - 1)
{
p = p->next;
count++;
}
if (p == NULL) throw "位置";
else {
s = new Node<DataType>; s->data = x;
s->next = p->next; p->next = s;
}
}
五.双链表
1. 双链表:在单链表的每个结点中再设置一个指向其前驱结点的指针域。
2.双链表定义节点结构
template <class DataType>
struct DulNode
{
DataType data;
DulNode<DataType> *prior, *next;
};
六.静态链表
1. 静态链表:用数组来表示单链表,用数组元素的下标来模拟单链表的指针
2.静态链表的存储结构定义
const int MaxSize = 100; //100只是示例数据
template <class DataType>
struct SNode
{
DataType data; // DataType表示不确定的数据类型
int next; //指针域(也称游标)
} SList[MaxSize];