一共有两份代码:
目录
第一个分为 两个.c文件和一个.h文件
说明:
assert(ps)表示如果ps为空,会立即报错,使用这个函数一般要加头文件#include<assert.h>
ps表示SL类型的结构体,相当于顺序表
SeqList.h文件(头文件)存放函数的声明
SeqList.c文件(源文件)存放函数的定义
Seqtext.c存放主函数
1、定义顺序表结构体和宏定义数据类型
typedef int SLDateType; //数据类型
typedef struct SeqList
{
SLDateType* a; //数据类型指针,指向动态开辟的数组
int size; //顺序表长度
int capacity; //顺序表容量
}SL;
2、顺序表的初始化
void SLInsert(SL* ps) //顺序表的初始化
{
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
3、顺序表的摧毁(使用完需要摧毁顺序表)
void SLDestroy(SL* ps) //顺序表的摧毁
{
assert(ps);
if (ps->a) //如果ps->a不为空
{
free(ps->a);//释放掉pa->a空间
ps->a = NULL;
ps->size = ps->capacity = 0;
}
}
4、顺序表元素的查找
int SLFind(SL* ps, SLDataType x)
{
assert(ps);
for (int i = 0; i < ps->size; ++i)
{
if (ps->a[i] == x)
{
return i;
}
}
return -1;
}
如果找到了需要找的值,返回值的下标,否者返回-1;
5、检查ps的空间是否满了,如果满了则要重新分配空间
void SLCheckCapacity(SL*ps)
{
assert(ps);
if (ps->size == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDataType *tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//把新添加的用量添加到ps->a里面,这里注意tmp是地址空间
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
}
刚开始初始化顺序表之后,也通过这个函数分配空间;在这里说一下realloc的作用:
(SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType))表示
给指向ps->a的指针分配一个大小为newCapacity * sizeof(SLDataType)大小
的空间,如果在原来指向ps->a的后面的空间被占用了,
则会异地开辟新的空间,
并且会拷贝原来的数据过来,而原来的空间会被释放掉。
6、在pos位置插入数据
//在pos 位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
assert(ps);
assert(pos>= 0);
assert(pos <= ps->size); //此处可以等于0,因为在插入之前ps->a[size]的值为0
SeqListCheckCapacity(ps);
int end = ps->size-1;
while (end>=pos)
{
ps->a[end+1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
在插入数据之前需要考虑顺序表容量有没有满:SEqListCheckCapacity(ps);如果没有满,则将在pos位置往后的数据往后挪,挪完之后再插入数据x;
7、在pos位置删除数据
//删除pos位置数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0);
assert(pos < ps->size);
int begin = pos + 1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
8、在头部插入数据
void SLPushFront(SL* ps, SLDataType x) //头插
{
SLInsert(ps, 0, x);
}
9、在头部删除数据
void SLPopFront(SL* ps) //头删
{
SLErase(ps, 0);
}
10、在尾部删除数据
void SLPopBack(SL* ps) //尾删除
{
SLErase(ps, ps->size-1);
}
11、在尾部插入数据
void SLPushBack(SL* ps, SLDataType x) //尾插入
{
SLInsert(ps, ps->size, x);
}
12、代码(全)
这个是.h文件(头文件),用来存放函数的声明和顺序表结构体的定义,引用头文件的时候记得加上#include"SeqList.h"
//SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//静态顺序表---不太实用
//N太小了不够用,N大了可能浪费
//#define N 1000
//动态顺序表---按需扩空间
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* a;
int size; //记录存储多少个有效数据
int capacity; //空间容量大小
}SL;
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
void SLPrint(SL* ps);
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLCheckCapacity(SL* ps); //检查容量
//尾插尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
//头插头删
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
void menu();
int SLFind(SL* ps, SLDataType x, int begin);
以下是SeqLIst.c文件,存放函数的定义
//SeqList.c
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include"SeqList.h"
void SLCheckCapacity(SL*ps)
{
assert(ps);
if (ps->size == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDataType *tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//把新添加的用量添加到ps->a里面,这里注意tmp是地址空间
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
}
void SLPrint(SL* ps) //打印
{
assert(ps);
for (int i = 0; i < ps->size; ++i)
{
printf(" %d", ps->a[i]);
}
printf("\n");
}
void SLInit(SL* ps) //顺序表的初始化
{
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
void SLDestroy(SL* ps) //顺序表的摧毁
{
assert(ps);
if (ps->a) //如果ps->a有值在里面
{
free(ps->a);//释放掉pa->a空间
ps->a = NULL;
ps->size = ps->capacity = 0;
}
}
//在pos位置插入数据
void SLInsert(SL *ps,int pos,SLDataType x)
{
assert(ps);
assert(pos >= 0);
assert(pos <= ps->size);
SLCheckCapacity(ps);
int end = ps->size - 1;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
//删除pos位置数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0);
assert(pos < ps->size);
int begin = pos + 1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
void SLPushBack(SL* ps, SLDataType x) //尾插入
{
SLInsert(ps, ps->size, x);
}
void SLPopBack(SL* ps) //尾删除
{
SLErase(ps, ps->size-1);
}
void SLPushFront(SL* ps, SLDataType x) //头插
{
SLInsert(ps, 0, x);
}
void SLPopFront(SL* ps) //头删
{
SLErase(ps, 0);
}
int SLFind(SL* ps, SLDataType x, int begin)
{
assert(ps);
for (int i = begin; i < ps->size; ++i)
{
if (ps->a[i] == x)
{
return i;
}
}
return -1;
}
以下是用来存放主函数的文件,以及一些函数的调用
//SLtest.c
#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void menu()
{
printf("***********************************************************\n");
printf("1、尾插数据 2、尾删数据\n");
printf("3、头插数据 4、头删数据\n");
printf("5打印数据 -1退出\n");
printf("***********************************************************\n");
}
int main()
{
SL ps;
SLInit(&ps); //顺序表的初始化
//SLInsert(&ps,0,1);
//SLPrint(&ps);
int n=0;
int option=0;
do
{
menu();
printf("输入操作\n");
scanf("%d", &option);
switch (option)
{
case 1:
printf("请输入你尾插的数据,以-1结束");
scanf("%d",&n);
while (n != -1)
{
SLPushBack(&ps,n);
scanf("%d",&n);
}
break;
case 2:
SLPopBack(&ps);
break;
case 3:
printf("请输入你头插入的数据,以-1结束\n");
scanf("%d", &n);
while (n != -1)
{
SLPushFront(&ps,n);
scanf("%d", &n);
}
break;
case 4:
SLPopFront(&ps);
break;
case 5:
SLPrint(&ps);
break;
default:
break;
}
} while (option != -1);
printf("????\n");
SLDestroy(&ps);
return 0;
}
第二份 一个.c文件就可以运行
(将代码复制到.c文件就可以运行)
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
int size;
int 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 SeqListInit(SeqList* ps)//初始化
{
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
void SeqListDestroy(SeqList* ps)
{
assert(ps);
if (ps->a)
{
free(ps->a);
ps->a = NULL; //指针制空,释放
ps->size = ps->capacity = 0;
}
}
void SeqPrint(SeqList* ps) //打印
{
int i;
assert(ps);
for (i = 0; i < ps->size; i++)
{
printf(" %d", ps->a[i]);
}
}
void SeqListCheckCapacity(SeqList* ps) //给ps->a 分配空间或者添加空间
{
assert(ps);
if (ps->size == ps->capacity) //当顺序表长度等于顺序表的容量的时候
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDateType* temp = (SLDateType*)realloc(ps->a, newCapacity * sizeof(SLDateType));
if (temp == NULL) //if里面用的是"=="
{
printf("realloc failed");
exit(-1);
}
ps->a = temp;
ps->capacity = newCapacity;
}
}
//在pos位置删除数据
void SeqListErase(SeqList* ps, int pos)
{
assert(ps);
assert(pos >= 0);
assert(pos < ps->size);
int begin = pos + 1;
while (begin < ps->size)
{
ps->a[begin--] = ps->a[begin]; //pos位置的数据被它后一位的数据覆盖
begin++;
}
ps->size--;
}
//在pos 位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
assert(ps);
assert(pos>= 0);
assert(pos <= ps->size); //此处可以等于0,因为在插入之前ps->a[size]的值为0
SeqListCheckCapacity(ps);
int end = ps->size-1;
while (end>=pos)
{
ps->a[end+1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
void SeqListPushBack(SeqList* ps,SLDateType x) //尾插
{
SeqListInsert(ps, ps->size, x); //相当于在位置ps->a[size]处插入值x
}
void SeqListPopBack(SeqList* ps) //尾删
{
SeqListErase(ps, ps->size - 1);//相当于在位置ps->a[size-1]处删除数据
}
void SeqListPushFront(SeqList* ps, SLDateType x) //头插
{
SeqListInsert(ps, 0, x);
}
void SeqListPopFront(SeqList* ps) //头删
{
SeqListErase(ps, 0);
}
int SeqListFind(SeqList* ps, SLDateType x) //查找元素
{
assert(ps);
for (int i = 0; i < ps->size; ++i)
{
if (ps->a[i] == x)
{
return i; //返回下标
}
}
return -1; //若返回-1则找不到
}
int main()
{
SeqList ps;
int op;
int x;
int find;
SeqListInit(&ps); //初始化
do
{
printf("\n1、尾插 2、尾删 3、头插 4、头删 5、查找元素下标 6、打印 -1、退出\n");
printf("输入你的操作:\n");
scanf("%d", &op);
switch (op)
{
case 1:
printf("请输入你尾删的数据,以-1结束\n");
scanf("%d", &x);
while (x != -1)
{
SeqListPushBack(&ps, x);
scanf("%d", &x);
}
break;
case 2:
SeqListPopBack(&ps); break;
case 3:
printf("请输入你头插的数据,以-1结束\n");
scanf("%d", &x);
while (x != -1)
{
SeqListPushFront(&ps, x);
scanf("%d", &x);
}
break;
case 4:
SeqListPopFront(&ps); break;
case 5:
printf("请输入你要查找的元素x=");
scanf("%d", &x);
if ((find = SeqListFind(&ps, x)) == -1)
{
printf("没有该元素\n");
}
else
printf("下标为%d", SeqListFind(&ps,x));
break;
case 6:
SeqPrint(&ps); break;
default:
break;
}
} while (op != -1);
SeqListDestroy(&ps);
return 0;
}