线性表的顺序存储实现

最近准备考研了,复习到数据结构这块,因为本人对数据结构和算法很有兴趣,准备把数据结构书上的代码都写一遍。以后会陆续上传博客。

#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;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值