2-1-2顺序表的源码
c1.h
// c1.h (程序名)
#pragma once
#ifndef __C1_H__
#define __C1_H__
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream> // cout,cin
using namespace std;
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define SUCCEEDED 1
#define ERROR 0
#define FAILED 0
#define INFEASIBLE -1
#define EQUAL 1
#define UNEQUAL 0
// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如SUCCEEDED等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE
#endif
Compare.cpp
// Compare.cpp 几个常用的函数
#include "Compare.h"
#include "SqListType.h"
#include <stdio.h>
Status equal(ElemType c1,ElemType c2)
{ // 判断是否相等的函数
if(c1==c2)
return EQUAL;
else
return UNEQUAL;
}
int unequal(ElemType a,ElemType b)
{ // 根据a<、=或>b,分别返回-1、0或1
if(a==b)
return 0;
else
return (a-b)/abs(a-b);
}
void Dprint(ElemType c)
{
printf("%d ",c);
}
void Cprint(ElemType c)
{
printf("%c ",c);
}
void CitePrint(ElemType &c)
{
printf("%d ",c);
}
Compare.h
#pragma once
#ifndef __COMPARE_H__
#define __COMPARE_H__
#include "c1.h"
#include "SqListType.h"
// 判断是否相等的函数
Status equal(ElemType c1,ElemType c2);
// 根据 a<、 =或 >b,分别返回 -1、 0或 1
int unequal(ElemType a,ElemType b);
void Dprint(ElemType c);
void Cprint(ElemType c);
void CitePrint(ElemType &c);
#endif
SqListBasicOperation.cpp
// bo2-1.cpp 顺序表示的线性表(存储结构由c2-1.h定义)的基本操作(12个),包括算法2.3,2.4,2.5,2.6
#include "c1.h"
#include "SqListType.h"
#include "SqListBasicOperation.h"
void InitList(SqList &L) // 算法2.3
{ // 操作结果:构造一个空的顺序线性表L
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
// printf("!L.elem=%x\n",!L.elem);
if(L.elem==NULL)
exit(OVERFLOW); // 存储分配失败
if (L.elem!=NULL){
L.length=0; // 空表长度为0
L.listsize=LIST_INIT_SIZE; // 初始存储容量
}
}
void DestroyList(SqList &L)
{ // 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L
free(L.elem);
L.elem=NULL;
L.length=0;
L.listsize=0;
}
void ClearList(SqList &L)
{ // 初始条件:顺序线性表L已存在。操作结果:将L重置为空表
L.length=0;
}
Status ListEmpty(SqList L)
{ // 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE
if(L.length==0)
return TRUE;
else
return FALSE;
}
int ListLength(SqList L)
{ // 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数
return L.length;
}
Status GetElem(SqList L,int pos,ElemType &e)
{ // 初始条件:顺序线性表L已存在,1≤pos≤ListLength(L)。操作结果:用e返回L中第i个数据元素的值
if(pos<1||pos>L.length)
return ERROR;
else
e=*(L.elem+pos-1);
return SUCCEEDED;
}
int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ // 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
// 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。
// 若这样的数据元素不存在,则返回值为0。算法2.6
ElemType *p;
int pos=1; // i的初值为第1个元素的位序
p=L.elem; // p的初值为第1个元素的存储位置
// printf("p=L.elem地址是%x\n",p);
// printf("原始pos=%d\n",pos);
// printf("*****************\n");
while(pos<=L.length){
if (compare(*p,e)==UNEQUAL){
p++;
pos++;
// printf("地址=%x\n",p);
// printf("++pos=%d\n",pos);
}else{
break;
}
}
if(pos<=L.length)
return pos;
else
return FAILED;
}
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{ // 初始条件:顺序线性表L已存在
// 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
// 否则操作失败,pre_e无定义
int pos=1;
ElemType *p=L.elem;
if (*L.elem==cur_e){
return INFEASIBLE;
}
pos+=1;
p=L.elem+1;
while(pos<=L.length&&*p!=cur_e)
{
p++;
pos++;
}
if(pos>L.length)
return INFEASIBLE; // 操作失败
else
{
pre_e=*--p;
return SUCCEEDED;
}
}
Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{ // 初始条件:顺序线性表L已存在
// 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
// 否则操作失败,next_e无定义
int pos=1;
ElemType *p=L.elem;
while(pos<L.length&&*p!=cur_e)
{
pos++;
p++;
}
if(pos==L.length||pos>L.length)
return INFEASIBLE; // 操作失败
else
{
next_e=*++p;
return SUCCEEDED;
}
}
Status ListInsert(SqList &L,int pos,ElemType e) // 算法2.4
{ // 初始条件:顺序线性表L已存在,1≤pos≤ListLength(L)+1
// 操作结果:在L中第pos个位置之前插入新的数据元素e,L的长度加1
ElemType *newbase,*insert,*an;
if(pos<1||pos>L.length+1) {
return ERROR;//pos值不合法
}else{
if(L.length>=L.listsize) // 当前存储空间已满,增加分配
{
newbase=(ElemType *)realloc(L.elem,(L.listsize+LIST_INCREMENT)*sizeof(ElemType));
// printf("旧的L.elem=%x\n",L.elem);
// printf("新的newbase=%x\n",newbase);
// printf("L的长度=%d",sizeof(L));
if(newbase==NULL)
exit(OVERFLOW); // 存储分配失败
L.elem=newbase; // 新基址
// printf("新的L.elem=%x\n",L.elem);
L.listsize+=LIST_INCREMENT; // 增加存储容量
}
insert=L.elem+pos-1; // insert为插入位置
for(an=L.elem+L.length-1;an>=insert;--an) // 插入位置及之后的元素右移
*(an+1)=*an;
*insert=e; // 插入e
++L.length; // 表长增1
return SUCCEEDED;
}
}
Status ListDelete(SqList &L,int pos,ElemType &e) // 算法2.5
{ // 初始条件:顺序线性表L已存在,1≤pos≤ListLength(L)
// 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
ElemType *delP,*an,*mov;
if(pos<1||pos>L.length){ // pos值不合法
return ERROR;
}else{
delP=L.elem+pos-1; // delP为被删除元素的位置
e=*delP; // 被删除元素的值赋给e
an=L.elem+L.length-1; // 表尾元素的位置
mov=++delP;//pos位置上的指针向后移动一位,为移动pos后面的元素做准备
while(mov<=an){
*(mov-1)=*mov;
++mov;// 被删除元素之后的元素左移
}
L.length--; // 表长减1
return SUCCEEDED;
}
}
void ListTraverse(SqList L,void(*vi)(ElemType&))
{ // 初始条件:顺序线性表L已存在
// 操作结果:依次对L的每个数据元素调用函数vi()
// vi()的形参加'&',表明可通过调用vi()改变元素的值
ElemType *p;//p是从顺序表开始遍历到表结束的指针
int i;
p=L.elem;
for(i=1;i<=L.length;i++){
vi(*p);//vi是显示格式的函数指针
p++;
}
printf("\n");
}
SqListBasicOperation.h
#pragma once
#ifndef _SQLISTBASICOPERATION_H__
#define _SQLISTBASICOPERATION_H__
#include "c1.h"
#include "SqListType.h"
void InitList(SqList &L);
void DestroyList(SqList &L);
void ClearList(SqList &L);
Status ListEmpty(SqList L);
int ListLength(SqList L);
Status GetElem(SqList L,int pos,ElemType &e);
int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType));
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e);
Status NextElem(SqList L,ElemType cur_e,ElemType &next_e);
Status ListInsert(SqList &L,int pos,ElemType e);
Status ListDelete(SqList &L,int pos,ElemType &e);
void ListTraverse(SqList L,void(*vi)(ElemType&));
#endif
SqListTestMain.cpp
// SqListTestMain.cpp 检验SqListBasicOperation.cpp的主程序
#include"c1.h"
#include"SqListType.h"
#include"Compare.h" // 包括equal()、comp()、Dprint()、Cprint()和CitePrint()函数
#include"SqListBasicOperation.h"
// 数据元素判定函数 (平方关系 ) , LocateElem() 调用的函数
Status sq(ElemType c1, ElemType c2);
// ListTraverse() 调用的另一函数 (元素值加倍 )
void ElemDouble(ElemType &Citec);
void main()
{
SqList L;
ElemType e,e0;
Status i;
int j,k;
InitList(L);
printf("初始化L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
for(j=1;j<=5;j++)
i=ListInsert(L,1,j);
printf("在L的表头依次插入1~5后:*L.elem=");
for(j=1;j<=5;j++)
cout<<*(L.elem+j-1)<<' ';
cout<<endl;
printf("L.elem=%u L.length=%d L.listsize=%d ",L.elem,L.length,L.listsize);
i=ListEmpty(L);
printf("L是否空:i=%d(1:是 0:否)\n",i);
ClearList(L);
printf("清空L后:L.elem=%u L.length=%d L.listsize=%d ",L.elem,L.length,L.listsize);
i=ListEmpty(L);
printf("L是否空:i=%d(1:是 0:否)\n",i);
for(j=1;j<=10;j++)
ListInsert(L,j,j);
printf("在L的表尾依次插入1~10后:*L.elem=");
for(j=1;j<=10;j++)
cout<<*(L.elem+j-1)<<' ';
cout<<endl;
printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
ListInsert(L,1,0);
printf("在L的表头插入0后:*L.elem=");
for(j=1;j<=ListLength(L);j++) // ListLength(L)为元素个数
cout<<*(L.elem+j-1)<<' ';
cout<<endl;
printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)\n",L.elem,L.length,L.listsize);
GetElem(L,5,e);
printf("第5个元素的值为:%d\n",e);
for(j=10;j<=11;j++)
{
k=LocateElem(L,j,equal);
if(k) // k不为0,表明有符合条件的元素,且其位序为k
printf("第%d个元素的值为%d\n",k,j);
else
printf("没有值为%d的元素\n",j);
}
for(j=3;j<=4;j++)
{
k=LocateElem(L,j,sq);
if(k) // k不为0,表明有符合条件的元素,且其位序为k
printf("第%d个元素的值为%d的平方\n",k,j);
else
printf("没有值为%d的平方的元素\n",j);
}
for(j=1;j<=2;j++) // 测试头两个数据
{
GetElem(L,j,e0); // 把第j个数据赋给e0
i=PriorElem(L,e0,e); // 求e0的前驱
if(i==INFEASIBLE)
printf("元素%d无前驱\n",e0);
else
printf("元素%d的前驱为:%d\n",e0,e);
}
for(j=ListLength(L)-1;j<=ListLength(L);j++) // 最后两个数据
{
GetElem(L,j,e0); // 把第j个数据赋给e0
i=NextElem(L,e0,e); // 求e0的后继
if(i==INFEASIBLE)
printf("元素%d无后继\n",e0);
else
printf("元素%d的后继为:%d\n",e0,e);
}
k=ListLength(L); // k为表长
for(j=k+1;j>=k;j--)
{
i=ListDelete(L,j,e); // 删除第j个数据
if(i==ERROR)
printf("删除第%d个元素失败\n",j);
else
printf("删除第%d个元素成功,其值为:%d\n",j,e);
}
printf("依次输出L的元素:");
ListTraverse(L,CitePrint); // 依次对元素调用CitePrint(),输出元素的值
printf("L的元素值加倍后:");
ListTraverse(L,ElemDouble); // 依次对元素调用ElemDouble(),元素值乘2
ListTraverse(L,CitePrint);
DestroyList(L);
printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
getchar();
}
Status sq(ElemType c1,ElemType c2)
{ // 数据元素判定函数(平方关系),LocateElem()调用的函数
if(c1==c2*c2)
return TRUE;
else
return FALSE;
}
void ElemDouble(ElemType &c)
{ // ListTraverse()调用的另一函数(元素值加倍)
c*=2;
}
SqListType.h
#pragma once
#ifndef _SQLISTTYPE_H_
#define _SQLISTTYPE_H_
#define LIST_INIT_SIZE 10/*1*/
#define LIST_INCREMENT 2/*2*/
typedef int ElemType;
struct SqList{
ElemType *elem;/*3*/
int length;/*4*/
int listsize;/*5*/
};
#endif