当前位置: 首页 > news >正文

如何将aaa云主机做网站成都小程序定制开发

如何将aaa云主机做网站,成都小程序定制开发,wordpress简单插件,网站开发移动app目录 一.什么是顺序表 二.顺序表的基本操作 1.初始化 2.增容 3.尾插 4.头插 5.尾删 6.头删 7.指定位置插入 8.指定位置删除 9.打印 10.查找 11.销毁 一.什么是顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组…

目录

一.什么是顺序表

二.顺序表的基本操作

  1.初始化

2.增容

3.尾插

4.头插

5.尾删

6.头删

7.指定位置插入

8.指定位置删除

9.打印

10.查找

11.销毁


一.什么是顺序表

        顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
        顺序表一般分为静态顺序表和动态顺序表,静态顺序表一般是用定长数组存储,而动态顺序表则是用动态内存管理函数进行动态分配空间,当空间不够时可以进行增容
        静态顺序表:
#define MAX 100
typedef int SLDataType;//对类型重定义,方便适应不同的数据类型
struct SeqList
{SLDataType a[MAX];//定长数组int size;         //当前数据个数
};

动态顺序表:

typedef int SLDataType;//对类型重定义,方便适应不同的数据类型
typedef struct SeqList
{SLDataType *a;//定义指针指向动态开辟的空间int size;    //当前存储的数据个数int capacity; //数据最大个数
}SL;

        一般我们不太经常使用静态顺序表,因为实际需求往往空间都是不定的,因此我们只讨论动态顺序表

        顺序表的本质还是对数组进行操作,只是和数组有所不同的是,顺序表的数据是连续存放的

二.顺序表的基本操作

        一般地,我们都是用结构体定义顺序表,对顺序表的基本操作分为初始化,插入,删除,打印,查找,增容等操作,下面我们就来学习一下这些基本操作

  1.初始化

        顺序表的初始化我们只需要讲指针置为空指针,然后将当前数据元素个数和最大数据元素个数置为0,到插入时我们便会动态开辟空间给指针a

void SLInit(SL * ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用ps->a = NULL;//置为空指针ps->size = 0;//初始化为0ps->capacity = 0;
}

2.增容

        当当前数据元素个数等于最大数据元素个数时,说明空间已满,此时则需要我们进行扩容,而扩容需要我们利用的动态内存管理函数开辟空间,我们选择的是realloc函数,打开cpp网站查看该函数有关信息

          realloc函数的的两个参数分别为空间的地址和扩容后的空间大小,返回值是指向扩容后空间的地址,返回值void*,因此我们需要将其强制类型转换为我们需要的类型

        当realloc函数的第一个指针为空指针时,其作用相当于malloc,第一次增容,由于我们初始化时给了最大容量capacity为0,因此需要给capacity赋一个初始值4,后面再扩容时则最大容量翻倍

        第一次调用realloc函数时,由于我们初始化时将指针a赋为空指针,故第一次调用realloc函数作用和malloc函数相当,后面再次调用则实现扩容功能

void SLCheckCapacity(SL* ps)
{assert(ps);断言是否为空指针,如传入空指针则报错,防止函数被误用if (ps->size == ps->capacity)//判断当前数据个数是否到达最大值,是则增容{int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//第一次给值为4,后面则翻倍SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//利用动态内存管理函数realloc开辟空间if (tmp == NULL)//判断是否开辟成功,如果返回空指针说明开辟失败则报错,否则将空间的地址付给a指针{perror("realloc fail");return;}ps->a = tmp;ps->capacity = newCapacity;//最大容量更新为扩容之后的容量}
}

3.尾插

        尾插先判断空间是否已满,若空间已满,则需要扩容,然后再直接从尾部插入,后将数据个数加1即可

void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用SLCheckCapacity(ps);//检查是否需要增容ps->a[ps->size] = x;//在尾部插入值ps->size++;			//数据个数加1
}

4.头插

        头插也需要判断空间是否已满,若空间已满,则需要扩容,然后再从头部插入,插入过程:先将顺序表里面已有的每一个元素往后挪动一个位置,相当于头部就腾出了一个“空位”,然后我们将需要插入的元素放到这个“空位”即可,后将数据元素加1

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[0] = x;//将值赋给第一个元素ps->size++;  //数据个数加1
}

5.尾删

        尾删需要先判断当前顺序表是否有元素,没有元素则直接报错,如果有元素,我们只需要将数据个数减1即达到删除效果,而不需要对最后一个元素进行操作,后续操作直接将它覆盖就行

void SLPopBack(SL* ps)
{assert(ps->size > 0);//判断当前是否有元素ps->size--;//直接将数据个数减1即可
}

6.头删

        头删也需要先判断当前顺序表是否有元素,没有元素则直接报错,如果有元素,则删除的过程为:以我们排队打饭为例,当队伍的最前面一个人打完饭,后面的每一个人就都会往前一个位置,此时删除元素也是一样,从第二个位置开始到最后一个元素每个元素都依次往前挪动一个元素即可,后将数据个数减1

void SLPopFront(SL* ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用assert(ps->size > 0);//判断当前是否有元素int begin = 0;while (begin < ps->size - 1)//从尾部一次挪动元素{ps->a[begin] = ps->a[begin+1];begin++;}ps->size--;//数据个数减1
}

7.指定位置插入

        指定位置我们需要先判断指定位置是否合法,如果小于0或者大于最大元素个数则直接报错,再判断是否需要增容,然后从指定位置开始到最后一个元素每个元素依次往后挪动一个位置,然后再将所插入的元素放到指定位置即可,后将数据元素个数加1

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用assert(pos >= 0 && 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++;//数据个数加1
}

8.指定位置删除

        指定位置删除野需要先判断给定位置是否合法,不合法则直接报错,然后从指定位置到最后一个元素依次往前挪动一个位置即可,后将数据元素减1

void SLErase(SL* ps, int pos)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用assert(pos >= 0 && pos < ps->size);//判断给定的位置是否合法int begin = pos;while (begin < ps->size - 1)//从指定位置依次挪动元素,直到到达尾部的前一个元素{ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;//数据个数减1
}

9.打印

        打印只需要定义一个循环变量,以下标的形式遍历顺序表打印即可

void SLPrint(SL* ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用int i = 0;for (i = 0; i < ps->size; i++)//依次遍历打印顺序表即可{printf("%d ", ps->a[i]);}
}

10.查找

        查找也是遍历顺序表,将每一个元素与查找的元素比较,若相等则返回元素下标,若遍历完没有找到元素,则返回-1,证明找不到该元素

int SLFind(SL* ps, SLDataType x)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用int i = 0;for (i = 0; i < ps->size; i++)//遍历数组,比较是否相等,相等则返回元素下标{if (ps->a[i] == x)return i;}return -1;//如果遍历没有找到该元素,则返回-1
}

11.销毁

        由于我们前面开辟空间是利用动态内存管理函数realloc开辟的,而该函数开辟的空间是由程序员自行开辟的,空间位于堆上,使用完空间后需要我们手动销毁,否则会导致内存泄露

        销毁空间我们需要用到free函数,我们打开cpp网站查看该函数有关信息

        freea函数的参数是一个指针,即所需要销毁的空间的地址,我们销毁顺序表只需要将指针a传给free函数即可,后讲指针a赋为空指针,防止其成为野指针

void SLDestroy(SL* ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用if (ps->a){free(ps->a);//释放a指针指向的空间ps->a = NULL;//将a指针置为空,防止其成为野指针ps->size = ps->capacity = 0;//当前数据元素个数和最大数据元素个数全置为0}
}

        可以看到,上面的基本操作都是有相应的接口函数,我们只需要调用相应的函数即可实现顺序表的一些基本操作

        上面所有的接口函数都用到了assert函数,且都位于函数体开头,assert函数称之为断言函数,当表达式为真是继续执行,当表达式为假时则直接报错,而这种报错可以让我们快速了解错误出在什么地方

        我们打开cpp网站查看该函数有关信息

        上面的所有接口函数调用assert函数,传的参数时指针a,当指针a为空指针时则直接报错,可以防止函数被误用而导致一些未知的错误 

        上面就是顺序表的一些基本操作,以下是全部代码:

SeqList.c

#include"SeqList.h"
void SLCheckCapacity(SL* ps)
{assert(ps);断言是否为空指针,如传入空指针则报错,防止函数被误用if (ps->size == ps->capacity)//判断当前数据个数是否到达最大值,是则增容{int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//第一次给值为4,后面则翻倍SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//利用动态内存管理函数realloc开辟空间if (tmp == NULL)//判断是否开辟成功,如果返回空指针说明开辟失败则报错,否则将空间的地址付给a指针{perror("realloc fail");return;}ps->a = tmp;ps->capacity = newCapacity;//最大容量更新为扩容之后的容量}
}
void SLInit(SL * ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用ps->a = NULL;//置为空指针ps->size = 0;//初始化为0ps->capacity = 0;
}
void SLDestroy(SL* ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用if (ps->a){free(ps->a);//释放a指针指向的空间ps->a = NULL;//将a指针置为空,防止其成为野指针ps->size = ps->capacity = 0;//当前数据元素个数和最大数据元素个数全置为0}
}
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用SLCheckCapacity(ps);//检查是否需要增容ps->a[ps->size] = x;//在尾部插入值ps->size++;			//数据个数加1
}
void SLPrint(SL* ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用int i = 0;for (i = 0; i < ps->size; i++)//依次遍历打印顺序表即可{printf("%d ", ps->a[i]);}
}
void SLPopBack(SL* ps)
{assert(ps->size > 0);//判断当前是否有元素ps->size--;//直接将数据个数减1即可
}
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[0] = x;//将值赋给第一个元素ps->size++;  //数据个数加1
}
void SLPopFront(SL* ps)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用assert(ps->size > 0);//判断当前是否有元素int begin = 0;while (begin < ps->size - 1)//从尾部一次挪动元素{ps->a[begin] = ps->a[begin+1];begin++;}ps->size--;//数据个数减1
}
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用assert(pos >= 0 && 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++;//数据个数加1
}
void SLErase(SL* ps, int pos)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用assert(pos >= 0 && pos < ps->size);//判断给定的位置是否合法int begin = pos;while (begin < ps->size - 1)//从指定位置依次挪动元素,直到到达尾部的前一个元素{ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;//数据个数减1
}
int SLFind(SL* ps, SLDataType x)
{assert(ps);//断言是否为空指针,如传入空指针则报错,防止函数被误用int i = 0;for (i = 0; i < ps->size; i++)//遍历数组,比较是否相等,相等则返回元素下标{if (ps->a[i] == x)return i;}return -1;//如果遍历没有找到该元素,则返回-1
}

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//动态顺序表
typedef int SLDataType;//对类型重定义,方便适应不同的数据类型
typedef struct SeqList
{SLDataType *a;//定义指针指向动态开辟的空间int size;    //当前存储的数据个数int capacity; //数据最大个数
}SL;
void SLCheckCapacity(SL *ps);
void SLInit(SL * ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);void SLPushBack(SL * ps, SLDataType x);
void SLPopBack(SL * ps);void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);void SLInsert(SL* ps,int pos, SLDataType x);
void SLErase(SL* ps, int pos);int SLFind(SL* ps, SLDataType x);

test.c

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void TestSeqList()
{SL sl;SLInit(&sl);SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(&sl, 5);SLPushFront(&sl, 0);SLInsert(&sl, 2, 9);SLErase(&sl, 2);int pos = SLFind(&sl, 5);if (pos != -1)SLErase(&sl, pos);SLPrint(&sl);SLDestroy(&sl);
}
int main()
{TestSeqList();return 0;
}

输出结果:

  好啦,顺序表我们就先学到这里,如果喜欢我的文章,欢迎动动手指一键三连~

http://www.yayakq.cn/news/967286/

相关文章:

  • 四川省住房与城乡建设厅网站官网工商注册费用多少钱
  • 南通优化网站排名福州省建设局网站
  • 创建网站 英文做网站一般需要哪些文件夹?
  • 个人做网站需要备案吗做建材网站
  • 做外贸大一点的网站wordpress邮件客户端
  • 电子商务网站开发的基本流程镇江网站设计开发公司电话
  • 制作网站最新工具小韩网站源码
  • 网站建设项目的摘要长沙做网站的价格
  • 网站开发工作流程网站伪静态设置
  • 怎么做网站寄生虫网站开发工作程序怎么写
  • 个人网站建设的目的中国世界排名第几?
  • 南宁网络推广方案佛山seo按效果付费
  • 麻章手机网站建设百度推广网站怎么做
  • 烟台做网站排名江西省网站建设先进表彰
  • 中国建设银行网站对公账户首页app项目策划书
  • 瀚钦科技网站建设深圳建筑设计找工作哪个招聘网站
  • 网站黑名单查询东莞公司企业设计网站建设
  • 专业网站设计网络服务漳州手机网站建设公司
  • 北京响应式网站开发网站购买广告位
  • 昊杰南宫网站建设软件制作专业
  • 3d设计网站东莞整合网站建设营销
  • 网站被墙什么意思中国外协加工网最新加工订单
  • 做网站涉及到哪些网站建设怎么上传不了图片
  • 想自己做个网站在哪里做莱芜杂谈
  • 网站怎么做能快速有排名网页一键生成小程序
  • 揭阳公司做网站十大搜索引擎排行榜
  • php 网站开发框架做异性的视频网站有哪些
  • 购物网站的前台功能网站开发职位
  • 网站建设公司哪家比较好想做个网站怎么做
  • 保定网站优化排名电脑做视频的网站