顺序表的操作(动态)

顺序表的操作(动态)

静态定义一个顺序表,是通过数组来定义, 顺序表所占的内存空间开辟在内存的栈上, 随着函数调用的结束, 这块内存区域会被系统自动回收;

动态定义顺序表, 顺序表所占的内存空间开辟在内存的堆上, 这块区域不会随着函数调用的结束被系统自动回收, 而是需要程序员自己去释放它。

顺序表的基本操作

1.顺序表的结构

typedef struct SeqList //SeqList可以省略
{
    ElemType elem*;//存储空间的基址,即开辟的动态数组的首地址
    int length;//有效数字的个数,顺序表当前存储元素的个数;
    int ListSize;//用来定义开辟空间的容量

}SeqList; //这里的SeqList相当于 struct SeqList 即可以通过SeqList L;直接声明顺序表变量

2.顺序表的初始化

void InitList(SeqList *L)
{
    L->elem=(ElemType*)malloc(MAXSIZE*sizeof(ElemType));//分配空间,即最大的元素数量乘以每个元素占的字节数。最后把指针类型强制转换位该元素类型的。
    if(!L->elem)//内存分配失败会返回NULL
        exit(OVERFLOW);//直接结束进程超量溢出,给系统返回错误代码-2
    L->length=0; //把顺序表的长度设置为0
    L->ListSize=MAXSIZE;//把当前顺序表的最大容量设置为MAXSIZE
}

3.顺序表的长度

int ListLength(SeqList L)
{
    return L.length;//返回线性表的的长度
}

4.判断顺序表是否为空

//判断线性表是否为空
int ListEmpty(SeqList L)
{
    if(L.length==0)//如果长度为0,返回1
        return 1;
    return 0;//默认非空,返回0;
}

5.打印出线性表的所有元素

//打印出线性表所有的元素
void PrintList(SeqList L)
{

    if(IsEmpty(L))
        printf("该顺序表为空表!\n");
    else
        for( int i=0; i<ListLength(L); i++)
        {
            printf("%d ",*(L.elem+i));
        }
}

6.向顺序表的指定位置插入元素

int InsertList(SeqList *L,int pos,ElemType e)//pos 插入的位置 e 插入的元素
{
    int j;//作为循环变量
    //先判断插入的位置是否合法
    if(pos<1||pos>L->length+1)
    {
        printf("插入位置不合法!\n");
        return ERROR;
    }
    //判断所剩空间是否充足,如果已满则需扩充空间
    else if(L->length==L->ListSize)
    {
        ElemType *temp;//建立一个指针存储返回的新的起始地址
        temp=realloc(L->elem,(L->ListSize+LISTCREMENT)*sizeof(ElemType));//realloc为更改存储空间大小的函数
        //判断是否分配内存成功
        if(!temp)
        {
          printf("分配内存失败!\n");
            exit(OVERFLOW);
        }
        else
        {
            L->elem=temp;
            L->ListSize+=LISTCREMENT;
        }
    }
    //从最后一个元素开始,向右平移一个单位,直到要插入的元素空出来
    else
    {
        for(j=L->length; j>=pos; j--)
            *(L->elem+j)=*(L->elem+j-1);//让后一个元素等与前一个元素
        *(L->elem+pos-1)=e;
        L->length++;//表长加一
    }
    return OK;
}

7.删除顺序表指定位置的元素

int DeleteList(SeqList *L,int pos,ElemType *e)//用e来保存删除位置的元素
{
    int i;//循环变量
    //判断删除的位置是否合理
    if(L->length==0)
    {
        printf("线性表是空表,不能进行删除!\n");
        return 0;
    }
    else if(pos<1||pos>L->length)
    {
        printf("删除位置不合理\n");
        return ERROR;
    }
    //从要删除的位置的右边开始,元素左移
    else
    {
        for(i=pos; i<L->length; i++)
            *(L->elem+i-1)=*(L->elem+i);

       L->length=L->length-1;
    }

    return OK;
}

8.摧毁顺序表


int DestroyList(SeqList *L)
{
    free(L->elem);
    L->elem=0;//空指针
    L->length=0;
    L->ListSize=0;
    printf("顺序表已销毁!\n");
    return OK;
}

9.清空线性表

int ClearLIst(SeqList *L)
{
    if(L->length==0)
      {
           printf("顺序表本来就是空表,不必清空!\n");
           return 0;
      }
      L->length=0;
    printf("顺序表已清空!\n");
    return OK;
}

10.获取顺序表指定位置的值

ElemType GetElem(SeqList L,int pos)
{
    if(pos>L.length||pos<1)
    {
        printf("输入的位置不合法!\n");
        return ERROR;
    }
    return *(L.elem+pos-1);
}

11.获取指定元素的位置

int LocatElem(SeqList L,ElemType e)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        if(e==*(L.elem+i))
            return i+1;
    }
    printf("顺序表中没有该元素!\n");
    return FALSE;
}

12.求指定元素的前驱元素

ElemType ProElem(SeqList L,ElemType e)
{
    if(!LocatElem(L,e))
        printf("顺序表中没有该元素!\n");
        else
        {
            if(LocatElem(L,e)==1)
            {
                printf("该元素没有前驱元素!\n");
                return ERROR;
            }

        }
        return *(L.elem+LocatElem(L,e)-1-1);
}

13.求指定元素的后继元素

//求指定元素的后继元素
ElemType NextElem(SeqList L,ElemType e)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        if(e==*(L.elem+i))
        {
            if(i==L.length-1)
            {
                printf("最后一个元素没有后继!\n");
                return ERROR;
            }
            return *(L.elem+i+1);
        }
    }
    printf("没有该元素!\n");
    return FALSE;
}

完整代码

SeqList.h

//声明顺序表的结构
typedef int ElemType; //元素的基本数据类型,方便更改
typedef struct //SeqList可以省略
{
    ElemType *elem;//定长数组;
    int length;//有效数字的个数,顺序表当前存储元素的个数;
    int ListSize;

} SeqList; //这里的SeqList相当于 struct SeqList 即可以通过SeqList L;直接声明顺序表变量

//顺序表的初始化
void InitList(SeqList *L)
{
    L->elem=(ElemType*)malloc(MAXSIZE*sizeof(ElemType));//分配空间,即最大的元素数量乘以每个元素占的字节数。最后把指针类型强制转换位该元素类型的。
    if(!L->elem)//内存分配失败会返回NULL
        exit(OVERFLOW);//直接结束进程超量溢出,给系统返回错误代码-2
    L->length=0; //把顺序表的长度设置为0
    L->ListSize=MAXSIZE;//把当前顺序表的最大容量设置为MAXSIZE
}
//判断线性表是否为空
int IsEmpty(SeqList L)
{
    if(L.length==0)
        return 1;
    return 0;
}
//顺序表的长度
int ListLength(SeqList L)
{
    return L.length;//返回线性表的的长度
}
//打印出线性表所有的元素
void PrintList(SeqList L)
{

    if(IsEmpty(L))
        printf("该顺序表为空表!\n");
    else
        for( int i=0; i<ListLength(L); i++)
        {
            printf("%d ",*(L.elem+i));
        }
    printf("\n");
}
//向顺序表的指定位置插入元素
int InsertList(SeqList *L,int pos,ElemType e)//pos 插入的位置 e 插入的元素
{
    int j;//作为循环变量
    //先判断插入的位置是否合法
    if(pos<1||pos>L->length+1)
    {
        printf("插入位置不合法!\n");
        return ERROR;
    }
    //判断所剩空间是否充足,如果已满则需扩充空间
    else if(L->length==L->ListSize)
    {
        ElemType *temp;//建立一个指针存储返回的新的起始地址
        temp=realloc(L->elem,(L->ListSize+LISTCREMENT)*sizeof(ElemType));//realloc为更改存储空间大小的函数
        //判断是否分配内存成功
        if(!temp)
        {
            printf("分配内存失败!\n");
            exit(OVERFLOW);
        }
        else
        {
            L->elem=temp;
            L->ListSize+=LISTCREMENT;
        }
    }
    //从最后一个元素开始,向右平移一个单位,直到要插入的元素空出来
    for(j=L->length; j>=pos; j--)
        *(L->elem+j)=*(L->elem+j-1);//让后一个元素等与前一个元素
    *(L->elem+pos-1)=e;
    ++L->length;//表长加一

    return OK;
}
//删除指定位置的元素
int DeleteList(SeqList *L,int pos,ElemType *e)//用e来保存删除位置的元素
{
    int i;//循环变量
    //判断删除的位置是否合理
    if(L->length==0)
    {
        printf("线性表是空表,不能进行删除!\n");
        return 0;
    }
    else if(pos<1||pos>L->length)
    {
        printf("删除位置不合理\n");
        return ERROR;
    }
    //从要删除的位置的右边开始,元素左移
    else
    {
        for(i=pos; i<L->length; i++)
            *(L->elem+i-1)=*(L->elem+i);

        L->length=L->length-1;
    }

    return OK;
}
//摧毁顺序表
int DestroyList(SeqList *L)
{
    free(L->elem);
    L->elem=0;//空指针
    L->length=0;
    L->ListSize=0;
    printf("顺序表已销毁!\n");
    return OK;
}
//清空线性表
int ClearLIst(SeqList *L)
{
    if(L->length==0)
    {
        printf("顺序表本来就是空表,不必清空!\n");
        return 0;
    }
    L->length=0;
    printf("顺序表已清空!\n");
    return OK;
}
//获取顺序表指定位置的值
ElemType GetElem(SeqList L,int pos)
{
    if(pos>L.length||pos<1)
    {
        //printf("输入的位置不合法!\n");
        return ERROR;
    }
    return *(L.elem+pos-1);
}
//获取指定元素的位置
int LocatElem(SeqList L,ElemType e)
{
    int i;
    for(i=0; i<L.length; i++)
    {
        if(e==*(L.elem+i))
            return i+1;
    }
    printf("顺序表中没有该元素!\n");
    return FALSE;
}
//求指定元素的前驱
ElemType ProElem(SeqList L,ElemType e)
{
    if(!LocatElem(L,e))
        {printf("顺序表中没有该元素!\n");
         return ERROR;
        }
        else
        {
            if(LocatElem(L,e)==1)
            {
               // printf("该元素没有前驱元素!\n");
                return ERROR;
            }

        }
        return *(L.elem+LocatElem(L,e)-1-1);
}
//求指定元素的后继元素
ElemType NextElem(SeqList L,ElemType e)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        if(e==*(L.elem+i))
        {
            if(i==L.length-1)
            {
                //printf("最后一个元素没有后继!\n");
                return ERROR;
            }
            return *(L.elem+i+1);//返回第i+1个元素
        }
    }
    printf("没有该元素!\n");
    return FALSE;
}

main.c

//typedef int ElemType;
#define LISTCREMENT 10 //存储空间增量,空间不足时便于增加
#define MAXSIZE 100
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define INFESAIBLE -1 //不能执行的
#define OVERFLOW -2
typedef int Status;// status是函数的类型,其值是函数结果状态代码
#include 
#include 
#include "SqList.h" //包含顺序表的操作函数
void Menu();
int main()
{
    int pos;//充当循环和其他变liang
    ElemType e;
    SeqList L;//声明一个顺序表L;
    InitList(&L);//初始化;
    int flag;
    Menu();
    while(1)
    {
        printf("请输入你要进行的操作:");
        scanf("%d",&flag);
        getchar();
        switch(flag)
        {
        case 0:
            Menu();
            break;
        case 1:
            InitList(&L);
            break;
        case 2:
            printf("线性表的长度为:%d\n",ListLength(L));
            break;
        case 3:
            if(IsEmpty(L))
                printf("线性表是空表!\n");
            else
                printf("线性表不是空表!\n");
            break;
        case 4:
            PrintList(L);
            break;
        case 5:
            printf("请输入你要插入的位置和元素:");
            scanf("%d %d",&pos,&e);
            getchar();
            if(InsertList(&L,pos,e))
                printf("插入成功!\n");
            break;
        case 6:
            printf("请输入你要删除的位置:");
            scanf("%d",&pos);
            if(DeleteList(&L,pos,&e))
                printf("删除成功,你删除的元素是%d\n",e);
            break;
        case 7:
            DestroyList(&L);
            break;
        case 8:
            ClearLIst(&L);
            break;
        case 9:
            printf("请输入你要查询的位置:");
            scanf("%d",&pos);
            getchar();
            if(GetElem(L,pos))
                printf("第%d个元素为%d\n",pos,GetElem(L,pos));
            else
                printf("输入的位置不合法!\n");
            break;
        case 10:
            printf("请输入你要查询的元素:");
            scanf("%d",&e);
            getchar();
            if(LocatElem(L,e))
                printf("元素%d的位置为%d\n",e,LocatElem(L,e));
            else
                printf("顺序表中没有该元素!\n");
            break;
        case 11:
            printf("请输入你要查询的元素:");
            scanf("%d",&e);
            getchar();
            if(ProElem(L,e))
                printf("元素%d的前驱为%d\n",e,ProElem(L,e));
            else
                printf("该元素没有前驱元素!\n");
            break;
        case 12:
            printf("请输入你要查询的元素:");
            scanf("%d",&e);
            getchar();
            if(NextElem(L,e))
                printf("元素%d的后继为%d\n",e,NextElem(L,e));
            else
                printf("该元素没有后继元素!\n");
            break;
        default :
            if(flag<0)
                exit(0);
            else
                printf("你输入的数字不合法!\n");
            break;

        }
    }
    return 0;
}
void Menu()
{
    printf("          顺序表的基本操作           \n");
    printf("  0.打印出菜单\n");
    printf("  1.初始化顺序表\n");
    printf("  2.求出当前顺序表的长度\n");
    printf("  3.判断顺序表是否为空\n");
    printf("  4.打印出顺序表中的所有元素\n");
    printf("  5.向顺序表的指定位置插入元素\n");
    printf("  6.删除顺序表的指定位置的元素\n");
    printf("  7.摧毁顺序表\n");
    printf("  8.清空顺序表\n");
    printf("  9.获取顺序表指定位置的值\n");
    printf("  10.获取顺序表指定值的位置\n");
    printf("  11.获取顺序表指定值的前驱\n");
    printf("  12.获取顺序表指定值的后继\n");
    printf(" !!!请输入一个负数退出此程序!\n");

}

最终运行结果

          顺序表的基本操作
  0.打印出菜单
  1.初始化顺序表
  2.求出当前顺序表的长度
  3.判断顺序表是否为空
  4.打印出顺序表中的所有元素
  5.向顺序表的指定位置插入元素
  6.删除顺序表的指定位置的元素
  7.摧毁顺序表
  8.清空顺序表
  9.获取顺序表指定位置的值
  10.获取顺序表指定值的位置
  11.获取顺序表指定值的前驱
  12.获取顺序表指定值的后继
 !!!请输入一个负数退出此程序!
请输入你要进行的操作:0
          顺序表的基本操作
  0.打印出菜单
  1.初始化顺序表
  2.求出当前顺序表的长度
  3.判断顺序表是否为空
  4.打印出顺序表中的所有元素
  5.向顺序表的指定位置插入元素
  6.删除顺序表的指定位置的元素
  7.摧毁顺序表
  8.清空顺序表
  9.获取顺序表指定位置的值
  10.获取顺序表指定值的位置
  11.获取顺序表指定值的前驱
  12.获取顺序表指定值的后继
 !!!请输入一个负数退出此程序!
请输入你要进行的操作:1
请输入你要进行的操作:2
线性表的长度为:0
请输入你要进行的操作:3
线性表是空表!
请输入你要进行的操作:4
该顺序表为空表!

请输入你要进行的操作:5
请输入你要插入的位置和元素:1 1
插入成功!
请输入你要进行的操作:5
请输入你要插入的位置和元素:2 2
插入成功!
请输入你要进行的操作:5
请输入你要插入的位置和元素:3 3
插入成功!
请输入你要进行的操作:4
1 2 3
请输入你要进行的操作:9
请输入你要查询的位置:1
第1个元素为1
请输入你要进行的操作:9
请输入你要查询的位置:2
第2个元素为2
请输入你要进行的操作:10
请输入你要查询的元素:2
元素2的位置为2
请输入你要进行的操作:10
请输入你要查询的元素:1
元素1的位置为1
请输入你要进行的操作:11
请输入你要查询的元素:2
元素2的前驱为1
请输入你要进行的操作:12
请输入你要查询的元素:3
该元素没有后继元素!
请输入你要进行的操作:8
顺序表已清空!
请输入你要进行的操作:-1

你可能感兴趣的:(顺序表的操作(动态))