数据结构 - 静态顺序线性表的实行(C语言)

数据结构 - 静态顺序线性表的实行(C语言)

1 获取元素操作

对于线性表的顺序存储结构来说,如果我们要实现GetElem操作,即将线性表L中的第i个位置元素值返回,其实是非常简单的。 只要i的数值在数组下标范围内,就是把数组第i下标的值返回即可。 来看代码:

/******************************************
名称: 获取元素操作
功能: 将线性表pSeqList中的第i个位置元素值返回给e
返回值: Status是函数结果状态,成功返回TRUE,失败返回FALSE
******************************************/
Status GetElem(SeqList *pSeqList, int i, ElemType *e)
{
    //前提条件: 顺序线性表已存在,且i在合理范围内:0 <= i <= ListLength-1(pSeqList)
    if (pSeqList->length == 0 || i < 0 || i>pSeqList->length-1) //若pSeqList.length==0,则说明顺序线性表不存在
        return FALSE;

    *e = pSeqList->data[i];

    return TRUE;
}


2 插入操作

插入数据的实现过程如下图所示:

img

插入算法的思路;

  • 判断插入位置是否合理,不合理则抛出异常;
  • 判断线性表长度是否大于等于数组长度,是则抛出异常或动态增加容量;
  • 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
  • 将要插入元素填入位置i处;
  • 表长加1。

实现代码如下:

/******************************************
名称: 插入元素操作
功能: 在线性表pSeqList中的第i个位置插入元素e
返回值: Status是函数结果状态,成功返回TRUE,失败返回FALSE
******************************************/
Status ListInsert(SeqList *pSeqList, int i, ElemType e)
{
    int k;

    //判断插入位置是否合理,不合理则抛出异常
    if (i < 0 || i > pSeqList->length)
        return FALSE;
    
    //判断线性表长度是否大于等于数组长度,是则抛出异常或动态增加容量
    if (pSeqList->length >= MAX_SIZE)
        return FALSE;

    //从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置
    //有一种特殊情况不用后移: 当插入元素到表尾的下一个位置
    if (i <= pSeqList->length-1) //若插入数据位置在表尾或更前面,表尾为最后一个元素的位置
    {
        //将插入位置及后面元素向后移动一位
        for (k = pSeqList->length-1; k>=i; k--)
            pSeqList->data[k+1] = pSeqList->data[k];
    }
    //将要插入元素填入位置i处
    pSeqList->data[i] = e; 
    
    //表长加1
    pSeqList->length++; 

    return TRUE;
}

注意:插入位置可以是表尾元素的下一个位置,那样不需要后移元素。


3 删除操作

线性表的顺序存储结构删除元素的过程如下图所示:

img

删除算法的思路:

  • 判断线性表是否为空,为空则抛出异常;
  • 判断删除位置是否合理,不合理则抛出异常;
  • 取出删除元素;
  • 从删除元素的下一个位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
  • 表长减1。

实现代码如下:

/******************************************
名称: 删除元素操作
功能: 删除线性表pSeqList中的第i个位置的元素,并用e返回其值
返回值: Status是函数结果状态,成功返回TRUE,失败返回FALSE
******************************************/
Status ListInsert(SeqList *pSeqList, int i, ElemType *e)
{
    int k;

    //判断线性表是否为空,为空则抛出异常
    if (pSeqList->length == 0)
        return FALSE;

    //判断删除位置是否合理,不合理则抛出异常
    if (i < 0 || i > pSeqList->length-1)
        return FALSE;

    //取出删除元素
    *e = pSeqList->data[i];

    //从删除元素的下一个位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置
    if (i != pSeqList->length-1) //若删除位置在表尾,则不需要前移
    {
        //将删除元素的下一个位置及后面元素向前移动一位
        for (k = i+1; k <= pSeqList->length-1; k++)
            pSeqList->data[k-1] = pSeqList->data[k];
    }

    //表长减1
    pSeqList->length--;

    return TRUE;
}

注意:若pSeqList->length等于0,则说明线性表为空。


4 综合程序

/*
 * 几个注意点:
 * 1.初始化时,应考虑数组大小为负的情况
 * 2.在各操作中,当涉及到位置i时,都应考虑i位置不合理的情况
 * 3.插入操作中,需考虑线性表已满的情况
 *   删除、获取操作中,需考虑线性表为空的情况
 * 4.插入删除操作中,均应考虑插入或删除位置为表尾情况(似乎没必要)
 * 5.插入删除操作中,别忘了最后要改变表长
 */

#include "stdafx.h"
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
typedef int Status; //Status是函数结果状态,成功返回TRUE,失败返回FALSE

#define MAX_SIZE 100 //静态顺序线性表的最大容量
typedef int ElemType;
//定义静态顺序线性表
typedef struct
{
    ElemType data[MAX_SIZE];
    int length; //静态顺序线性表的元素个数
}SeqList;

SeqList *InitList(); //初始化操作
void ListDestroy(SeqList *pSeqList); //销毁线性表操作
Status ListEmpty(SeqList *pSeqList); //检测是否为空操作
Status ClearList(SeqList *pSeqList); //清空线性表操作
int ListLength(SeqList *pSeqList); //获取元素个数操作
Status GetElem(SeqList *pSeqList, int i, ElemType *e); //获取元素操作
int LocateElem(SeqList *pSeqList, const ElemType e); //查找元素位置操作
Status ListInsert(SeqList *pSeqList, int i, const ElemType e); //插入元素操作
Status ListInsert(SeqList *pSeqList, int i, ElemType *e); //删除元素操作

/******************************************
名称: 初始化操作
功能: 建立一个空的线性表pSeqList
******************************************/
SeqList *InitList()
{
    SeqList *pSeqList = (SeqList *)malloc(sizeof(SeqList));
    if (pSeqList == NULL)
    {
        printf("InitList malloc error!\n");
        exit(1);
    }

    pSeqList->length = 0;
    return pSeqList;
}

/******************************************
名称: 销毁线性表操作
功能: 释放线性表指针申请内存,并指向NULL
******************************************/
void ListDestroy(SeqList *pSeqList)
{
    free(pSeqList);
    pSeqList = NULL;
}

/******************************************
名称: 检测是否为空操作
功能: 若线性表元素个数为0,则认为线性表为空
返回值: 若线性表为空,返回true,否则返回false
******************************************/
Status ListEmpty(SeqList *pSeqList)
{
    return pSeqList->length == 0 ? TRUE :FALSE;
}

/******************************************
名称: 清空线性表操作
功能: 将线性表清空:将长度清零即可
返回值: 若线性表成功清空,返回true,否则返回false
******************************************/
Status ClearList(SeqList *pSeqList)
{
    pSeqList->length = 0;

    return TRUE;
}

/******************************************
名称: 获取元素个数操作
功能: 获取线性表pSeqList的元素个数
返回值: 线性表元素个数
******************************************/
int ListLength(SeqList *pSeqList)
{
    return pSeqList->length;
}

/******************************************
名称: 获取元素操作
功能: 将线性表pSeqList中的第i个位置元素值返回给e
返回值: Status是函数结果状态,成功返回TRUE,失败返回FALSE
******************************************/
Status GetElem(SeqList *pSeqList, int i, ElemType *e)
{
    //前提条件: 顺序线性表已存在,且i在合理范围内:0 <= i <= ListLength(pSeqList)
    if (pSeqList->length == 0 || i < 0 || i>pSeqList->length) //若pSeqList.length==0,则说明顺序线性表不存在
        return FALSE;

    *e = pSeqList->data[i];

    return TRUE;
}

/******************************************
名称: 查找元素位置操作
功能: 在线性表pSeqList中查找与给定值e相等的元素索引
返回值: 查找成功返回元素所在的位置索引,失败返回-1(不能返回0)
******************************************/
int LocateElem(SeqList *pSeqList, const ElemType e)
{
    //遍历并显示线性表元素
    for (int i = 0; i < pSeqList->length; i++)
    {
        if (e == pSeqList->data[i])
            return i;
    }

    return -1;
}

/******************************************
名称: 插入元素操作
功能: 在线性表pSeqList中的第i个位置插入元素e
返回值: Status是函数结果状态,成功返回TRUE,失败返回FALSE
******************************************/
Status ListInsert(SeqList *pSeqList, int i, const ElemType e)
{
    int k;

    //判断插入位置是否合理,不合理则抛出异常
    if (i < 0 || i > pSeqList->length)
        return FALSE;
    
    //判断线性表长度是否大于等于数组长度,是则抛出异常或动态增加容量
    if (pSeqList->length >= MAX_SIZE)
        return FALSE;

    //从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置
    //有一种特殊情况不用后移: 当插入元素到表尾的下一个位置
    if (i <= pSeqList->length-1) //若插入数据位置在表尾或更前面,表尾为最后一个元素的位置
    {
        //将插入位置及后面元素向后移动一位
        for (k = pSeqList->length-1; k>=i; k--)
            pSeqList->data[k+1] = pSeqList->data[k];
    }
    //将要插入元素填入位置i处
    pSeqList->data[i] = e; 
    
    //表长加1
    pSeqList->length++; 

    return TRUE;
}

/******************************************
名称: 删除元素操作
功能: 删除线性表pSeqList中的第i个位置的元素,并用e返回其值
返回值: Status是函数结果状态,成功返回TRUE,失败返回FALSE
******************************************/
Status ListInsert(SeqList *pSeqList, int i, ElemType *e)
{
    int k;

    //判断线性表是否为空,为空则抛出异常
    if (pSeqList->length == 0)
        return FALSE;

    //判断删除位置是否合理,不合理则抛出异常
    if (i < 0 || i > pSeqList->length-1)
        return FALSE;

    //取出删除元素
    *e = pSeqList->data[i];

    //从删除元素的下一个位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置
    if (i != pSeqList->length-1) //若删除位置在表尾,则不需要前移
    {
        //将删除元素的下一个位置及后面元素向前移动一位
        for (k = i+1; k <= pSeqList->length-1; k++)
            pSeqList->data[k-1] = pSeqList->data[k];
    }

    //表长减1
    pSeqList->length--;

    return TRUE;
}

/******************************************
名称: 遍历操作
功能: 遍历并显示线性表元素
返回值: 查找成功返回元素所在的位置索引,失败返回-1(不能返回0)
******************************************/
void ListTraverse(SeqList *pSeqList)
{
    for (int i = 0; i < pSeqList->length; i++)
        printf("%d ", pSeqList->data[i]);
    printf("\n");
}

int main()
{
    //初始化静态线性表
    SeqList *pSeqList = InitList();

    //检测线性表是否为空
    if (ListEmpty(pSeqList))
        printf("线性表为空!\n");
    else
        printf("线性表不为空!\n");

    //插入元素到静态线性表
    ListInsert(pSeqList, 0, 0);
    ListInsert(pSeqList, 1, 1);
    if ( ListInsert(pSeqList, 0, 2) ) //在位置0插入,后面位置的元素后移一位
        printf("元素插入成功!\n");

    //在线性表中删除元素
    int value1;
    if (ListInsert(pSeqList, 2, &value1) == FALSE)
    {
        printf("error!\n");
        return -1;
    }
    printf("删除的元素为:%d\n", value1);

    //获取元素个数
    printf("元素个数为%d个\n", ListLength(pSeqList));

    //查找元素位置
    printf("查找到元素的位置为:%d\n", LocateElem(pSeqList, 0));

    //遍历并显示线性表元素
    printf("遍历线性表: ");
    ListTraverse(pSeqList);

    //清空线性表
    printf("清空线性表!");
    ClearList(pSeqList);

    //销毁线性表
    ListDestroy(pSeqList);
    printf("\n");

    return 0;
}

/*
输出结果:

线性表为空!
元素插入成功!
删除的元素为:1
元素个数为2个
查找到元素的位置为:1
遍历线性表: 2 0
清空线性表!
*/

注意上面只是“静态顺序线性表”的C语言实现,只实现了一些最基本的操作,有兴趣的同学可以在这上面扩展。

转载于:https://www.cnblogs.com/linuxAndMcu/p/10304079.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值