详解(数据结构C语言版)顺序表

顺序表的定义及其特点

顺序表的定义

顺序表可以通过结构体来定义,通常包含以下两个主要成员:

  1. 数据数组:存储数据元素的数组,每个数组元素都存储一个数据项。
  2. 长度属性:表示顺序表当前包含的元素数量。
#define MaxSize 1000 //先定义最大长度便于修改

typedef struct SeqList { //使用typedef重命名结构体便于使用
    DataType data[MaxSize]; // 数据元素数组
    int length;             // 顺序表的当前长度
} SeqList;

顺序表的特点

  1. 连续存储: 顺序表中的元素在内存中以连续的方式存储,这使得随机访问变得高效,可以通过索引快速访问任何元素。

  2. 固定容量: 顺序表的容量在创建时通常是固定的,即最大容量是预先定义好的。当顺序表达到最大容量时,无法再插入新元素,除非进行扩容操作。

  3. 动态长度:顺序表的长度可以随着元素的插入和删除而动态变化。

  4. 适合元素较少情况: 顺序表适用于元素数量不太多的情况。当元素数量较大时,可能需要频繁的扩容操作,影响性能。

  5. 适合随机访问: 由于元素的连续存储,顺序表非常适合随机访问,方便快速查找和拥有高效的查找速度

顺序表的运算 

顺序表支持多种常见的运算,包括:

  1. 初始化: 创建一个空的顺序表,设置长度为零。

  2. 插入元素: 在指定位置插入一个新元素,需要考虑位置的合法性和容量限制。

  3. 删除元素: 删除指定位置的元素,同样需要考虑位置的合法性。

  4. 查找元素: 根据元素值或位置查找元素。

  5. 判断是否为空: 检查顺序表是否为空。

  6. 判断是否已满: 检查顺序表是否已满。

  7. 获取长度: 获取顺序表中元素的数量。

  8. 遍历顺序表: 遍历顺序表中的所有元素。

  9. 扩容: 当顺序表达到最大容量时,可以进行扩容操作,以容纳更多元素。

  10. 销毁: 释放顺序表占用的内存,销毁顺序表。

  11. 其他操作: 根据具体需求,顺序表还可以支持其他操作,如排序、合并等。

顺序表的实现 

创建结构体

#define MaxSize 1000    // 先定义最大长度便于修改
#define InitialSize 10  // 初始顺序表大小
#define IncreaseSize 10 // 每次扩容的增量

typedef int DataType; // 为了语义化,将int数据类型重命名

typedef struct SeqList // 使用typedef重命名结构体便于使用
{
    DataType *data;
    int length;
    int maxsize;
} SeqList;

初始化顺序表

// 初始化顺序表
void initSeqList(SeqList *L)
{
    L->data = (DataType *)malloc(sizeof(DataType) * InitialSize);
    L->length = 0;
    L->maxsize = InitialSize;
}

插入元素 

// 插入元素
bool insertElement(SeqList *L, int position, DataType value)
{
    if (position < 1 || position > L->length + 1) // 检查插入位置是否合法
    {
        return false; // 插入位置无效
    }

    if (L->length >= L->maxsize) // 如果顺序表已满,扩容
    {
        DataType *newData = (DataType *)malloc(sizeof(DataType) * (L->maxsize + IncreaseSize));
        if (newData == NULL)
        {
            return false; // 内存分配失败
        }
        for (int i = 0; i < L->length; i++)
        {
            newData[i] = L->data[i];
        }
        free(L->data);              // 释放旧的内存
        L->data = newData;          // 更新数据指针
        L->maxsize += IncreaseSize; // 更新最大容量
    }

    // 将指定位置后的元素向后移动一个位置
    for (int i = L->length; i >= position; i--)
    {
        L->data[i] = L->data[i - 1];
    }

    // 插入新元素
    L->data[position - 1] = value;
    L->length++;

    return true;
}

 删除元素

// 删除元素
bool deleteElement(SeqList *L, int position, DataType *deletedValue)
{
    if (position < 1 || position > L->length)
    {
        return false; // 删除位置无效
    }

    // 保存被删除元素的值
    *deletedValue = L->data[position - 1];

    // 将指定位置后的元素向前移动一个位置
    for (int i = position; i < L->length; i++)
    {
        L->data[i - 1] = L->data[i];
    }

    L->length--;

    return true;
}

 判断顺序表是否为空

// 判断顺序表是否为空
bool isEmpty(SeqList *L)
{
    return L->length == 0;
}

判断顺序表是否满了

// 判断顺序表是否满
bool isFull(SeqList *L)
{
    return L->length == L->maxsize;
}

输出顺序表

// 输出顺序表
void printSeqList(SeqList *L)
{
    if (isEmpty(L))
    {
        printf("顺序表没有元素.\n");
    }
    else
    {
        printf("顺序表内容为: ");
        for (int i = 0; i < L->length; i++)
        {
            printf("%d ", L->data[i]);
        }
        printf("\n");
    }
}

 查找元素

// 查找元素
int find(SeqList *L, DataType value)
{
    for (int i = 0; i < L->length; i++)
    {
        if (L->data[i] == value)
        {
            return i + 1; // 找到了,返回位置
        }
    }
    return -1; // 未找到
}

顺序表demo

详细的实现代码如下

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define MaxSize 1000    // 先定义最大长度便于修改
#define InitialSize 10  // 初始顺序表大小
#define IncreaseSize 10 // 每次扩容的增量

typedef int DataType; // 为了语义化,将int数据类型重命名

typedef struct SeqList // 使用typedef重命名结构体便于使用
{
    DataType *data;
    int length;
    int maxsize;
} SeqList;

char welcome[] = "Welcome to my application";

// 初始化顺序表
void initSeqList(SeqList *L)
{
    L->data = (DataType *)malloc(sizeof(DataType) * InitialSize);
    L->length = 0;
    L->maxsize = InitialSize;
}

// 插入元素
bool insertElement(SeqList *L, int position, DataType value)
{
    if (position < 1 || position > L->length + 1) // 检查插入位置是否合法
    {
        return false; // 插入位置无效
    }

    if (L->length >= L->maxsize) // 如果顺序表已满,扩容
    {
        DataType *newData = (DataType *)malloc(sizeof(DataType) * (L->maxsize + IncreaseSize));
        if (newData == NULL)
        {
            return false; // 内存分配失败
        }
        for (int i = 0; i < L->length; i++)
        {
            newData[i] = L->data[i];
        }
        free(L->data);              // 释放旧的内存
        L->data = newData;          // 更新数据指针
        L->maxsize += IncreaseSize; // 更新最大容量
    }

    // 将指定位置后的元素向后移动一个位置
    for (int i = L->length; i >= position; i--)
    {
        L->data[i] = L->data[i - 1];
    }

    // 插入新元素
    L->data[position - 1] = value;
    L->length++;

    return true;
}

// 删除元素
bool deleteElement(SeqList *L, int position, DataType *deletedValue)
{
    if (position < 1 || position > L->length)
    {
        return false; // 删除位置无效
    }

    // 保存被删除元素的值
    *deletedValue = L->data[position - 1];

    // 将指定位置后的元素向前移动一个位置
    for (int i = position; i < L->length; i++)
    {
        L->data[i - 1] = L->data[i];
    }

    L->length--;

    return true;
}

// 判断顺序表是否为空
bool isEmpty(SeqList *L)
{
    return L->length == 0;
}

// 判断顺序表是否满
bool isFull(SeqList *L)
{
    return L->length == L->maxsize;
}

// 输出顺序表
void printSeqList(SeqList *L)
{
    if (isEmpty(L))
    {
        printf("顺序表没有元素.\n");
    }
    else
    {
        printf("顺序表内容为: ");
        for (int i = 0; i < L->length; i++)
        {
            printf("%d ", L->data[i]);
        }
        printf("\n");
    }
}

// 查找元素
int find(SeqList *L, DataType value)
{
    for (int i = 0; i < L->length; i++)
    {
        if (L->data[i] == value)
        {
            return i + 1; // 找到了,返回位置
        }
    }
    return -1; // 未找到
}

int main()
{
    SeqList myList;
    initSeqList(&myList);

    int command;
    DataType value;
    int position;
    DataType deletedValue;
    int i, m, n;

    for (i = 0; i < strlen(welcome); i++)
    {
        printf("%c", welcome[i]);
        for (m = 0; m < 10000; m++)
            for (n = 0; n < 10000; n++)
            {
                ;
            }
    }
    printf("\n\n\n");

    printf("顺序表演示程序\n");
    printf("1. 顺序表初始化\n");
    printf("2. 插入元素\n");
    printf("3. 删除元素\n");
    printf("4. 检查顺序表是否为空\n");
    printf("5. 检查顺序表是否已满\n");
    printf("6. 输出顺序表\n");
    printf("7. 查找元素\n");
    printf("10. 帮助\n");
    printf("0. 退出\n");

    while (1)
    {
        printf("输入指令: ");
        scanf("%d", &command);
        switch (command)
        {
        case 1:
            initSeqList(&myList);
            printf("顺序表初始化完成\n");
            break;

        case 2:
            printf("输入插入的位置和值,使用空格分开:");
            scanf("%d %d", &position, &value);

            if (insertElement(&myList, position, value))
            {
                printf("元素插入成功\n");
            }
            else
            {
                printf("插入失败!!!\n");
            }
            break;

        case 3:
            printf("输入需要删除的元素的位置: ");
            scanf("%d", &position);

            if (deleteElement(&myList, position, &deletedValue))
            {
                printf("已删除元素的值: %d\n", deletedValue);
            }
            else
            {
                printf("删除失败.\n");
            }
            break;

        case 4:
            if (isEmpty(&myList))
            {
                printf("顺序表是空的\n");
            }
            else
            {
                printf("顺序表不是空的\n");
            }
            break;

        case 5:
            if (isFull(&myList))
            {
                printf("顺序表已经满了\n");
            }
            else
            {
                printf("顺序表还未满.\n");
            }
            break;

        case 6:
            printSeqList(&myList);
            break;

        case 7:
            printf("输入需要查找的元素的值: ");
            scanf("%d", &value);
            position = find(&myList, value);
            if (position != -1)
            {
                printf("元素 %d 位于位置 %d\n", value, position);
            }
            else
            {
                printf("未找到元素 %d\n", value);
            }
            break;

        case 10:
            printf("本程序由陈勇豪制作\n");
            break;

        case 0:
            free(myList.data); // 释放动态分配的内存
            printf("退出程序.\n");
            return 0;

        default:
            printf("无效指令,请重新输入.\n");
            break;
        }
    }

    return 0;
}

 以下是运行结果截图

小结

这个C语言程序是一个简单的数字列表管理工具,用户可以初始化列表、添加、删除、查找、查看、判断是否为空或已满,以及自动扩容。程序的界面友好,通过输入数字指令即可执行各种操作,而动态内存分配确保了列表可以随需要自动扩展或收缩。这个程序可以帮助理解顺序表数据结构和内存管理的基本原理,为进一步学习和开发更复杂的应用奠定了基础。 

参考文献:《数据结构(C语言版)》李刚、刘万辉主编,高等教育出版社。OpenAI

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值