c++(非STL)实现线性表
这里注意一个问题
关于涉及地址的函数定义和引用
//初始化一个空的线性表
Status InitList(SqList *L) 这里是*L
{
L->elem = (Elemtype *) malloc(INIT_SIZE * sizeof(Elemtype));
if(!L->elem)
{
return ERROR;
}
L->length = 0;
L->size = INIT_SIZE;
return OK;
}
这里是*L
引用函数的时候
InitList(&L); 传L的地址
如果是Status InitList(SqList &L) 这就是c++特有的一种方式(具体叫什么我忘了,好像是引用)
调用函数的时候 InitList(L);
代码明天早上我敲上来
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INIT_SIZE 10 //初始化表长
#define INCREMENT_SIZE 5 //分配增量
/**
c语言中并没有status这个关键字,
但是一般会定义这样一个类型,
表示成功或者失败的状态
**/
typedef int Status;
typedef int Elemtype;
//#define Status int
//#define Elemtype int
//定义线性表结构
typedef struct
{
Elemtype *elem; //存储空间基址
int length; //当前长度
int size; //当前分配的表长大小
}SqList;
//初始化一个空的线性表
Status InitList(SqList *L)
{
L->elem = (Elemtype *) malloc(INIT_SIZE * sizeof(Elemtype));
if(!L->elem)
{
return ERROR;
}
L->length = 0;
L->size = INIT_SIZE;
return OK;
}
//销毁线性表
Status DestroyList(SqList *L)
{
free(L->elem);
L->length = 0;
L->size = 0;
return OK;
}
//清空线性表
Status ClearList(SqList *L)
{
L->length = 0;
return OK;
}
//判断线性表是否为空
Status isEmpty(const SqList L) //const好像是不能改动
{
if(L.length == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
//获取长度
Status getLength(const SqList L)
{
return L.length;
}
//根据位置获取元素
Status GetElem(const SqList L,int i,Elemtype *e) //最后这个Elemtype *e应该就是用来接收获取的这个元素的
{
if(i<1||i>L.length) //取第一个元素,就是在取第0个
{
return ERROR;
}
*e = L.elem[i-1]; //这里直接对传进来的参数操作
return OK;
}
//比较两个元素是否相等(用于查找元素)
Status compare(Elemtype e1,Elemtype e2)
{
if(e1 == e2)
{
return 0;
}
else if(e1 < e2)
{
return -1;
}
else
{
return 1;
}
}
//查找元素(使用 判断两个元素是否相等)
Status FindElem(const SqList L,Elemtype e,Status(*compare)(Elemtype, Elemtype))
{
int i;
for(i=0;i<L.length;i++)
{
if(!(*compare)(L.elem[i],e))
{
return i+1;
}
}
if(i>=L.length)
{
return ERROR;
}
}
//查找前驱元素
Status PreElem(const SqList L,Elemtype cur_e,Elemtype *pre_e)
{
int i;
for(i=0;i<L.length;i++)
{
if(cur_e == L.elem[i])
{
if(i!=0)
{
*pre_e = L.elem[i-1];
}
else
{
return ERROR;
}
}
if(i>=L.length)
{
return ERROR;
}
}
}
//查找后继元素
Status NextElem(const SqList L, Elemtype cur_e, Elemtype *next_e)
{
int i;
for (i = 0; i < L.length; i++)
{
if (cur_e == L.elem[i])
{
if (i < L.length - 1)
{
*next_e = L.elem[i + 1];
return OK;
}
else
{
return ERROR;
}
}
}
if (i >= L.length)
{
return ERROR;
}
}
//插入元素
Status InsertElem(SqList *L,int i,Elemtype e)
{
Elemtype *newbase = NULL;
if(i<1||i>L->length+1)
{
return ERROR;
}
if(L->length >= L->size) //如果L现有的长度大于其分配的表长
{
//realloc:在现有情况下分配(增加)线性表
newbase = (Elemtype*)realloc(L->elem,(L->size+INCREMENT_SIZE)*sizeof(Elemtype));
if(!newbase)
{
return ERROR;
}
L->elem = newbase;
L->size += INCREMENT_SIZE;
}
Elemtype *p = &L->elem[i-1];
Elemtype *q = &L->elem[L->length-1];
for(;q>=p;q--)
{
*(q+1) = *q;
}
*p = e;
++L->length;
return OK;
}
//删除元素并返回其值
Status DeleteElem(SqList *L,int i,Elemtype *e)
{
if(i<1||i>L->length)
{
return ERROR;
}
Elemtype *p = &L->elem[i - 1];
*e = *p; //被删除元素
//我感觉也可以不用取地址赋值,可以直接赋值
for (; p < &L->elem[L->length]; p++)
{
*(p) = *(p + 1);
}
--L->length;
return OK;
}
//访问元素
void visit(Elemtype e)
{
cout<<e;
}
//遍历线性表
Status TraverseList(const SqList L,void(*visit)(Elemtype))
{
for(int i=0;i<L.length;i++)
{
//为什么这里不用括起来取地址
visit(L.elem[i]);
}
return OK;
}
//主函数测试
int main()
{
SqList L; //实例化一个对象
if(InitList(&L))
{
Elemtype e;
cout<<"init success"<<endl;
for(int i=0;i<10;i++)
{
InsertElem(&L,i+1,i);
}
cout<<"length is "<<getLength(L)<<endl;
if (GetElem(L, 1, &e)) {
cout<<"The first element is "<<e<<endl;
}
else
{
cout<<"element is not exist"<<endl;
}
if (isEmpty(L))
{
cout<<"list is empty"<<endl;
}
else
{
cout<<"list is not empty"<<endl;
}
TraverseList(L,visit);
cout<<L.elem[2];
}
return 0;
}