线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。
顺序表则是线性表的一种,是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
1. 静态顺序表:使用定长数组存储。
#define N 100
typedef struct SeqList
{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
2. 动态顺序表:使用动态开辟的数组存储。
typedef int SLDateType;
typedef struct Seqlist
{
SLDateType* a; //用于保存顺序表开始地址
int size; //当前长度
int limit; //总长度
}Seq;
显然动态更方便。
接口实现(增删查改):
1.初始化
void SeqListInit(Seq* ps) //初始化
{
assert(ps);
ps->a = NULL;
ps->limit = 0;
ps->size = 0;
}
2.销毁
void SeqListDestory(Seq* ps) //销毁
{
free(ps->a);
ps->a = NULL;
ps->limit = ps->size = 0;
}
3.打印
void SeqListPrint(Seq* ps) //打印
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size; i++)
{
printf("%d ", ps->a[i]);
}
}
4.扩容,当a为NULL时realloc和malloc的功能相同。
void SeqListMemorycheck(Seq* ps) //扩容
{
assert(ps);
if (ps->size == ps->limit) //扩容
{
int limit1 = ps->limit == 0 ? 4 : 2 * ps->limit; //第一个表达式进行检验,如果为真,则返回表达式2的值;如果为假,则返回表达式3的值。
SLDateType* newA = (SLDateType*)realloc(ps->a,limit1*sizeof(SLDateType)); //指针,个数 * 单位大小,当a为NULL时realloc和malloc的功能相同。
if (newA == NULL)
{
printf("扩容失败\n");
exit(-1);
}
else
{
ps->a = newA;
ps->limit = limit1;
}
}
}
5.尾插
void SeqListPushBack(Seq* ps, SLDateType n) //尾插
{
assert(ps);
SeqListMemorycheck(ps);
ps->a[ps->size] = n;
ps->size++;
}
6.头插
void SeqListPushFront(Seq* ps, SLDateType n) //头插
{
assert(ps);
SeqListMemorycheck(ps);
int i = ps->size - 1; //n个数字,下标= n-1
while (i >= 0) //等于0时也要进
{
ps->a[i + 1] = ps->a[i];
i--;
}
ps->a[0] = n;
ps->size++;
}
7.尾删
void SeqListDelBack(Seq* ps) //尾删
{
assert(ps);
ps->size--;
}
8.头删
void SeqListDelFront(Seq* ps) //头删
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size - 1; i++) //等于0时也要进
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
9.顺序表在pos位置插入x
void SeqListInsert(Seq* ps, size_t pos, SLDateType n) //顺序表在pos位置插入x
{
assert(ps);
SeqListMemorycheck(ps);
int i = ps->size - 1; //n个数字,下标= n-1
while (i >= pos - 1) //第pos个对应下标pos - 1
{
ps->a[i + 1] = ps->a[i];
i--;
}
ps->a[pos - 1] = n;
ps->size++;
}
10.顺序表删除pos位置的值
void SeqListErase(Seq* ps, size_t pos) // 顺序表删除pos位置的值
{
assert(ps);
for (int i = pos - 1; i < ps->size - 1; i++)
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
11.顺序表查找
int SeqListFind(Seq* ps, SLDateType n) // 顺序表查找
{
assert(ps);
for (int i = 0; i < ps->size - 1; i++)
{
if (ps->a[i] == n)
{
return i;
}
}
return -1;
}
下面给出完整代码:
1.Seqlist.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDateType; //给数据类型起了一个别名
typedef struct Seqlist
{
SLDateType* a; //用于保存顺序表开始地址
int size; //当前长度
int limit; //总长度
}Seq;
void SeqListInit(Seq* ps); //初始化
void SeqListPrint(Seq* ps); //打印
void SeqListDestory(Seq* ps); //销毁
void SeqListPushBack(Seq* ps, SLDateType n); //尾插
void SeqListPushFront(Seq* ps, SLDateType n); //头插
void SeqListDelBack(Seq* ps); //尾删
void SeqListDelFront(Seq* ps); //头删
void SeqListInsert(Seq* ps, size_t pos, SLDateType x); //顺序表在pos位置插入x
void SeqListErase(Seq* ps, size_t pos); // 顺序表删除pos位置的值
int SeqListFind(Seq* ps, SLDateType x); // 顺序表查找
2.Seqlist.c
#include"Seqlist.h"
void SeqListInit(Seq* ps) //初始化
{
assert(ps);
ps->a = NULL;
ps->limit = 0;
ps->size = 0;
}
void SeqListDestory(Seq* ps) //销毁
{
free(ps->a);
ps->a = NULL;
ps->limit = ps->size = 0;
}
void SeqListPrint(Seq* ps) //打印
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size; i++)
{
printf("%d ", ps->a[i]);
}
}
void SeqListMemorycheck(Seq* ps) //扩容
{
assert(ps);
if (ps->size == ps->limit) //扩容
{
int limit1 = ps->limit == 0 ? 4 : 2 * ps->limit; //第一个表达式进行检验,如果为真,则返回表达式2的值;如果为假,则返回表达式3的值。
SLDateType* newA = (SLDateType*)realloc(ps->a,limit1*sizeof(SLDateType)); //指针,个数 * 单位大小,当a为NULL时realloc和malloc的功能相同。
if (newA == NULL)
{
printf("扩容失败\n");
exit(-1);
}
else
{
ps->a = newA;
ps->limit = limit1;
}
}
}
void SeqListPushBack(Seq* ps, SLDateType n) //尾插
{
assert(ps);
SeqListMemorycheck(ps);
ps->a[ps->size] = n;
ps->size++;
}
void SeqListPushFront(Seq* ps, SLDateType n) //头插
{
assert(ps);
SeqListMemorycheck(ps);
int i = ps->size - 1; //n个数字,下标= n-1
while (i >= 0) //等于0时也要进
{
ps->a[i + 1] = ps->a[i];
i--;
}
ps->a[0] = n;
ps->size++;
}
void SeqListDelBack(Seq* ps) //尾删
{
assert(ps);
ps->size--;
}
void SeqListDelFront(Seq* ps) //头删
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size - 1; i++) //等于0时也要进
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
void SeqListInsert(Seq* ps, size_t pos, SLDateType n) //顺序表在pos位置插入x
{
assert(ps);
SeqListMemorycheck(ps);
int i = ps->size - 1; //n个数字,下标= n-1
while (i >= pos - 1) //第pos个对应下标pos - 1
{
ps->a[i + 1] = ps->a[i];
i--;
}
ps->a[pos - 1] = n;
ps->size++;
}
void SeqListErase(Seq* ps, size_t pos) // 顺序表删除pos位置的值
{
assert(ps);
for (int i = pos - 1; i < ps->size - 1; i++)
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
int SeqListFind(Seq* ps, SLDateType n) // 顺序表查找
{
assert(ps);
for (int i = 0; i < ps->size - 1; i++)
{
if (ps->a[i] == n)
{
return i;
}
}
return -1;
}
3.test.c
#include"Seqlist.h"
void TestSeqList1()
{
Seq s; //创建结构体
SeqListInit(&s); //初始化
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPushFront(&s, 0);
SeqListPushFront(&s, 0);
SeqListPushFront(&s, 0);
SeqListPushFront(&s, 0);
SeqListDelBack(&s);
SeqListDelFront(&s);
SeqListInsert(&s, 9, 4);
SeqListErase(&s, 5);
int ret = SeqListFind(&s, 1);
printf("%d\n", ret);
SeqListPrint(&s);
SeqListDestory(&s);
}
int main()
{
TestSeqList1(); //顺序表的增删查改
return 0;
}
以上就是本文所有内容,希望大家多多指正。

本文详细介绍了顺序表的概念及其两种实现方式——静态顺序表和动态顺序表,并提供了C语言实现顺序表的基本操作,包括初始化、销毁、打印、扩容、尾插、头插、尾删、头删、插入、删除和查找。代码示例展示了如何在顺序表中进行增删查改操作。
535

被折叠的 条评论
为什么被折叠?



