线性表的定义
线性表(亦作顺序表)是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。
线性表的抽象数据类型
ADT 线性表(List)
Data
线性表的数据对象集合为{a1,a2,……,an},每个元素的类型均为DataType。其中除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation
- InitList(SqList *L); 构造一个空的线性表L
- DestroyList(SqList *L); 销毁线性表Status ClearList(SqList *L);清空线性表
- ListEmpty(SqList L); 判断线性表是否为空
- LocateElem(SqList L, ElemType e, Status(*compare)(ElemType,ElemType)); 返回第一个与e满足compare关系的数据元素的位序
- GetElem(SqList L, int i, ElemType *e);返回线性表总第i个数据元素的值
- ListInsert(SqList *L, int i, ElemType e);在线性表第i个位置之前插入新的数据元素e
- PriorElem(SqList L, ElemType cur_e, ElemType *pre_e); //返回指定元素的前驱
- NextElem(SqList L, ElemType cur_e, ElemType *next_e); //返回指定元素的后继
- ListDelete(SqList *L, int i, ElemType *e);删除线性表中指定的元素
- ListTraverse(SqList L, void(vist)(ElemType ));遍历整个链表
线性表的顺序存储结构实现
- sqlist.h
/*
防止重复引用头文件
*/
#pragma once
#ifndef SQLIST_H
#define SQLIST_H
#define INIT_LIST_SIZE 10 //线性表存储空间的初始分配量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef int Status; //返回的状态
typedef int ElemType; //数据的类型
typedef struct SqList
{
ElemType *data; //线性表的基地址
int length; //线性表的当前长度
int listsize; //当前分配的存储空间
};
Status InitList(SqList *L); //构造一个空的线性表L
Status DestroyList(SqList *L); //销毁线性表
Status ClearList(SqList *L); //清空线性表
Status ListEmpty(SqList L); //判断线性表是否为空
Status LocateElem(SqList L, ElemType e, Status(*compare)(ElemType,ElemType)); //返回第一个与e满足compare关系的数据元素的位序
Status GetElem(SqList L, int i, ElemType *e); //返回线性表总第i个数据元素的值
Status ListInsert(SqList *L, int i, ElemType e); //在线性表第i个位置之前插入新的数据元素e
Status PriorElem(SqList L, ElemType cur_e, ElemType *pre_e); //返回指定元素的前驱
Status NextElem(SqList L, ElemType cur_e, ElemType *next_e); //返回指定元素的后继
Status ListDelete(SqList *L, int i, ElemType *e); //删除线性表中指定的元素
Status ListTraverse(SqList L, void(*vist)(ElemType *));
void vist(ElemType *elem);
#endif
- sqlist.cpp
#include "sqlist.h"
#include <iostream>
using namespace std;
Status InitList(SqList *L)
{
L->data = (ElemType*)malloc(INIT_LIST_SIZE*sizeof(ElemType));
if (!L->data)
return ERROR;
L->length = 0;
L->listsize = INIT_LIST_SIZE;
return OK;
}
Status DestroyList(SqList *L)
{
if (L->data)
free(L->data); //销毁线性表
return OK;
}
Status ClearList(SqList *L)
{
L->length = 0; //将线性表置为空表
return OK;
}
Status ListEmpty(SqList L)
{
if (L.length == 0) //长度为0时,线性表为空表
return TRUE;
return FALSE;
}
Status ListLength(SqList L)
{
return L.length; //线性表长度
}
Status LocateElem(SqList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
int i = 1;
ElemType *p = L.data;
while (i < L.length && !(*compare)(e, *p++))
++i;
if (i <= L.length)//返回满足关系compare的元素
return i;
else
return FALSE;
}
Status GetElem(SqList L, int i, ElemType *e)
{
if (L.length == 0 || i < 0 || i > L.length) //要查找的i值不合法
return ERROR;
*e = L.data[i - 1]; //得到要查找的元素
return OK;
}
Status ListInsert(SqList *L, int i, ElemType e)
{
ElemType *newbase, *q , *p ;
if (i<1 || i>L->length + 1) //当前插入的位置不合法
return ERROR;
if (L->length > L->listsize) //当前分配存储空间已满,增加分配
{
newbase = (ElemType*)realloc(L->data, LISTINCREMENT*sizeof(ElemType));
if (!newbase)
return ERROR; //存储空间分配失败
L->data = newbase; //新基址
L->listsize += LISTINCREMENT;
}
q = L->data + i - 1; //插入的位置
p = L->data + L->length - 1;
for (p; p >= q; --p)
*(p+1) = *p; //插入位置之后的元素后移
*q = e; //插入元素
++L->length; //线性表的长度增加1
//cout << "ListInsert" << endl;
return OK;
}
Status PriorElem(SqList L, ElemType cur_e, ElemType *pre_e)
{
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
/* 否则操作失败,pre_e无定义 */
ElemType *p = L.data + 1; //指向线性表第二个元素的指针
int i = 2; //循环开始
while (i <= L.length && *p != cur_e)
{
i++;
p++;
}
if (i > L.length)
return ERROR; //循环控制次数超出范围跳出循环
else
{
*pre_e = *--p; //找到与之匹配的元素跳出循环
return OK;
}
}
Status NextElem(SqList L, ElemType cur_e, ElemType *next_e)
{
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
/* 否则操作失败,next_e无定义 */
int i = 1;
ElemType *p = L.data;
while (i < L.length && *p != cur_e)
{
i++;
p++;
}
if (i >= L.length)
return ERROR;
else
{
*next_e = *++p;
return OK;
}
}
Status ListDelete(SqList *L, int i, ElemType *e)
{
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
ElemType *q, *p;
if (i < 0 || i > L->length) //i值不合法
return ERROR;
q= L->data + i -1; //q为被删除元素的指针
*e = *q;
p = L->data + L->length -1; //p为表位的指针
for (++q ; q <= p; q++)
{
*(q-1) = *q; //被删除后的元素前移
}
L->length --; //表的长度减1
return OK;
}
Status ListTraverse(SqList L, void(*vist)(ElemType *))
{
int i = 0;
ElemType *p = L.data;
for (i; i < L.length; i++)
{
vist(p++);
}
return OK;
}
void vist(ElemType *elem)
{
cout << *elem << " ";
}