最近准备考研了,复习到数据结构这块,因为本人对数据结构和算法很有兴趣,准备把数据结构书上的代码都写一遍。以后会陆续上传博客。
#include<stdio.h>
#include<stdlib.h>
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
#define ElemType int
typedef int Status;
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
/**
一般是不在函数中写太多的输出和格式控制的操作,因为在调用的时候有
自己的输出和逻辑判断要求,我在这里为了判断和调试方便,就把过多的输出写在
了函数里面,望各位大神不要介意我这个小白的写法。
*/
bool compare(ElemType a,ElemType b)
{
if(a == b) return true;
return false;
}
bool visit(ElemType e)
{
printf("%d ",e);
return true;
}
/**
基本操作
*/
//(1)构造一个空的线性表
Status InitList(SqList &L)
{
L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) //存储分配失败
{
printf("构造线性表失败\n");
exit(OVERFLOW);
}
L.length = 0; //空表长度
L.listsize = LIST_INIT_SIZE; //出事存储容量
printf("构造空线性表成功\n");
return OK;
}
//(2) 销毁线性表 L
//初始条件:线性表 L 已存在
void DestroyList(SqList &L)
{
free(&L);
printf("线性表已经销毁\n");
}
// (3) 将线性表L 置为空表
//初始条件:线性表 L 已存在
void ClearList(SqList &L)
{
L.length = 0;
printf("线性表L被置为空表\n");
}
// (4) 若L为空表,则返回 TURE ,否则返回 FALSE
bool ListEmpty(SqList L)
{
if(0 == L.length)
{
printf("L 是一张空的线性表\n");
return true;
}
else
{
printf("L 不是一张空的线性表\n");
return false;
}
}
// (5) 返回L表 中元素的个数
Status ListLength(SqList L)
{
return L.length;
}
// (6) 用e返回L中第i个元素的值
Status GetElem(SqList L,int i,ElemType &e)
{
if(i < 1 || i > L.length) return ERROR;
e = L.elem[i-1];
return TURE;
}
// (7) 返回L中第一个与e满足关系compare()的数据元素的位序,若这样的元素不存在,则返回0
Status LocateElem(SqList L,int e,bool (*compare)(ElemType,ElemType))
{
int i = 1;
ElemType* p = L.elem;
while(i <= L.length && !(*compare)(*p++, e)) ++i;
if(i <= L.length) return i;
else return 0;
}
// (8) 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
for(int i = 1; i<L.length; i++)
{
if(cur_e == L.elem[i])
{
pre_e = L.elem[i-1];
return OK;
}
}
return ERROR;
}
// (9) 若cur_e是L中的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{
for(int i = 0;(i < L.length - 1);i++)
{
if(cur_e == L.elem[i])
{
next_e = L.elem[i+1];
return OK;
}
}
return ERROR;
}
// (10) 在L中第i个位置之前插入新的数据元素e,L的长度加1
Status ListInsert(SqList &L,int i,ElemType e)
{
if(i < 1 || i > L.length + 1)
{
printf("传入的i的数组越界,请输入合法的i的值\n");
return ERROR;
}
if(L.length>=L.listsize) //在此处判断一下是否有可用的插入空间,没有的话增加空间容量.
{
ElemType *newbase = (ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW);
L.elem = newbase;
L.listsize = L.listsize + LISTINCREMENT;
}
for(int j = (L.length -1);j >= (i - 1);j--)
{
L.elem[j+1] = L.elem[j];
}
L.elem[i-1] = e;
L.length++;
return OK;
}
// (11) 删除L 中的第i个数据元素,并用e返回其值,L的长度减一
Status ListDelete(SqList &L,int i, ElemType &e)
{
if(i < 1 || i > L.length + 1)
{
printf("传入i的值不合法,请重新传入i的值\n");
return ERROR;
}
e = L.elem[i-1];
for(int t = i - 1;t < L.length - 1 ; t++)
{
L.elem[t] = L.elem[t+1];
}
L.length--;
return OK;
}
// (12) 以此对L中的每个元素调用visit()函数,一旦visit()函数调用失败,则操作失败
Status ListTraverse(SqList L,bool(*visit)(ElemType))
{
int i = 1;
ElemType *p = L.elem;
while(i <= L.length && (*visit)(*p++)) ++i;
printf("\n");
if(i < L.length)
{
return ERROR;
}
return OK;
}
int main()
{
SqList L;
ElemType e;
ElemType pre_e;
ElemType next_e;
InitList(L); //构造一张线性表
ListEmpty(L); //判断线性表L是否是空表
// ListInsert(SqList &L,int i,ElemType e)
//在表 L 中插入元素
for(int i = 1 ;i <= 10 ; i++)
{
ListInsert(L,i,i);
}
ListEmpty(L); //判断线性表L是否是空表
printf("线性表L的长度是: %d\n",ListLength(L)); //查看表L的长度
ListTraverse(L,visit); //打印出L表中的元素
if(GetElem(L,10,e)) //取第10个位置的元素,并打印出来
{
printf("GetElem(L,10,e) = %d\n",e);
}
if( int index = LocateElem(L,7,compare))
{
printf("LocateElem()操作成功,L中与7相等元素的位置序列是: %d\n",index);
}else{
printf("LocateElem()操作失败\n");
}
if(PriorElem(L,10,pre_e))
{
printf("cur_e的前驱是: %d\n",pre_e);
}else{
printf("没有找到元素cur_e元素的前驱\n");
}
if(NextElem(L,1,next_e))
{
printf("cur_e 元素的后继是: %d\n",next_e);
}else{
printf("没有找到cur_e 元素的后继\n");
}
printf("执行删除操作之前线性表的中的元素:");
ListTraverse(L,visit);
if(ListDelete(L,3,e))
{
printf("执行删除操作成功,被删除的元素是: %d\n",e);
}else{
printf("执行删除操作失败\n");
}
printf("执行删除操作之后线性表的中的元素:");
ListTraverse(L,visit);
return 0;
}