线性表
{
线性表定义:
若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前趋和一个直接后继。
线性表的表示:
文字表示
(a1 , a2 , ……, an)
图形表示
○-○-○-○-○-○
线性表特点:
有且仅有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前趋和一个直接后继。
顺序存储:
顺序存储线性表(随机存取)
链式存储:
链式存储线性表(顺序存取)
}
顺序存储线性表
{
顺序存储线性表的表示
顺序存储线性表的实现
{
顺序表的类型定义(长度和基地址(数组思想)):
#define MAXSIZE 100 //最大长度
Typedef struct
{
ElemType *elem; //指向数据元素的基地址
Int length; //线性表的当前长度
}SqList; //线性表
顺序表的重要操作的实现:
(1)初始化线性表L
方式一:
Status InitList_Sq(SqList *L) //构造一个空的线性表
{
L->elem=new ElemType[MAXSIZE]; //为线性表分配存储空间
If(!L->elem) return false; //线性表的基地址为空,分配空间失败
L->length=0; //线性表的长度设置为0
return ture ; //初始化成功
}
方式二:
Status InitList_Sq(SqList &L) //构造一个空的线性表
{
L.elem=new ElemType[MAXSIZE]; //为线性表分配存储空间
If(!L.elem) return false; //线性表的基地址为空,分配空间失败
L.length=0; //线性表的长度设置为0
return ture ; //初始化成功
}
(2)销毁线性表L
void DestroyList(SqList &L) //销毁线性表
{
If(L.elem)delete []L.elem; //释放存储空间
}
(3)求线性表L的长度
int GetLength(SqList L) //求线性表的长度
{
return L.length;
}
(4)判断线性表L是否为空
Status IsEmpty_Sq(SqList L) //判断线性表是否为空
{
If(L.length) return false; //线性表非空
return ture; //线性表为空
}
(5)线性表的取值操作
int GetElem(SqList L,int i,ElemType &e)
{
if (i<1||i>L.length) return ERROR;
//判断i值是否合理,若不合理,返回ERROR
e=L.elem[i-1]; //第i-1的单元存储着第i个数据
return OK;
}
(6)线性表的查找操作(遍历)
int LocateELem(SqList L,ElemType e)//在线性表L中查找值为e的数据元素
{
for (i=0;i< L.length;i++)
if (L.elem[i]==e) return i+1;
return 0;
}
(7)线性表的插入操作
Status ListInsert_Sq(SqList &L,int i ,ElemType e)
//在线性表L中第i个数据元素之前插入数据元素e
{
if(i<1 || i>L.length+1) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for(j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1]=e; //将新元素e放入第i个位置
++L.length; //表长增1
return OK;
}
(8)将线性表L中第i个数据元素删除
Status ListDelete_Sq(SqList &L,int i)
{
if((i<1)||(i>L.length)) return ERROR; //i值不合法
for (j=i;j<=L.length-1;j++)
L.elem[j-1]=L.elem[j]; //被删除元素之后的元素前移
--L.length; //表长减1
return OK;
}
算法评价:
(1)查找、插入、删除算法的平均时间复杂度为 O(n)
(2)顺序表的空间复杂度S(n)=O(1)
(没有占用辅助空间)
顺序表的优缺点:
1.优点:
(1)存储密度大(结点本身所占存储量/结点结构所占存储量)
(2)可以随机存取表中任一元素
2.缺点:
(1)在插入、删除某一元素时,需要移动大量元素
(2)浪费存储空间
(3)属于静态存储形式,数据元素的个数不能自由扩充
}
链式存储线性表
{
链式存储线性表的表示
链式存储线性表的实现
{
链式表的类型定义:
typedef struct LNode
{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList; // *LinkList为Lnode类型的指针
链式表的重要操作(单链表为例):
(1)链式表的初始化(构造一个空表 )
Status InitList_L(LinkList &L)
{
L=new LNode; //生成新结点作头结点,用头指针L指向头结点 L->next=NULL; //头结点的指针域置空
return OK;
}
(2)清空链式表
Status ClearList(LinkList & L) // 将L重置为空表
{
LinkList p,q;
p=L->next; //p指向第一个结点
while(p) //没到表尾
{ q=p->next; delete p; p=q; }
L->next=NULL; //头结点指针域为空
return OK;
}
(3)销毁链式表
Status DestroyList_L(LinkList &L)
{
LinkList p;
while(L)
{
p=L;
L=L->next;
delete p;
}
return OK;
}
(4)求表长
int ListLength_L(LinkList L)
{
//返回L中数据元素个数
LinkList p;
p=L->next; //p指向第一个结点
i=0;
while(p)
{//遍历单链表,统计结点数
i++;
p=p->next;
}
return i;
}
算法的优缺点与顺序存储结构的相反
}
}