线性表(List):零或多个数据元素的有限序列。
ADT 线性表 (List)
Data
Operation
void initList(*L); //创建并初始化一个空线性表,如果成功返回true,修改表传指针
bool listEmpty(L); //判断一个线性表是否为空,不修改表传值
void clearList(*L); //清空一个线性表,成功返回true
bool getElem(L,i,*e); //从某个位置取出元素并赋值给e(i的范围是[1,L.length]),修改e的值所以传递一个指针,成功返回true
int locateElem(L,e); //查找线性表中是否有e,如果有返回它的位置(从1开始),否则返回0表示失败
bool listInsert(*L,i,e); //插入一个元素e在第i个元素之前(i的取值范围是[1,L.length+1]) ,成功返回true
bool listDelete(*L,i,*e); //删除在第i个位置上的元素(i的取值范围是[1,L.length]),删除的元素赋给e,成功返回true
int listLength(L); //返回线性表的元素个数
endADT
用一段地址连续的存储单元依次存储线性表的数据元素。
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE]; //数组存储数据元素
int length; //线性表当前长度
}SqList;
/*初始条件:顺序线性表L已存在,1≤i≤ListLength(L)*/
/*操作结果: 在L中第i个位置之前插入新的数据元素e,L的长度加1*/
Status ListInsert(SqList *L,int i ,ElemType e)
{
int k;
if(L->length==MAXSIZE) /*顺序表已满*/
return ERROR;
if(i<1 || i>L->length+1) /*如果i不在范围时*/
return ERROR;
if(i<=L->length) /*若插入数据不在表尾*/
{
for (k=L->length-1;k>=i-1;k--) /*将要插入位置后数据元素向后移动一位*/
L->data[k+1]=L->data[k];
}
L->data[i-1]=e; /*将新元素插入*/
L->length++; /*表长加1*/
return OK;
}
/*初始条件: 顺序线性表L已存在,1≤i≤ListLength(L)*/
/*操作结果: 删除L的第i个数据元素,并用e返回其值,L的长度减1*/
Status ListDelete(SqList *L,int i,ElemType *e)
{
int k;
if(L->length==0) /*线性表为空*/
return ERROR;
if(i<1 || i >L->length) /*删除位置不正确*/
return ERROR;
*e = L->data[i-1];
if(ilength) /*如果删除不是最后位置*/
{
for(k=i;klength;k++) /*将删除位置后继元素前移*/
L->data[k-1]=L->data[k];
}
L->length--; /*表长减1*/
return OK;
}
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
1.声明一结点p指向链表第一个结点,初始化j从1开始;
2.当j<1时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
3.若到链表末尾p为空,则说明第i个元素不存在;
4.否则查找成功,在系统中生成一个空结点s;
5.将数据元素e赋值给s->data;
6.单链表的插入标准语句s->next=p->next; p->next=s;
7.返回成功。
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个结点位置之前插入新的数
据元素e,L的长度加1 */
Status ListInsert(LinkList *L, int i, ElemType e)
{
int j;
LinkList p, s;
p = *L;
j = 1;
/* 寻找第i-1个结点 */
while (p && j < i)
{
p = p->next;
++j;
}
/* 第i个结点不存在 */
if (!p || j > i)
return ERROR;
/* 生成新结点(C标准函数) */
s = (LinkList)malloc(sizeof(Node));
s->data = e;
/* 将p的后继结点赋值给s的后继 */
s->next = p->next;
/* 将s赋值给p的后继 */
p->next = s;
return OK;
}
1.声明一指针p指向链表头结点,初始化j从1开始;
2.当j
3.若到链表末尾p为空,则说明第i个结点不存在;
4.否则查找成功,将欲删除的结点p->next赋值给q;
5.单链表的删除标准语句p->next=q->next;
6.将q结点中的数据赋值给e,作为返回;
7.释放q结点;
8.返回成功。
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个结点,并用e返回其
值,L的长度减1 */
Status ListDelete(LinkList *L, int i, ElemType *e)
{
int j;
LinkList p, q;
p = *L;
j = 1;
/* 遍历寻找第i-1个结点 */
while (p->next && j < i)
{
p = p->next;
++j;
}
/* 第i个结点不存在 */
if (!(p->next) || j > i)
return ERROR;
q = p->next;
/* 将q的后继赋值给p的后继 */
p->next = q->next;
/* 将q结点中的数据给e */
*e = q->data;
/* 让系统回收此结点,释放内存 */
free(q);
return OK;
}
循环链表:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表成为单循环链表。
双向链表:在单链表中的每个结点中,再设置一个指向其前驱结点的指针域。