线性表的顺序表示
顺序表的存储结构
// 算法描述
#define MAXSIZE 100
//数组静态分配
typedef struct
{
ElemType elem[MAXSIZE];
int length;
}SqList;
//数组动态分配
typedef struct
{
ElemType *elem;
int length;
}SqList;
SqList L;
L.elem = (ElemType *)malloc(sizeof(ElemType) * MAXSIZE);
//C++的动态存储分配
int * p = new ElemType;
int * p = new ElemType(10);
实例
#define MAXSIZE 10000 //图书表可能达到的最大长度
typedef struct { //图书信息定义
char no[20]; //图书ISBN
char name[50]; //图书名字
float price; //图书价格
}Book;
typedef struct {
Book *elem; //存储空间的基地址
int length; //图书表中当前图书个数
}SqList; //图书表的顺序存储结构类型为SqList
顺序表的基本操作
InitList(&L) //初始化操作,建立一个空的线性表L
DestoryList(&L) //销毁已存在的线性表L
ClearList(&L) //将线性表清空
GetLength(L) //返回线性表L的元素个数
IsEmpty(L) //若线性表为空,返回true,否则返回false
GetElem(L,i,&e) //线性表L中的第i个位置元素返回给e
LocateElem(L,e) //L中查找与给定值e相等的元素,成功返回该元素的序号,否知返回0
ListInsert(&L,i,e) //在线性表L中第i个位置插入新元素e
ListDelete(&L,i,&e) //删除线性表L中第i位置元素,用e返回
顺序表的初始化
//算法描述
//线性表L的初始化(参数用引用)
Status InitList_Sq(SqList &L) { //构造一个空的顺序表L
L.elem=new ElemType[MAXSIZE]; //为顺序表分配空间
if(!L.elem)
exit(OVERFLOW); //存储分配失败
L.length = 0; //空表长度为0
return OK;
}
销毁顺序表L
void DestroyList(SqList &L) {
if (L.elem)
delete L.elem; //释放存储空间
}
清空顺序表L
void ClearList(SqList &L) {
L.length = 0; //将线性表的长度置为0
}
求顺序表L的长度
int GetLength(SqList L) {
return (L.length);
}
判断顺序表L是否为空
int IsEmpty(SqList L) {
if (L.length==0)
return 1;
else
return O;
}
顺序表的取值
//根据位置i获取相应位置数据元素的内容
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;
}
顺序表的查找
int LocateELem(SqList L, ElemType e) { //在线性表L中省找值为e的数据元素,返回其序号(是第几个元素)
for (i=0;i< L.length;i++)
if (L.elem[i]==e)
return i+1; //查找成功,返回序号
return O; //查找失败,返回0
}
顺序表的插入
Status Listlnsert_Sq(SqList &L,inti,ElemType 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;
}
顺序表的删除
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;
}
链表
从头结点开始p=L; 首元结点开始p=L->next.
p=L; //p指向头结点
S=L->next; //s指向首元结点
p=p->next; //p指向下一结点
单链表的存储结构
typedef struct Lnode { //声明结点的类型和指向结点的指针类型
ElemType data; //结点的数据域
struct Lnode *next; //结点的指针域
}Lnode, *LinkList; //LinkList为指向结构体Lnode的指针类型
实例
//存储学生学号、姓名、成绩的单链表结点类型定义
typedef Struct student {
char num[8]; //数据域
char name[8]; //数据域
int score; //数据域
struct student *next; //指针域
}Lnode, *LinkList;
// 为了统一链表的操作,通常这样定义
typedef Struct {
char num[8]; //数据域
char name[8]; //数据域
iht score; //数据域
}ElemIype;
typedef struct Lnode {
ElemType data; //数据域
struct Lnode *next; //指针域
}Lnode, *LinkList;
单链表的初始化
Status InitList L(LinkList &L) {
L = new LNode; //或L=(LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
判断单链表是否为空
int ListEmpty(LinkList L) { //若L为空表,则返回1,否则返回0
if(L->next) //非空
return O;
else
return 1;
}
单链表的销毁
Status DestroyList_L(LinkList &L) {
Lnode *p; // 或LinkList p;
while(L) {
p = L;
L = L->next;
delete p;
}
}
清空单链表
//链表仍存在,但链表中无元素,成为空链表(头指针和头结点仍然在)
Status ClearList(LinkList &L) { //将L重置为空表
Lnode *p,*q; //或LinkList p,q
p=L->next;
while(p) { //没到表尾
q = p->next;
delete p;
p = q;
}
L->next = NULL; //头结点指针域为空
return OK;
}
求单链表L的表长
int ListLength_L(LinkList L) { //返回L中数据元素个数
LinkList p;
p = L->next; //p指向第一个结点
i=0;
while(p) { //遍历单链表,统计结点数
i++;
p=p->next;
}
return i;
}
取值
Status GetElem_L(LinkList L, int i, ElemType &e) {//获取线性表L中的某个数据元素的内容,通过变量e返回
p=L->next;
j=1; //初始化
while(p && j<i) {//向后扫描,直到p指向第i个元素或p为空
p = p->next;
++j;
}
if(!p ||j>i)
return ERROR; //第i个元素不存在
e=p->data; //取第i个元素
return OK;
} //GetElem L
查找
//按值查找 -- 根据指定数据获取该数据所在的位置(该数据的地址)
Lnode *LocateELem_L (LinkList L, Elemtype e) {
//在线性表L中查找值为e的数据元素
//找到,则返回L中值为e的数据元素的地址,查找失败返回NULL
p=L->next;
while(p && p->data!=e)
p = p->next;
return p;
}
//按值查找 -- 根据指定数据获取该数据所在的位置序号(是第几个元素)
//在线性表L中查找值为e的数据元素的位置序号
int LocateELem_L (LinkList L, Elemtype e) {
//返回L中值为e的数据元素的位置序号,查找失败返回0
p=L->next;
j=1;
while(p && p->data!=e) {
p=p->next;
j++;
}
if(p)
return j;
else
return 0;
}
插入
//在L中第i个元素之前插入数据元素e
Status Listlnsert_L(LinkList &L, int i, ElemType e) {
p=L;
j=0;
while(p && j<i-1) {
p=p->next;
++j;
}//寻找第i-1个结点,p指向i-1结点
if(!p || j>i-1)
return ERROR; //大于表长+1或者小于1,插入位置非法
S=new LNode;
S->data=e; //生成新结点S,将结点s的数据域置为e
s->next = p->next; //将结点s插入L中
p->next = S;
return OK;
}
删除
//将线性表L中第i个数据元素删除
Status ListDelete_L(LinkList &L, int i, ElemType &e)
p=L;
j=0;
while(p->next && j<i-1) {
p=p->next;
++j;
} //寻找第i个结点,并令p指向其前驱
if(!(p->next) || i>i-1)
return ERROR; //删除位置不合理
q=p->next; //临时保存被删结点的地址以备释放
p->next = q->next; //改变删除结点前驱结点的指针域
e = q->data; //保存删除结点的数据域
delete q; //释放删除结点的空间
return OK;
}
创建单链表
// 头插法
void CreateList_H(LinkList &L, int n) {
L = new LNode;
L->next = NULL; //先建立一个带头结点的单链表
for(i=n; i>0;--i) {
p = new LNode; //生成新结点 p=(LNode*)malloc(sizeof(LNode));
cin>>P->data; //输入元素值 scanf(&p->data);
p->next = L->next; //插入到表头
L->next = p;
}
}
//尾插法
void CreateList_R(LinkList &L, int n) {
L = new LNode;
L->next = NULL;
r=L; //尾指针r指向头结点
for(i=0; i<n; ++1) {
p = new LNode;
cin>>p->data; //生成新结点,输入元素值
p->next = NULL;
r->next = p; //插入到表尾
r = p; //r指向新的尾结点
}
}