服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言深入浅出讲解顺序表的实现

C语言深入浅出讲解顺序表的实现

2022-11-09 14:38scut-ALong C/C++

线性表是最简单的数据结构,而顺序表又是最简单的线性表,其基本思想是用一段地址连续的储存单元依次存储线性表的数据元素,比如我们常用的一维数组,下面代码实现了顺序表的定义以及基本操作

今天起开始编写数据结构中的各种数据结构及算法的实现,说到顺序表,我们首先得了解下线性表。

1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

C语言深入浅出讲解顺序表的实现

2.顺序表

2.1 概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。顺序表一般可分为:

1.静态顺序表:使用定长数组存储。

2.动态顺序表:使用动态开辟的数组存储。

?
1
2
3
4
5
6
7
//顺序表的静态存储
#define N 100
struct SeqList
{
    int a[N];//定长存储
    int size;//有效数据的个数
};
?
1
2
3
4
5
6
7
//顺序表的动态存储
typedef struct SeqList
{
    SeqDataType* a;//指向动态开辟的数组
    int size;     //有效数据个数
    int capacity; //容量
}SeqList;

顺序表本质上是数组,在数组上增加了两个要求:

1.插入数据的过程中,可以动态增长

2.并且要求里面存储的数据必须是从左往右,是连续的

顺序表的缺陷

1.动态增容有性能消耗

2.头部插入数据时,需要挪动数据

2.2 提供接口

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们来实现动态顺序表。

首先在头文件<SeqList.h>中提供接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
typedef int SeqDataType; //需要插入什么类型的数据,就改成对应类型
 
typedef struct SeqList
{
    SeqDataType* a;//指向动态开辟的数组
    int size;     //有效数据个数
    int capacity; //容量
}SeqList;
 
//内存中管理数据结构 提供增删查改的接口
//顺序表初始化
void SeqListInit(SeqList* pq);
//顺序表销毁
void SeqListDestory(SeqList* pq);
//顺序表打印
void SeqListPrint(SeqList* pq);//打印数组
//检查空间,如果满了,进行增容
void SeqCheckCapacity(SeqList* pq)
//顺序表尾插
void SeqListPushBack(SeqList* pq, SeqDataType x);
//顺序表头插
void SeqListPushFront(SeqList* pq, SeqDataType x);
//顺序表尾删
void SeqListPopBack(SeqList* pq);
//顺序表头删
void SeqListPopFront(SeqList* pq);
//顺序表查找x
int SeqListFind(SeqList* pq, SeqDataType x);//查找 查到返回下标,没查到返回-1
//顺序表在指定位置插入数据
void SeqListInsert(SeqList* pq, int pos, SeqDataType x);//在下标pos位置处插入数据
//顺序表在指定位置删除数据
void SeqListErase(SeqList* pq, int pos);//把下标为pos位置处的数据删除
//顺序表在指定位置替换数据
void SeqListModify(SeqList* pq, int pos, SeqDataType x);//把小标为pos位置的值改为x

2.3 接口实现

在源文件SeqList.c中实现接口功能

(1)顺序表初始化

?
1
2
3
4
5
6
7
void SeqListInit(SeqList* pq)
{
    assert(pq != NULL);//或者 assert(pq); 断言 防止传入空指针
    pq->a = NULL;
    pq->size = 0;
    pq->capacity = 0;
}

(2)顺序表销毁

?
1
2
3
4
5
6
7
8
void SeqListDestory(SeqList* pq)
{
    assert(pq);
    free(pq->a);
    pq->a = NULL;
    pq->size = 0;
    pq->capacity = 0;
}

(3)顺序表打印

?
1
2
3
4
5
6
7
8
9
void SeqListPrint(SeqList* pq)
{
    assert(pq);
    for (int i = 0; i < pq->size; ++i)
    {
        printf("%d ", pq->a[i]);
    }
    printf("\n");
}

(4)检查空间,如果满了,进行增容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//检查是否需要扩容
void SeqCheckCapacity(SeqList* pq)
{
    //满了,需要增容
    if (pq->size == pq->capacity)
    {
        int newcapacity = (pq->capacity == 0 ? 4 : pq->capacity * 2);
 
        //realloc接收的地址如果为空,将像malloc一样,开辟一块新空间
        SeqDataType* newA = realloc(pq->a, sizeof(SeqDataType) * newcapacity);//realloc返回 开辟的新空间的地址
        if (newA == NULL)
        {
            printf("realloc fail\n");
            exit(-1);//失败了就退出
        }
        pq->a = newA;
        pq->capacity = newcapacity;
    }
}

(5)顺序表尾插

?
1
2
3
4
5
6
7
8
9
void SeqListPushBack(SeqList* pq, SeqDataType x)//尾插
{
    assert(pq);
 
    SeqCheckCapacity(pq);
 
    pq->a[pq->size] = x;
    pq->size++;
}

(6)顺序表头插

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void SeqListPushFront(SeqList* pq, SeqDataType x)
{
    assert(pq);
 
    SeqCheckCapacity(pq);
 
    int end = pq->size - 1;
    while (end >= 0)
    {
        pq->a[end + 1] = pq->a[end];
        end--;
    }
    pq->a[0] = x;
    pq->size++;
}

(7)顺序表尾删

?
1
2
3
4
5
6
void SeqListPopBack(SeqList* pq)
{
    assert(pq);
    assert(pq->size > 0);
    pq->size--;
}

(8)顺序表头删

?
1
2
3
4
5
6
7
8
9
10
11
12
13
void SeqListPopFront(SeqList* pq)
{
    assert(pq);
    assert(pq->size > 0);
 
    int begin = 0;
    while (begin < pq->size - 1)
    {
        pq->a[begin] = pq->a[begin + 1];
        begin++;
    }
    pq->size--;
}

(9)顺序表查找x

?
1
2
3
4
5
6
7
8
9
10
11
12
int SeqListFind(SeqList* pq, SeqDataType x)
{
    assert(pq);
    for (int i = 0; i < pq->size; ++i)
    {
        if (pq->a[i] == x)
        {
            return x;
        }
    }
    return -1;//没找到
}

(10)顺序表在指定位置插入数据

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void SeqListInsert(SeqList* pq, int pos, SeqDataType x){<!--{C}%3C!%2D%2D%20%2D%2D%3E-->assert(pq);assert(pos >= 0 && pos < pq->size);SeqCheckCapacity(pq);//检查是否需要扩容int end = pq->size - 1;while (end >= pos){<!--{C}%3C!%2D%2D%20%2D%2D%3E-->pq->a[end + 1] = pq->a[end];end--;}pq->a[pos] = x;pq->size++;}void SeqListInsert(SeqList* pq, int pos, SeqDataType x)
{
    assert(pq);
    assert(pos >= 0 && pos < pq->size);
 
    SeqCheckCapacity(pq);//检查是否需要扩容
 
    int end = pq->size - 1;
    while (end >= pos)
    {
        pq->a[end + 1] = pq->a[end];
        end--;
    }
    pq->a[pos] = x;
    pq->size++;
}

(11)顺序表在指定位置删除数据

?
1
2
3
4
5
6
7
8
9
10
11
12
void SeqListErase(SeqList* pq, int pos)
{
    assert(pq);
    assert(pos >= 0 && pos < pq->size);
    int begin = pos;
    while (begin <= pq->size - 1)
    {
        pq->a[begin] = pq->a[begin + 1];
        begin++;
    }
    pq->size--;
}

(12)顺序表在指定位置替换数据

?
1
2
3
4
5
6
7
void SeqListModify(SeqList* pq, int pos, SeqDataType x)
{
    assert(pq);
    assert(pos >= 0 && pos < pq->size);
 
    pq->a[pos] = x;
}

主函数的设计大家可以自由发挥,做个简单的测试功能调用函数或是创建菜单栏实现交互都可以。我水平有限,请朋友们谅解!写的不好的地方还请大佬们指出。

下期预告——单链表

到此这篇关于C语言深入浅出讲解顺序表的实现的文章就介绍到这了,更多相关C语言 顺序表内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_43460230/article/details/124160112

延伸 · 阅读

精彩推荐
  • C/C++C语言圣诞树的实现示例

    C语言圣诞树的实现示例

    本篇主要介绍了C语言圣诞树的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    补集王子7742022-07-16
  • C/C++C语言实现贪吃蛇小黑窗

    C语言实现贪吃蛇小黑窗

    这篇文章主要为大家详细介绍了C语言实现贪吃蛇小黑窗,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    元灵石胎4932022-08-08
  • C/C++C语言文件复制实例详解

    C语言文件复制实例详解

    这篇文章主要介绍了C语言文件复制实例详解的相关资料,需要的朋友可以参考下...

    CSDN4662021-05-20
  • C/C++C++中四种加密算法之DES源代码

    C++中四种加密算法之DES源代码

    本篇文章主要介绍了C++中四种加密算法之DES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    kynge1367372021-04-20
  • C/C++C++二分查找算法实例

    C++二分查找算法实例

    这篇文章主要为大家详细介绍了C++二分查找算法的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    ^~~^11092021-05-29
  • C/C++C语言sizeof和strlen的指针和数组面试题详解

    C语言sizeof和strlen的指针和数组面试题详解

    strlen是函数,字符串长度,不包括停止符。而sizeof则是内存块的大小,包括停止符。数组是一种数据类型,数据类型的本质就是固定大小,内存块的别名。...

    scut-ALong4152022-11-07
  • C/C++C语言高斯消元法的使用详解

    C语言高斯消元法的使用详解

    本篇文章是对C语言中高斯消元法的使用进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网4722020-11-29
  • C/C++C语言 超详细讲解算法的时间复杂度和空间复杂度

    C语言 超详细讲解算法的时间复杂度和空间复杂度

    算法复杂度分为时间复杂度和空间复杂度。其作用: 时间复杂度是度量算法执行的时间长短;而空间复杂度是度量算法所需存储空间的大小...

    天影云光3392022-10-28