数据结构 (一)顺序表

本文详细介绍了顺序表的存储结构、初始化、插入元素、删除元素、查找元素以及更改元素的操作。顺序表利用数组实现,通过动态内存分配和realloc()函数来扩展存储空间。代码示例展示了如何在C语言中实现这些基本操作。
摘要由CSDN通过智能技术生成

一、顺序存储结构

顺序表,全名顺序存储结构,是线性表的一种。
线性表用于存储逻辑关系为“一对一”的数据,顺序表自然也不例外。

顺序表存储数据时,会提前申请一整块足够大小的物理空间,然后将数据依次存储起来,存储时做到数据元素之间不留一丝缝隙。

例如,使用顺序表存储集合 {1,2,3,4,5},数据最终的存储状态如图 1 所示:
在这里插入图片描述
由此我们可以得出,将“具有 ‘一对一’ 逻辑关系的数据按照次序连续存储到一整块物理空间上”的存储结构就是顺序存储结构。
通过观察图 1 中数据的存储状态,我们可以发现,顺序表存储数据同数组非常接近。其实,顺序表存储数据使用的就是数组。

二、顺序表的初始化

使用顺序表存储数据之前,先定义一个结构体:
1.申请足够大小的物理空间;
2. 顺序表的长度,也就是表中存储数据元素的个数;
3. 顺序表申请的存储容量;

一般来说(顺序表申请的存储容量要大于表中存储数据元素的个数)

typedef struct{
    int *head; //声明了一个名为 head 的长度不确定的数组,也叫“动态数组”
    int length; //记录表中存储数据元素的个数
    int size; //记录顺序表分配的存储容量
}tabel;

#define Size 5
tabel initTable()
{
    tabel t;
    t.head = (int *)malloc(Size*sizeof(int));
    if(!t.head)
    {
        printf("初始化失败");
        exit(0);
    }
    t.length = 0;
    t.size = Size;
    return t;
}

运行结果:
在这里插入图片描述

三、顺序表插入元素

1.判断插入是否有问题
2.做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
3.插入操作,需要将从插入位置开始的后续元素,逐个后移
4.后移完成后,直接将所需插入元素,添加到顺序表的相应位置

例如,在 {1,2,3,4,5} 的第 3 个位置上插入元素 6,实现过程如下:

在这里插入图片描述

//插入函数,其中place 为插入到顺序表的位置 ,data 为插入的元素
tabel addTabel(tabel t,int place,int data)
{
    //判断插入是否有问题
    if(place>t.length+1 ||place <0 )
    {
        printf("插入的位置有问题\n");
        return t;
    }
    //做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
    if(t.length >= t.size)
    {
        t.head = (int *)realloc(t.head,(t.size+1)*sizeof(int));
        if(t.head == NULL)
        {
            printf("存储分配失败\n");
            return t;
        }
        t.size++;
    }
    //插入操作,需要将从插入位置开始的后续元素,逐个后移
    for(int i=t.length-1;i>=place-1;i--)
    {
        t.head[i+1] = t.head[i];
    }
    //后移完成后,直接将所需插入元素,添加到顺序表的相应位置
    t.head[place-1] = data;
    t.length++; 
    return t;
}

运行结果:
在这里插入图片描述

四、顺序表删除元素

1.判断删除的元素的位置是否正确
2.执行删除操作

从顺序表中删除指定元素,实现起来非常简单,只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。
后续元素整体前移一个位置,会直接将目标元素删除,可间接实现删除元素的目的
在这里插入图片描述

// 顺序表删除元素
tabel delTabel(tabel t,int place)
{
    //1.判断删除的元素的位置是否正确
    if(place>t.length || place<0)
    {
        printf("被删除的元素的位置有误!\n");
        return t;
    }
    //2.执行删除操作
    for(int i=place;i<t.length;i++)
    {
        t.head[i-1] = t.head[i];
    }
    t.length --;
    return t;
}

在这里插入图片描述

五、顺序表查找元素,返回元素位置

//查找函数,其中,data 表示要查找的数据元素的值
//如果查找成功返回元素的位置
int findTabel(tabel t,int data)
{
    for(int i=0;i<t.length;i++)
    {
        if(t.head[i] == data)
        {
            return i+1;
        }
    }
    return -1;//如果查找失败,返回-1
}

在这里插入图片描述

六、顺序更改元素

// 顺序表更改元素的实现过程是:
// 1. 找到目标元素;
// 2. 直接修改该元素的值;

tabel changeTabel(tabel t,int data,int newdata)
{

    int place;//定义需要修改元素的位置,先查找到元素
    place = findTabel(t,data);
    t.head[place-1] = newdata;//由于返回的是元素在顺序表中的位置,所以place-1 就是该元素在数组中的下标
    return t;
}

在这里插入图片描述

七、完整顺序表的代码

#include <stdio.h>
#include <stdlib.h>
//顺序表的初始化

// 使用顺序表存储数据之前,先定义一个结构体
// 1.申请足够大小的物理空间之外,
// 2.顺序表的长度,也就是表中存储数据元素的个数;
// 3.顺序表申请的存储容量;

//(提示:正常状态下,顺序表申请的存储容量要大于顺序表的长度。)
typedef struct{
    int *head; //声明了一个名为 head 的长度不确定的数组,也叫“动态数组”
    int length; //记录表中存储数据元素的个数
    int size; //记录顺序表分配的存储容量
}tabel;

#define Size 5
tabel initTable()
{
    tabel t;
    t.head = (int *)malloc(Size*sizeof(int));
    if(!t.head)
    {
        printf("初始化失败");
        exit(0);
    }
    t.length = 0;
    t.size = Size;
    return t;
}

//插入函数,其中place 为插入到顺序表的位置 ,data 为插入的元素
tabel addTabel(tabel t,int place,int data)
{
    //判断插入是否有问题
    if(place>t.length+1 ||place <0 )
    {
        printf("插入的位置有问题\n");
        return t;
    }
    //做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
    if(t.length >= t.size)
    {
        t.head = (int *)realloc(t.head,(t.size+1)*sizeof(int));
        if(t.head == NULL)
        {
            printf("存储分配失败\n");
            return t;
        }
        t.size++;
    }
    //插入操作,需要将从插入位置开始的后续元素,逐个后移
    for(int i=t.length-1;i>=place-1;i--)
    {
        t.head[i+1] = t.head[i];
    }
    //后移完成后,直接将所需插入元素,添加到顺序表的相应位置
    t.head[place-1] = data;
    t.length++; 
    return t;
}

// 顺序表删除元素
tabel delTabel(tabel t,int place)
{
    //1.判断删除的元素的位置是否正确
    if(place>t.length || place<0)
    {
        printf("被删除的元素的位置有误!\n");
        return t;
    }
    //2.执行删除操作
    for(int i=place;i<t.length;i++)
    {
        t.head[i-1] = t.head[i];
    }
    t.length --;
    return t;
}

//查找函数,其中,data 表示要查找的数据元素的值
//如果查找成功返回元素的位置
int findTabel(tabel t,int data)
{
    for(int i=0;i<t.length;i++)
    {
        if(t.head[i] == data)
        {
            return i+1;
        }
    }
    return -1;//如果查找失败,返回-1
}

// 顺序表更改元素的实现过程是:
// 1. 找到目标元素;
// 2. 直接修改该元素的值;
tabel changeTabel(tabel t,int data,int newdata)
{

    int place;//定义需要修改元素的位置,先查找到元素
    place = findTabel(t,data);
    t.head[place-1] = newdata;//由于返回的是元素在顺序表中的位置,所以place-1 就是该元素在数组中的下标
    return t;
}

void displayTable(tabel t)
{
    for(int i=0;i<t.length;i++)
    {
        printf("%d ",t.head[i]);
    }
    printf("\n");
}

int main()
{
    tabel t;
    int i;
    t = initTable();
    //向顺序表中添加元素组
    for(i=0;i<Size;i++)
    {
        t.head[i] = i+1;
        t.length++;
    }
    printf("顺序表中存储的元素分别是:\n");
    displayTable(t);

    //向顺序表元素
    printf("向顺序表中第3个位置插入元素6\n");
    t = addTabel(t,3,6);
    displayTable(t);

    //向顺序表中删除元素
    printf("删除第3个位置上的元素:\n");
    t = delTabel(t,3);
    displayTable(t);

    //查找
    printf("查找元素3的位置:%d\n",findTabel(t,3));
    
    //更改元素
    printf("将元素4更改为元素6\n");
    t = changeTabel(t,4,6);
    displayTable(t);
    //申请内存要释放掉,不然会造成内存泄露
	free(t.head);
    return 0;
}


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值