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

长春 万网 网站建设关键词林俊杰无损下载

长春 万网 网站建设,关键词林俊杰无损下载,餐饮网站建设设计,做网站的客户需求Hello~,欢迎大家来到我的博客进行学习! 目录 1.线性表2.顺序表2.1 概念与结构2.2 分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 动态顺序表的实现初始化尾插头插尾删头删查找指定位置之前插入数据删除指定位置的数据销毁 1.线性表 首先我们需要知道的是,…

在这里插入图片描述

Hello~,欢迎大家来到我的博客进行学习!

目录

  • 1.线性表
  • 2.顺序表
    • 2.1 概念与结构
    • 2.2 分类
      • 2.2.1 静态顺序表
      • 2.2.2 动态顺序表
    • 2.3 动态顺序表的实现
      • 初始化
      • 尾插
      • 头插
      • 尾删
      • 头删
      • 查找
      • 指定位置之前插入数据
      • 删除指定位置的数据
      • 销毁

1.线性表

首先我们需要知道的是,顺序表和链表都属于线性表。线性表是具有相同特性的一类数据结构的集合。

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。

这里的相同特性我从逻辑结构和物理结构两个方面进行分析。

  • 逻辑结构(一定是线性的):人为想象出来的。
  • 物理结构(不一定是线性的):比如数组在存储空间是连续的,和物理结构上的线性是一样的。

2.顺序表

2.1 概念与结构

概念:顺序表是用⼀段物理地址连续的存储单元(物理结构是线性的)依次存储数据元素的线性结构,⼀般情况下采用数组存储。顺序表的底层结构是数组。
在这里插入图片描述
顺序表和数组的区别?
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口。
在这里插入图片描述

2.2 分类

2.2.1 静态顺序表

如果顺序表底层是固定的空间大小,我们把它叫做静态顺序表。
实现静态顺序表,需要三个文件:头文件(.h)、源文件(.c)、测试文件(test.c)。

  • 头文件(.h):用来声明一些结构和我们的方法
  • 源文件(.c):方法的具体实现
  • 测试文件(test.c):用于测试

取名为SeqList(Sequence List),意为连续的。
我们可以定义一下静态顺序表的大小N,还需要一个size来定义一下有效数据的个数。同时这里的数据类型可能是各种各样的,使用typedef来解决。当要使用这个结构体的时候,我每次都要加上关键词,感觉麻烦,使用typedef来解决。

SeqList.h

#define N 1000
typedef char SLDataType;
//静态顺序表
typedef struct SeqList {SLDataType arr[N];int size;//有效数据的个数
}SL;

2.2.2 动态顺序表

如果空间是不固定的,我想要多少,可以去增加,就是动态顺序表。

#define N 1000
typedef char SLDataType;
//动态顺序表
typedef struct SeqList {SLDataType* arr;int size;//有效数据的个数int capacity;//容量大小
}SL;

2.3 动态顺序表的实现

初始化

现在我先进行初始化,参数传一个s,初始化的具体方法在SeqList.c文件中实现。
SeqList.c

#include"SeqList.h"
//初始化
void SLInit(SL s)
{s.arr = NULL;s.size = s.capacity = 0;
}

在test.c中进行检验。

#include"SeqList.h"
void SLTest()
{SL sl;SLInit(sl);
}int main()
{SLTest();return 0;
}

此时会报错:
在这里插入图片描述
在test.c的sl是实参,在SeqList里面的s为形参。
在这里插入图片描述
我们需要将sl的地址传过去,而不是传值。传值时,改变形参并不能改变实参。在SeqList.c这里我就应该用指针来接收。
改完以后:
SeqList.c

#include"SeqList.h"
//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}

test.c

#include"SeqList.h"
void SLTest()
{SL sl;SLInit(&sl);
}int main()
{SLTest();return 0;
}

SeqList.h

#include<stdio.h>
#include<stdlib.h>
#define N 1000
typedef int SLDataType;
静态顺序表
//typedef struct SeqList {
//	SLDataType arr[N];
//	int size;//有效数据的个数
//}SL;//动态顺序表
typedef struct SeqList {SLDataType* arr;int size;//有效数据的个数int capacity;//容量大小
}SL;//初始化
void SLInit(SL* ps);

调试看看:
在这里插入图片描述
跳出以后,sl里面的部分也初始化了:
在这里插入图片描述

尾插

现在来添加插入数据的功能,顺序表的底层是数组,我可能需要需要在原来数据的末尾、中间、开头插入数据。
首先实现尾插(在顺序表最后一个可插的位置,插入数据)的功能。
在这里插入图片描述
如上图,我有5块空间,里面有3个有效数据。尾插就是在3的后面插入数据。

用SLPushBack这个函数来实现,里面的参数为ps和我们要插入的数据。现在我们需要在顺序表里插入数据,这里有三个成员:arr、size、capacity。size指向的位置刚好就是最后一个有效数据的下一个位置。
在这里插入图片描述
假设空间足够,现在往里面插入一个数据X = 99,直接往3后面放,这里并不需要遍历数据组,往size这个位置放就行,插入完成之后,size++。

//尾插
void SLPushBack(SL* ps, SLDataType x)
{ps->arr[ps->size] = x;++ps->size;
}

假设空间不够(此时size和capacity在一个位置),按以上方式插入数据,会越界。就需要对原数组申请空间,,然后再在size位置插入数据,插入后size++。
因而我们需要分情况来写。
在这里插入图片描述
在增容时,我们使用realloc(可以在原数组的基础上进行增加容量)来进行这一操作。如果插一个数据,增加一个容量,没有空间的浪费,但是增容频繁,程序效率低下。如果一次多申请一些,可能会造成空间的浪费。通常,增容是按倍数增加,如2倍、3倍…这里我选择两倍。
在这里插入图片描述
按照以上思路,其实是有漏洞的。

//尾插
void SLPushBack(SL* ps, SLDataType x)
{//空间不够,申请空间if (ps->size == ps->capacity){//空间不够,2倍增容SLDataType* tmp = (SLDataType*)realloc(ps->arr, ps->capacity * 2);}ps->arr[ps->size++] = x;
}

在realloc这里,第二个参数是size_t size单位是字节,ps->capacity * 2 这里改为 ps->capacity * 2 *sizeof(SLDataType)。并看看增容成功没有。但是之前我们初始化那里把capacity初始化为0,现在需要扩容的话,需要先给一个初始值。我这里先给一个SLDestroy函数,在程序结束时释放动态分配的内存,不然程序结束时会出现内存泄漏。
SeqList.c

#include"SeqList.h"
//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}//尾插
void SLPushBack(SL* ps, SLDataType x)
{if (ps == NULL){return;}//空间不够,申请空间if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//空间不够,2倍增容SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}ps->arr[ps->size++] = x;
}// 释放顺序表
void SLDestroy(SL* ps) 
{if (ps->arr != NULL) {free(ps->arr);  // Free the allocated memoryps->arr = NULL;}
}

在这里插入图片描述

头插

现在来实现头插。这里也要看空间大小够不够,则可以分装一个方法来判断空间大小够不够。前面的步骤和尾插差不多,只是实现头插时有部分区别。需要把数据整体往后移动,然后再进行插入。在移动的时候,先把后面的数据往后移动,最后把插入的数据放在下标为0的位置。同样在增加完数据之后,size++。
SeqList.c

#include"SeqList.h"
//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}void SLcheckCapacity(SL* ps)
{//空间不够,申请空间if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//空间不够,2倍增容SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}
}//尾插
void SLPushBack(SL* ps, SLDataType x)
{if (ps == NULL){return;}SLcheckCapacity(ps);ps->arr[ps->size++] = x;
}//头插
void SLPushFront(SL* ps, SLDataType x)
{if (ps == NULL){return;}SLcheckCapacity(ps);//直接头插//数据整体向后移动一位for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;++ps->size;
}

尾删

ps不能传空,删除数据之后,size要 - -。顺序表为空,也不行。这里把最后一个数据弄掉,不是把最后一个数据弄为0,而是可以修改

//尾删
void SLPopBack(SL* ps)
{assert(ps&&ps->size>0);--ps->size;}

头删

这里的前提和尾删一样。ps不能传空,删除数据之后,size要 - -。顺序表为空,也不行。我们需要移动数据,下标为零以后的数据,整体向前移动一位

//头删
void SLPopFront(SL* ps)
{assert(ps && ps->size > 0);--ps->size;for (int i = 0; i<ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}
}

查找

这里比较简单,遍历顺序表,如果查找到返回下标;如果找不到返回无效下标。

//查找
int SLFind(SL* ps, SLDataType x)
{for(int i = 0; i < ps->size; i++){if (x == ps->arr[i]){//找到了,返回下标return i;}}//找不到return -1;
}

指定位置之前插入数据

这里新增一个参数pos(指定位置)。pos需要有效,pos >= 0 && pos <= ps->size。与之前一样需要判断空间是否足够,插入好之后size++。
假设需要将99这个数据插入3这个位置之前,需要将pos以及之后的数据向后移动一位。
在这里插入图片描述

//指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);//前=:头插//后=:尾插assert(pos >= 0 && pos <= ps->size);SLcheckCapacity(ps);for (int i = ps->size - 1; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;++ps->size;
}

删除指定位置的数据

同样的size需要减减,指定位置pos必须pos >= 0 && pos <= ps->size。要删除pos位置的数据就需要把pos之后的数据整体向前移。

//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos;i<ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}--ps->size;
}

销毁

动态申请的空间在不用的时候需要销毁。

//销毁
void SLDestroy(SL* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->size = ps->capacity = 0;
}

此时,我们对顺序表已经比较理解了。

好了,我们的顺序表的知识就讲到这里。如果文章内容有误,请大佬在评论区斧正!谢谢大家!
在这里插入图片描述

http://www.dtcms.com/wzjs/175139.html

相关文章:

  • 榆林做网站公司推广app的单子都在哪里接的
  • 如何申请一个网站网络营销整合推广
  • 网站做打鱼游戏挣钱吗企业宣传
  • 找人做网站昆明英文seo外链
  • 品牌建设有待加强兰州seo实战优化
  • 自己写的网站怎么发布seo职业发展
  • 做门户网站的好处百度网站官网
  • 网站建设设备清单营销类网站
  • 我自己做的一个网站显示证书错误关键词优化技巧有哪些
  • 网站建设负责人证明免费拓客软件哪个好用
  • 网站的标题标签一般是写在最近时事热点新闻评论及点评
  • 广西网站建设软件推广广州seo公司品牌
  • 重庆的网站设计公司网站注册时间查询
  • 工程公司起名aso优化软件
  • 公司做网站要多久windows7系统优化工具
  • 微信公众号可以做几个微网站吗林云seo博客
  • 铁门关网站建设河北百度代理公司
  • 怎么做卖卷网站一手app推广接单平台
  • 政府门户网站建设与管理武汉企业seo推广
  • 手机创建网站免费深圳建站公司
  • 网站建设策划书(建设前的市场分析)新手怎么学做电商
  • asp.net开发网站和优势曹操博客seo
  • 西宁做网站君博解决北京优化seo
  • 网站空间测试seo流量排名软件
  • 微信小程序可以做音乐网站吗搜索引擎平台排名
  • 深圳网站建设外贸公司价格俄罗斯搜索引擎yandex官网入口
  • 哪个网站可以做视频外链权重查询工具
  • 武威市凉州区建设局网站获取排名
  • 网站模板紫色东莞网站建设方案外包
  • 政府 门户网站 互动平台 方案怎样做品牌推广