在介绍顺序表之前,我们需要知道线性表的定义。
线性表是由n个具有相同特征的数据元素的有限序列,是最常用的一种数据结构。
一个数据元素可以有若干个数据项组成(数据项是数据的不可分割的最小单元),
这时,我们常把数据元素(在数据结构中,数据的基本单位是数据项)称为记录,含有大量记录的线性表又称为文件
顺序表是线性表的一种实现方式,需要用一组地址连续的存储单元一次存储线性表。(类似与数组)
优点:容易查找和修改(时间复杂度为N(1))
缺点:增加和删除需要移动其他元素(尾部增删是特殊个例,这里需要统计所有情况)
时间复杂度为N(n)
需要一组连续的地址
内存可能存在不足或者浪费情况
在使用之前,我们需要定义顺序表
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
SLDateType size; //有效数据
SLDateType capacity; //空间容量
}SeqList;
并且将常用函数列举(方便后面书写)
// 对数据的管理:增删查改
//初始化
void SeqListInit(SeqList* ps);
//销毁
void SeqListDestroy(SeqList* ps);
//打印
void SeqListPrint(SeqList* ps);
//尾插
void SeqListPushBack(SeqList* ps, SLDateType x);
//头插
void SeqListPushFront(SeqList* ps, SLDateType x);
//头删
void SeqListPopFront(SeqList* ps);
//尾删
void SeqListPopBack(SeqList* ps);
// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
然后实现各个函数的功能
在使用函数时,我们必须确保顺序表已经存在,不为空(增加可以不用考虑),以及顺序表的内存是否够用(增加会增大线性表的存储大小),所以我们对顺序表先进行初始化,然后进行增删查改等操作,使用完后需要将它销毁(否则会造成内存泄漏)
void SeqListInit(SeqList* ps)
{
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
void SeqListDestroy(SeqList* ps)
{
if (ps->a != NULL)
{
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->size = 0;
}
}
void SeqListPrint(SeqList* ps)
{
if (ps->a == NULL)
return;
for (int i = 0; i < ps->size; ++i)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
void SeqListPushBack(SeqList* ps, SLDateType x)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 3 : ps->capacity * 2;
SLDateType* tmp = (SLDateType*) realloc(ps->a, sizeof(SLDateType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->size] = x;
ps->size++;
}
void SeqListPushFront(SeqList* ps, SLDateType x)
{
if (ps->a == NULL)
return;
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 3 : ps->capacity * 2;
SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
--end;
}
ps->a[0] = x;
++ps->size;
}
void SeqListPopFront(SeqList* ps, SLDateType x)
{
if (ps->size == 0)
{
return;
}
if (ps->a == NULL)
return;
if (ps->size < x)
x = ps->size;
int star = 1;
int end = ps->size - 1;
while (star < x)
{
ps->a[star-1] = ps->a[star+x-1];
++star;
--end;
}
ps->size = end;
}
void SeqListPopBack(SeqList* ps, SLDateType x)
{
if (ps->size == 0)
{
return;
}
if (ps->a == NULL)
return;
if (ps->size < x)
{
x = ps->size;
}
for (int i = x; i > 0; i--)
{
ps->a[ps->size-1] = 0;
--ps->size;
}
}
int SeqListFind(SeqList* ps, SLDateType x)
{
if (ps->a == NULL)
return ERROR;
int n = ps->size;
for (int i = 0; i < n; i++)
{
if (ps->a[i] == x)
printf("%d \n", i);
}
return FALSE;
}
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
if (ps->a == NULL || ps->size == 0 || pos < 0 || pos > ps->size)
return;
int end = ps->size;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
--end;
}
ps->a[pos] = x;
++ps->size;
}
void SeqListErase(SeqList* ps, int pos)
{
if (ps->a == NULL)
return;
int end = ps->size;
while (end > pos)
{
ps->a[pos] = ps->a[pos+1];
++pos;
}
--ps->size;
}
完整代码如下:
test.h
#pragma once
#include <iostream>
#include <assert.h>
#include <stdlib.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define ERROR 0
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
SLDateType size; //有效数据
SLDateType capacity; //空间容量
}SeqList;
// 对数据的管理:增删查改
//初始化
void SeqListInit(SeqList* ps);
//销毁
void SeqListDestroy(SeqList* ps);
//打印
void SeqListPrint(SeqList* ps);
//尾插
void SeqListPushBack(SeqList* ps, SLDateType x);
//头插
void SeqListPushFront(SeqList* ps, SLDateType x);
//头删
void SeqListPopFront(SeqList* ps);
//尾删
void SeqListPopBack(SeqList* ps);
// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
test.cpp
#include"test.h"
void SeqListInit(SeqList* ps)
{
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
void SeqListDestroy(SeqList* ps)
{
if (ps->a != NULL)
{
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->size = 0;
}
}
void SeqListPrint(SeqList* ps)
{
if (ps->a == NULL)
return;
for (int i = 0; i < ps->size; ++i)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
void SeqListPushBack(SeqList* ps, SLDateType x)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 3 : ps->capacity * 2;
SLDateType* tmp = (SLDateType*) realloc(ps->a, sizeof(SLDateType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->size] = x;
ps->size++;
}
void SeqListPushFront(SeqList* ps, SLDateType x)
{
if (ps->a == NULL)
return;
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 3 : ps->capacity * 2;
SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
--end;
}
ps->a[0] = x;
++ps->size;
}
void SeqListPopFront(SeqList* ps, SLDateType x)
{
if (ps->size == 0)
{
return;
}
if (ps->a == NULL)
return;
if (ps->size < x)
x = ps->size;
int star = 1;
int end = ps->size - 1;
while (star < x)
{
ps->a[star-1] = ps->a[star+x-1];
++star;
--end;
}
ps->size = end;
}
void SeqListPopBack(SeqList* ps, SLDateType x)
{
if (ps->size == 0)
{
return;
}
if (ps->a == NULL)
return;
if (ps->size < x)
{
x = ps->size;
}
for (int i = x; i > 0; i--)
{
ps->a[ps->size-1] = 0;
--ps->size;
}
}
int SeqListFind(SeqList* ps, SLDateType x)
{
if (ps->a == NULL)
return ERROR;
int n = ps->size;
for (int i = 0; i < n; i++)
{
if (ps->a[i] == x)
printf("%d \n", i);
}
return FALSE;
}
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
if (ps->a == NULL || ps->size == 0 || pos < 0 || pos > ps->size)
return;
int end = ps->size;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
--end;
}
ps->a[pos] = x;
++ps->size;
}
void SeqListErase(SeqList* ps, int pos)
{
if (ps->a == NULL)
return;
int end = ps->size;
while (end > pos)
{
ps->a[pos] = ps->a[pos+1];
++pos;
}
--ps->size;
}
void test1()
{
SeqList sl;
SeqListInit(&sl);
SeqListPushBack(&sl,1);
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);
SeqListPushBack(&sl, 5);
//输出 1 2 3 4 5
SeqListPushFront(&sl, 10);
SeqListPushFront(&sl, 20);
SeqListPushFront(&sl, 30);
SeqListPushFront(&sl, 40);
SeqListPushFront(&sl, 50);
//输出 50 40 30 20 10(单独输入,与尾插不相关)
SeqListPopBack(&sl,4);
//输出为 删除最后4位
// 如果需要删除的数大于顺序表最大长度,则全部删除
SeqListPopFront(&sl,4);
//输出为 删除前面4位
// 如果需要删除的数大于顺序表最大长度,则全部删除
SeqListFind(&sl, 1);
SeqListInsert(&sl, 1, 7);
SeqListErase(&sl, 2);
SeqListPrint(&sl);
SeqListDestroy(&sl);
}
int main()
{
test1();
//system("pause");
return 0;
}