数据结构——C语言实现顺序表-创新互联
数据结构——顺序表
顺序表的基本结构目前创新互联建站已为1000+的企业提供了网站建设、域名、网络空间、网站改版维护、企业网站设计、宁强网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。文章目录
本文标题:数据结构——C语言实现顺序表-创新互联
路径分享:http://cdiso.cn/article/csopsd.html
- 数据结构——顺序表
- 顺序表的基本结构
- 建立变量
- 初始化与释放
- 创建动态空间
- 插入数据、删除数据
- 头部插入数据
- 头部删除数据
- 尾部增加数据
- 尾部删除数据
- 指定下标增加数据)
- 指定下标删除数据
- 调试
- 查找
- 查找删除
- 源码
- 主函数
- 声明
数据是依次存储的,具有连续性,是数据连续性不是数字大小连续性。
顺序表分为静态和动态
静态基本就是空间是固定的,需要自己修改;
动态的没有空间就自动扩容。
建立变量typedef int SLDataType;//方便修改创建变量
typedef struct seqList
{SLDataType* a;
int size;//记录存储多少个有效数据
int capicity;//容量空间
}SL;
这整个变量也可以叫做接口,typedef就是容易修改的,设一个变量去表示所对应的类型。
初始化与释放//初始化
//断言很重要
void SLInit(SL* ps)
{assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
//初始化,先判断指针传过来的数据是否为空指针,然后再对指针内容去初始化。
//释放
void SLInit(SL* ps)
{assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
创建动态空间void SLCheckCapacity(SL* ps)
{assert(ps);
//扩容
if (ps->size == ps->capicity)//判断存了数据和大小是否相等,如果相等就是满了
{int newcapicity = ps->size == 0 ? 4 : ps->capicity * 2;//如果=0就返回4,不等于就返回2倍
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapicity * sizeof(SLDataType));
if (tmp == NULL)
{ perror("realloc fail");
exit(-1);//异常结束
}
ps->a = tmp;//扩容后地址,可能异地扩容所以要给一个新地址
ps->capicity = newcapicity;//扩容成功大小
}
}
插入数据、删除数据
头部插入数据void SLPushFront(SL* ps, SLDataType x)
{assert(ps);
SLCheckCapacity(ps);//不管增加什么数据都要判断一下内存容量,不够就扩容
int end = ps->size - 1;
while (end >= 0)
{ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;
ps->size++;
}
头部删除数据void SLPopFront(SL* ps)
{assert(ps);
int begin = 1;//从一开始是为了覆盖下标为0的数据,达到删除效果
assert(ps->size >0);//所存数据必须大于等于一个
while (begin< ps->size)//size-1才是最后一个数据的下标
{ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;//操作完后就把空间删除
}
尾部增加数据//尾部的数据直接添加就行,因为当前的ps->a[ps->size]的下标就是在size的位置,然后size++是要确保size要指向最后一个数据的下一个起始位置
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);
SLCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
尾部删除数据//尾部删除就直接size直接减一不打印就行,就可以达到删除效果
void SLPopBack(SL* ps)
{assert(ps);
//assert(ps);
温柔的检查
//if (ps->size == 0)
//{//return;
//}
// 暴力的检查
assert(ps->size >0);//如果报错会直接输出有错误,上述温柔的检查就直接结束
ps->size--;
}
指定下标增加数据)void SLInsert(SL* ps, size_t pos, SLDataType x)
{assert(ps);
assert(ps->size >= pos);
assert(pos >= 0);//判断下标区间
SLCheckCapacity(ps);//挪动前判断内存是否足够
int end = ps->size-1;//挪动数据
while (end >= pos)//移动到下标那位就行,从后面挪
{ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;//挪完后,下标就在pos的位置,直接赋值
ps->size++;
}
指定下标删除数据void SLErase(SL* ps, size_t pos)
{assert(ps);
assert(ps->size >pos);//尾删就是size-1的位置
assert(pos >= 0);
int begin = pos+1;//这里为什么是1呢?因为如果第一个(下标为0)需要删除的话就是直接可以用下标为1的去覆盖他
while (begin< ps->size)//数据大的下标是size-1
{ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
//while (begin >= pos && begin< ps->size)已经定义了begin就取大区间就行
//{// ps->a[begin - 1] = ps->a[begin];
// begin++;
//}
// 一开始写的就是这么烂,虽然说效果差不多,哈哈哈。
调试//这里举例说一下
void TestSeqList1()
{//要传地址才能修改
SL s1;
SLInit(&s1);//初始化
SLPushBack(&s1,1);
SLPushBack(&s1, 2);
SLPushBack(&s1, 3);
SLPushBack(&s1, 4);
SLPrint(&s1);
SLDestroy(&s1);//销毁
}
int main()
{TestSeqList1();
return 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;
}
查找删除//分两种类型
//删除一个,删除全部
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;
}
//首先我们要接收返回值
//假设删除4,然后从下标0开始
int SLF=SLFind(&s1, 4, 0);
if(SLF!=-1)
{ SLErase(&s1, SLF);//调用下标删除函数
}
//删除全部
int SLF=SLFind(&s1, 4, 0);
while(SLF!=-1)
{ SLErase(&s1, SLF);//调用下标删除函数
SLF=SLFind(&s1, 4, SLF);//这次的下标换成上一次删除下标的位置,减少重复计算
}
源码
主函数#define _CRT_SECURE_NO_WARNINGS 1
#include"seqList.h"
int main()
{SL s;
SLInit(&s);
int option = 0;
int val = 0;
do
{menu();
printf("请输入你的操作:>");
scanf("%d", &option);
switch (option)
{case 1:
printf("请依次输入你要尾部插入的数据,以-1结束");
scanf("%d", &val);
while (val != -1)
{ SLPushBack(&s, val);
scanf("%d", &val);
}
break;
case 2:
SLPopBack(&s);
break;
case 3:
printf("请依次输入你要在头部插入的数据,以-1结束");
scanf("%d", &val);
while (val != -1)
{ SLPushFront(&s, val);
scanf("%d", &val);
}
break;
case 4:
SLPopFront(&s);
break;
case 5:
SLPrint(&s);
break;
default:
break;
}
} while (option != -1);
SLDestroy(&s);
return 0;
}
声明#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include#include#include
静态顺序表
//#define N 10
//typedef int SLDataType;//方便修改创建变量
//typedef struct seqList
//{// SLDataType a[N];
// int size;//记录存储多少个有效数据
//}SL;
//
//动态顺序表--按需要扩容
typedef int SLDataType;//方便修改创建变量
typedef struct seqList
{SLDataType* a;
int size;//记录存储多少个有效数据
int capicity;//容量空间
}SL;
//打印
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);
//pos 下标
// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos);
//查找
int SLFind(SL* ps, SLDataType x,int begin);
#####实现函数
#define _CRT_SECURE_NO_WARNINGS 1
#include"seqList.h"
void SLPrint(SL* ps)
{assert(ps);
int i = 0;
for (i = 0; i< ps->size; i++)
{printf("%d", ps->a[i]);
}
printf("\n");
}
void SLCheckCapacity(SL* ps)
{assert(ps);
//扩容
if (ps->size == ps->capicity)
{int newcapicity = ps->size == 0 ? 4 : ps->capicity * 2;
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapicity * sizeof(SLDataType));
if (tmp == NULL)
{ perror("realloc fail");
exit(-1);
}
ps->a = tmp;//扩容后地址
ps->capicity = newcapicity;//扩容成功大小
}
}
void SLInit(SL* ps)
{assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
void SLDestroy(SL* ps)
{assert(ps);
if (ps->a)
{free(ps->a);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
}
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);
SLCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
void SLPopBack(SL* ps)
{assert(ps);
assert(ps->size >0);
ps->size--;
}
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);
SLCheckCapacity(ps);
int end = ps->size - 1;
while (end >= 0)
{ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;
ps->size++;
}
void SLPopFront(SL* ps)
{assert(ps);
int begin = 1;
assert(ps->size >0);
while (begin< ps->size)
{ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
void SLInsert(SL* ps, size_t pos, SLDataType x)
{assert(ps);
assert(ps->size >= pos);
assert(pos >= 0);
SLCheckCapacity(ps);
int end = ps->size-1;
while (end >= pos)
{ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;
ps->size++;
}
void SLErase(SL* ps, size_t pos)
{assert(ps);
assert(ps->size >= pos);//尾删就是size-1的位置
assert(pos >= 0);
int begin = pos+1;
while (begin< ps->size)
{ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
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;
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
本文标题:数据结构——C语言实现顺序表-创新互联
路径分享:http://cdiso.cn/article/csopsd.html