用C语言实现顺序表(数据结构)

线性表按其存储结构来分,可以分为顺序表和链表。
在这里插入图片描述


顺序表表中元素的逻辑顺序与物理顺序相同

顺序表的特点

  •  1.随机存取(主要),可在O(1)内找到指定的元素
    
  •  2.存储密度高
    
  •  3.插入和删除操作需要移动大量元素
    

C语言实现如下:

// 顺序表的最大长度
#define MaxSize 20

#define InitSize 20

// 静态分配
typedef struct 
{
   int data[MaxSize]; // 用静态"数组"存放数据元素
   int length; // 顺序表的当前长度(当前元素的个数)
 }SqList1;

// 动态分配
typedef struct 
{
    int *data; // 数据
    int MaxSize, length; // 数组的最大容量、当前元素个数
}SqList;

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


// 顺序表的初始长度

#define InitSize 20

// 动态分配
typedef struct 
{
    int *data; // 数据
    int MaxSize, length; // 数组的最大容量、当前元素个数
}SqList;

// 基本操作

/**
 * 初始化顺序表
 */
void InitList(SqList *L) 
{
    // 给结构体中的data分配内存空间
    L->data = (int *)malloc(sizeof(int) * InitSize);
    L->length = 0;
    L->MaxSize = InitSize;
}

/**
 * 增加顺序表的长度,动态扩容
 */
void IncreaseSize(SqList *L)
{
    int len;
    int *p = L->data; // p指针指向原来顺序表的首地址
    printf("请输入你要增加的顺序表的长度:\n");
    scanf("%d", &len);

    // 分配新的内存空间
    L->data = (int *)malloc(sizeof(int) * (L->MaxSize + len));

    // 把原来顺序表的元素复制到新的顺序表
    for (int i = 0; i < L->length; i++)
    {
        L->data[i] = p[i];
    }
    
    // 设置新的顺序表的最大长度
    L->MaxSize = L->MaxSize + len;

    // 释放原来的空间
    free(p);
  
}


/**
 * 插入一个元素
 */
bool ListInsert(SqList *L, int i, int e)
{
    // 1.涉及到位置的都要进行边界判断
    // 注意:这里的 i 表示位置,而不是下标,当i的值是[1,L->length+1]时,都是有效的插入位置。
    if (i < 1 || i > L->length+1)
    {
        return false;
    }

    // 2.判断当前的存储空间是否足够
    if (L->length >= L->MaxSize)
    {
        return false;
    }

    // 3.将第i个元素及之后的元素后移
    // 注意:数组下标从0开始,length个元素,最后一个元素的下标是length-1,所以j要从最后一个元素下标的后一个位置开始
    for (int j = L->length; j >= i; j--)
    {
        L->data[j] = L->data[j-1];
    }

    // 4.将待插入元素插入下标【i-1】处
    L->data[i-1] = e;
    
    // 5.将当前元素个数加1
    L->length++;
    return true;

}

/**
 * 删除某个位置的元素
 */
bool ListDelete(SqList *L, int i)
{
    // 1.判断位置是否合法 [1,L->length]
    if (i < 1 || i > L->length)
    {
        return false;
    }
    
    // 2.判断是否是空表
    if (!L->data)
    {
        return false;
    }
    
    // 3.删除: 将第i个位置之后的元素前移 [i,L->length-1]
    // 第i个元素下标为[i-1],所以 j 从下标[i]开始
    for (int j = i; j <= L->length-1 ; j++)
    {
        L->data[j-1] = L->data[j]; 
    }
    
    // 4.将当前元素个数减1
    L->length--;

    return true;
}

/**
 * 按值查找(顺序查找)
 * @return 该元素的位置(不是下标)
 */
int GetElement(SqList *L, int target)
{
    // 遍历整个线性表
    for (int i = 0; i < L->length; i++)
    {
        if (L->data[i] == target)
        {
            return i+1;
        }
    }
    
    return 0; // 返回0,说明查找失败
}

/**
 * 顺序表的销毁
 */
void DestroyList(SqList *L)
{
    char ch;
    printf("是否销毁顺序表(Y/N): ");
    scanf("%c", &ch);
    if (ch == 'Y')
    {
        L->length = 0;
        L->MaxSize = 0;
        free(L->data);
        printf("顺序表已成功销毁!");
    }
    
}

/**
 * 打印顺序表
 */
void PrintList(SqList *L)
{
    if (!L->data)
    {
      printf("该顺序表为空!");
      return;
    }
    for (int i = 0; i < L->length; i++)
    {
        printf("%d ", L->data[i]);
    }
    printf("\n");
    
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值