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

概念

顺序表是由一组元素组成的线性集合,这些元素按照一定的顺序排列,每个元素都有一个确定的位置。在顺序表中,元素之间的关系是一对一的关系,即除了第一个和最后一个元素外,每个元素都有唯一的前驱和后继。

数据存储

顺序表通常采用数组来实现。这意味着所有元素都存储在连续的内存地址中。数组的索引或下标用于访问顺序表中的元素。例如,一个包含5个元素的顺序表可以表示为 array[0...4]

特性

  1. 顺序性:顺序表中的元素是按照一定的顺序存储的,可以是递增或递减,也可以是其他特定的顺序。
  2. 随机访问:由于元素在内存中连续存储,可以通过索引直接访问任何一个元素,访问时间复杂度为O(1)。
  3. 固定容量:对于静态顺序表,其容量在创建时确定,之后不可更改。动态顺序表则可以在需要时扩展容量。

基本操作

以下是一些顺序表的基本操作:

初始化:创建一个空的顺序表,并为其分配初始容量

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 创建一个空的顺序表
seqlist_p CreatEpSeqlist() 
{
    seqlist_p p = (seqlist_p)malloc(sizeof(seqlist_t));
    if (NULL == p)
    {
        perror("malloc lost"); // perror打印上一个函数报的错误
        return NULL;           // 错误情况让函数返回空指针
    }
    // 对结构体初始化
    p->last = -1;//当数组为空时下标为-1
    return p;
}

插入:在顺序表的指定位置插入一个新元素

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 向顺序表的指定位置插入一个元素
int InsertSeqlist(seqlist_p p, int post, int data) 
{
    // 容错判断:判断数组空间是否足够,对post判断
    if (IsFullSeqlist(p) || post < 0 || post > p->last + 2)
    {
        printf("error\n");
        return -1; // 错误返回
    }
    else
    {
        int i = p->last;
        while (i >= post-1)
        {
            p->data[i + 1] = p->data[i];
            i--;
        }
        p->data[post-1] = data;
        p->last++;
    }
    return 0;
}

删除:删除顺序表中指定位置的元素

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 删除顺序表指定位置的元素
int DeleteSeqlist(seqlist_p p, int post) 
{
    // 容错判断:判断数组空间是否,对post判断
    if (IsEpSeqlist(p)||post < 0 || post >= p->last + 2)
    {
        printf("error\n");
        return -1; // 错误返回
    }
    else
    {
        int i = post - 1;
        while (i < p->last)
        {
            p->data[i] = p->data[i + 1];
            i++;
        }
        p->last--;
    }
    return 0;
}

查找:在顺序表中查找特定的元素,并返回其位置

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
//查找指定数据出现的位置,返回下标,未找到返回-1
int SerchSqelist(seqlist_p p, int data)
{
    for(int i=0;i<=p->last;i++)
    {
            if(p->data[i]==data)
                return i;
    }
    return -1;
}

修改:修改顺序表中指定位置的元素值

#include <stdio.h>
#include <stdlib.h>
#include "head.h"
// 修改顺序表指定位置的元素
int ChangeSeqlist(seqlist_p p, int post, int data)
{
    // 容错判断:判断数组空间是否为空,对post判断
    if (IsEpSeqlist(p) || post < 0 || post >= p->last + 2)
    {
        perror("error");
        return -1; // 错误返回
    }
    else
    {
        p->data[post - 1] = data;
    }
    return 0;
}

遍历:循环遍历顺序表

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 循环遍历顺序表
void show(seqlist_p p) 
{
    for (int i = 0; i <= p->last; i++)
    {
        printf("%d ", p->data[i]);
    }
    printf("\n");
}

优缺点

优点

  • 随机访问能力强,访问任何一个元素的时间复杂度都是O(1)。
  • 存储密度高,不需要额外空间存储节点间关系。

缺点

  • 插入和删除操作需要移动大量元素,时间复杂度为O(n)。
  • 静态顺序表长度固定,可能导致空间浪费或不足。
  • 动态顺序表在扩容时可能需要复制整个数组,效率较低。

代码示例:

头文件

#define N 10
typedef struct seqlist // 封装顺序表结构体类型
{
    int data[N]; // 存储数据的数组
    int last;    // 数组中最后一个有效元素的下标
} seqlist_t, *seqlist_p;

seqlist_p CreatEpSeqlist() ;
int IsFullSeqlist(seqlist_p p);
int IsEpSeqlist(seqlist_p p);
int InsertSeqlist(seqlist_p p, int post, int data) ;
int DeleteSeqlist(seqlist_p p, int post) ;
int SerchSqelist(seqlist_p p, int data);
int ChangeSeqlist(seqlist_p p, int post,int data) ;
void show(seqlist_p p) ;

 容错判断

#include <stdio.h>
#include<stdlib.h>
#include"head.h"

// 判断顺序表是否为满,满返回1,未满返回0
int IsFullSeqlist(seqlist_p p)
{
    return p->last + 1 == N;//return 1
}

// 判断顺序表是否为空,空返回1,非空返回0
int IsEpSeqlist(seqlist_p p)
{
    return p->last == -1;//return 1
}

 创建空顺序表

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 创建一个空的顺序表
seqlist_p CreatEpSeqlist() 
{
    seqlist_p p = (seqlist_p)malloc(sizeof(seqlist_t));
    if (NULL == p)
    {
        perror("malloc lost"); // perror打印上一个函数报的错误
        return NULL;           // 错误情况让函数返回空指针
    }
    // 对结构体初始化
    p->last = -1;//当数组为空时下标为-1
    return p;
}

在指定位置插入元素

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 向顺序表的指定位置插入一个元素
int InsertSeqlist(seqlist_p p, int post, int data) 
{
    // 容错判断:判断数组空间是否足够,对post判断
    if (IsFullSeqlist(p) || post < 0 || post > p->last + 2)
    {
        printf("error\n");
        return -1; // 错误返回
    }
    else
    {
        int i = p->last;
        while (i >= post-1)
        {
            p->data[i + 1] = p->data[i];
            i--;
        }
        p->data[post-1] = data;
        p->last++;
    }
    return 0;
}

删除指定位置的元素

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 删除顺序表指定位置的元素
int DeleteSeqlist(seqlist_p p, int post) 
{
    // 容错判断:判断数组空间是否,对post判断
    if (IsEpSeqlist(p)||post < 0 || post >= p->last + 2)
    {
        printf("error\n");
        return -1; // 错误返回
    }
    else
    {
        int i = post - 1;
        while (i < p->last)
        {
            p->data[i] = p->data[i + 1];
            i++;
        }
        p->last--;
    }
    return 0;
}

修改指定位置的元素

#include <stdio.h>
#include <stdlib.h>
#include "head.h"
// 修改顺序表指定位置的元素
int ChangeSeqlist(seqlist_p p, int post, int data)
{
    // 容错判断:判断数组空间是否为空,对post判断
    if (IsEpSeqlist(p) || post < 0 || post >= p->last + 2)
    {
        perror("error");
        return -1; // 错误返回
    }
    else
    {
        p->data[post - 1] = data;
    }
    return 0;
}

查找指定数据出现的位置

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
//查找指定数据出现的位置,返回下标,未找到返回-1
int SerchSqelist(seqlist_p p, int data)
{
    for(int i=0;i<=p->last;i++)
    {
            if(p->data[i]==data)
                return i;
    }
    return -1;
}

循环遍历顺序表

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
// 循环遍历顺序表
void show(seqlist_p p) 
{
    for (int i = 0; i <= p->last; i++)
    {
        printf("%d ", p->data[i]);
    }
    printf("\n");
}

main.c主函数

#include <stdio.h>
#include<stdlib.h>
#include"head.h"
int main(int argc, char const *argv[])
{
    seqlist_p p = CreatEpSeqlist(); // 定义一个结构体类型的指针接收函数的返回值
    InsertSeqlist(p, 1, 1);
    InsertSeqlist(p, 2, 2);
    InsertSeqlist(p, 3, 3);
    show(p);
    DeleteSeqlist(p,2);
    show(p);
    ChangeSeqlist(p,1,0);
    show(p);
    printf("%d\n",SerchSqelist(p,3));
    return 0;
}

 程序运行结果

1 2 3 
1 3 
0 3 
1
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
顺序表是一种线性表,它的物理存储结构是连续的。在 C 语言中,可以用数组来实现顺序表。以下是一个简单的顺序表的 C 语言实现: ```c #include <stdio.h> #define MAXSIZE 100 // 定义顺序表的最大长度 typedef struct { int data[MAXSIZE]; // 存储数据元素的数组 int length; // 当前顺序表的长度 } SeqList; // 初始化顺序表 void InitList(SeqList *L) { L->length = 0; } // 获取顺序表中指定位置的元素 int GetElem(SeqList L, int i) { if (i < 1 || i > L.length) { printf("Error: index out of range.\n"); return -1; } return L.data[i-1]; } // 在顺序表中插入元素 void ListInsert(SeqList *L, int i, int e) { int j; if (L->length == MAXSIZE) { printf("Error: list is full.\n"); return; } if (i < 1 || i > L->length+1) { printf("Error: index out of range.\n"); return; } for (j = L->length; j >= i; j--) { L->data[j] = L->data[j-1]; } L->data[i-1] = e; L->length++; } // 删除顺序表中指定位置的元素 void ListDelete(SeqList *L, int i) { int j; if (i < 1 || i > L->length) { printf("Error: index out of range.\n"); return; } for (j = i; j < L->length; j++) { L->data[j-1] = L->data[j]; } L->length--; } // 输出顺序表中的元素 void PrintList(SeqList L) { int i; for (i = 0; i < L.length; i++) { printf("%d ", L.data[i]); } printf("\n"); } int main() { SeqList L; InitList(&L); ListInsert(&L, 1, 1); ListInsert(&L, 2, 2); ListInsert(&L, 3, 3); ListInsert(&L, 4, 4); ListInsert(&L, 5, 5); PrintList(L); ListDelete(&L, 3); PrintList(L); printf("%d\n", GetElem(L, 2)); return 0; } ``` 在这个例子中,我们定义了一个结构体 `SeqList`,其中包含一个数组 `data` 和一个表示顺序表长度的变量 `length`。然后我们定义了一些操作函数来对顺序表进行初始化、插入、删除、获取元素和输出顺序表的元素。在 `main()` 函数中,我们创建了一个顺序表 `L`,并对它进行了一些操作,最后输出了结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值