淘宝店铺网站建设可行性报告,asp网站制作实例教程,莱芜网站建设价格低,做蛋糕的企业网站目录
一、顺序表是什么
1.1 概念
1.2 分类
1.3 结构
二、顺序表的基本操作
2.1 前绪准备
2.2 初始化
2.3 扩容
2.5 尾插 2.6 打印
2.7 尾删
2.8 头插 2.9 头删 2.10 在pos位置插入 2.11 删除pos位置的数据 2.12 查找
三、完整代码
3.1 Test.c文件
3.2 SeqList.h…目录
一、顺序表是什么
1.1 概念
1.2 分类
1.3 结构
二、顺序表的基本操作
2.1 前绪准备
2.2 初始化
2.3 扩容
2.5 尾插 2.6 打印
2.7 尾删
2.8 头插 2.9 头删 2.10 在pos位置插入 2.11 删除pos位置的数据 2.12 查找
三、完整代码
3.1 Test.c文件
3.2 SeqList.h文件
3.3 SeqList.c文件
四、与顺序表相关的例题
4.1 移除元素
4.1.1 题目描述
4.1.2 题目分析
4.2 删除有序数组中的重复项
4.2.1 题目描述
4.2.2 题目分析
4.3 合并两个有序数组
4.3.1 题目描述
4.3.2 题目分析
五、顺序表的缺陷 一、顺序表是什么
1.1 概念 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构一般情况下采用数组存储在数组上完成数据的增删查改。
1.2 分类 顺序表可以分为静态顺序表和动态顺序表。
静态顺序表使用定长数组存储元素。动态顺序表使用动态开辟的数组存储。
相对来说动态顺序表的优势大静态顺序表不太实用局限性大。
1.3 结构 顺序表需要对存储的数据进行管理存储的数据本质上是使用数组存储要对数据进行管理就需要知道顺序表中存储元素的个数其次如果创建的是动态的顺序表那么还需要记录下它的容量对于动态顺序表我们单用某一种类型的变量无法将他准确的描述出来它包含顺序表有效元素个数顺序表的容量以及顺序表开辟的空间的地址三个主要元素无法使用某种单一的类型来表示所以我们需要定义一个结构体类型。
typedef struct SeqList
{SLDataType* a; //开辟的空间的起始地址int size; //有效数据的个数int capacity; //空间容量
}SL;
一个简单的顺序表可以由下图来表示 二、顺序表的基本操作 在此处我们分装成SeqList.h、SeqList.c以及Test.c这三个文件来实现顺序表的完整操作在SeqList.h中定义顺序表需要的函数SeqList.c中实现顺序表的操作Test.c中实现主函数完成一系列的操作在本文章的第二部分主要是对顺序表的每个操作进行讲解整体实现在第三部分。
顺序表主要有以下操作
void SeqInit(SL* s); //初始化
void SeqDestory(SL* s); //销毁
void SLPushBack(SL* s, SLDataType x); //尾插
void SLPrint(SL* s); //打印
void SLPopBack(SL* s); //尾删
void SLCheckCapacity(SL* s); //扩容
void SLPushFront(SL* s, SLDataType x); //头插
void SLPopFront(SL* s); //头删
void SLInsert(SL* s,int pos, SLDataType x); //从pos位置插入
void SLErase(SL* s, int pos); //删除pos位置的元素
int SLFind(SL* s, SLDataType x); //找某个数在顺序表中的位置
2.1 前绪准备 我们是创建的动态顺序表即动态开辟空间空间不够再进行扩容操作为了我们写的顺序表有更广泛地使用定义 INIT_CAPACITY 来表示容量大小以便我们后续对容量进行改变。我们在此顺序表设置的起始开辟的容量为4在本文章展示的顺序表存储的是int类型数据这里指的是开辟4个int类型的空间即16字节的空间。
#define INIT_CAPACITY 4 顺序表中可以存储不同类型的元素为了使我们写的顺序表具有广泛性在这里我们使类型重定义用SLDataType代表某种类型。在本文章中我们存储的是int类型的数据。
typedef int SLDataType;2.2 初始化 对于一个顺序表我们主要关注顺序表有效元素个数顺序表的容量以及顺序表开辟的空间的地址三个主要元素对他进行初始化即对这三个要素进行初始化。 对于顺序表的初始化函数我们需要注意传参的时候需要传的是地址我们在此函数中需要改变结构体的内容就要传结构体的指针很多同学在这里会出现以下错误我们通过图来解释 void SeqInit(SL* ps)
{assert(ps); //断言ps为空时顺序表不存在再进行下面操作没有意义ps-a (SLDataType*)malloc(INIT_CAPACITY * sizeof(SLDataType)); //动态开辟空间if (ps-a NULL) //判断开辟空间是否成功{perror(malloc fail);return;}ps-size 0;ps-capacity INIT_CAPACITY;
} 上面开辟空间时我们使用了malloc函数对此函数不了解的可以参照下图 2.3 扩容 在对顺序表进行插入的时候有可能存在将开辟的空间用完的情况即空间中存储的数据有效个数与容量相等这个时候我们就需要进行扩容一般是将容量扩充到当前的二倍。 我们需要注意
realloc的第二个参数传的是扩容后的总字节数。realloc分为原地扩容和异地扩容如果是原地扩容那么realloc调用后返回的地址与原空间的地址相同如果是异地扩容那么realloc将返回新的地址所以在这里我们需要将tmp的值赋给ps-a。
void SLCheckCapacity(SL* ps) //扩容
{assert(ps);if (ps-size ps-capacity){SLDataType * tmp (SLDataType*)realloc(ps-a, ps-capacity * sizeof(SLDataType)*2);if (tmp NULL){perror(realloc fail);return;}ps-a tmp;ps-capacity * 2;}
} 上述函数中在扩容的时候我们使用的是realloc函数对他使用不熟练的同学可以看下图
2.5 尾插 对于顺序表的尾插我们主要需要注意以下两个问题
需要考虑是否扩容这里直接复用上面的扩容函数尾插的原理 void SLPushBack(SL* ps, SLDataType x) //尾插
{assert(ps);SLCheckCapacity(ps);ps-a[ps-size] x;ps-size;
} 2.6 打印 我们对顺序表进行增删查改等操作后需要打印来观察顺序表是否进行了增删查改操作。
void SLPrint(SL* ps) //打印
{assert(ps);int i 0;for (i 0; i ps-size; i){printf(%d , ps-a[i]);}printf(\n);
}
2.7 尾删 对于顺序表的尾删我们需要知道顺序表主要是通过size来看空间中的有效数据个数对于尾删只需要使size--即可。 尾删有个前提条件就是空间中存在数据如果空间中没有数据那么删除就会出问题在这里我们使用assert断言assert后面括号中的内容为假就会直接报错为真操作忽略。 尾删的代码如下
void SLPopBack(SL* ps) //尾删
{assert(ps);assert(ps-size 0);ps-size--;}注意对于动态开辟的空间在释放时只能整块整块的释放不能在中间随意位置进行释放。
2.8 头插 顺序表的底层存储是数组且是连续的地址进行存储如果要在头部插入一个数据那么就要移动后面的数据。 void SLPushFront(SL* ps, SLDataType x) //头插
{assert(ps);SLCheckCapacity(ps);int end ps-size-1;while (end 0){ps-a[end1] ps-a[end];end--;}ps-a[0] x;ps-size;
}2.9 头删 顺序表的头删与头插正好相反他需要从前向后挪动数据具体情况如下 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--;
} 2.10 在pos位置插入 在pos位置插入我们首先要对pos位置是否合法进行判断避免出现越界等问题其次此函数也可以在头插尾插函数中进行复用。 void SLInsert(SL* ps, int pos, SLDataType x) //从pos位置插入
{assert(ps);assert(pos 0 pos ps-size);SLCheckCapacity(ps);int end ps-size;while (end pos){ps-a[end] ps-a[end - 1];end--;}ps-a[pos] x;ps-size;
} 2.11 删除pos位置的数据 删除pos位置的数据首先也要判断pos位置是否合法其次删除pos位置要将pos位置之后的数据依次往前挪动。 void SLErase(SL* ps, int pos) //删除pos位置的元素
{assert(ps);assert(pos0posps-size);int begin pos;while (begin ps-size - 1){ps-a[begin] ps-a[begin 1];begin;}ps-size--;
} 2.12 查找 我们有时候会在顺序表中找某一个值就用到了查找函数。
int SLFind(SL* ps, SLDataType x) //找某个数在顺序表中的位置
{assert(ps);int search 0;while (search ps-size){if (x ps-a[search]){return search;}}return -1;
} 在此函数中如果找到返回下标没有找到就返回-1.
三、完整代码 注意由于顺序表的操作多在每写完一个操作后我们最好测试一下所以在Test.c中有多个测试函数。
3.1 Test.c文件
#include SeqList.hvoid TestSeqList1()
{SL s;SeqInit(s); //初始化SLPushBack(s, 1);SLPushBack(s, 2);SLPushBack(s, 3);SLPushBack(s, 4);SLPushBack(s, 5);SLPrint(s);SeqDestory(s); //销毁}void TestSeqList2()
{SL s;SeqInit(s); //初始化SLPushBack(s, 1);SLPushBack(s, 2);SLPushBack(s, 3);SLPushBack(s, 4);SLPushBack(s, 5);SLPrint(s);SLPopBack(s);SLPrint(s);SLPopBack(s); SLPrint(s);SLPopBack(s);SLPopBack(s);SLPopBack(s);SLPrint(s);SeqDestory(s); //销毁}void TestSeqList3()
{SL s;SeqInit(s); //初始化SLPushFront(s, 1);SLPushFront(s, 2);SLPushFront(s, 3);SLPushFront(s, 4);SLPushFront(s, 5);SLInsert(s, 2, 10);SLPrint(s);SLErase(s,2);SLPrint(s);SLPopFront(s);SLPrint(s);SLPopFront(s);SLPrint(s);SLPopFront(s);SLPopFront(s);SLPopFront(s);SLPrint(s);SeqDestory(s); //销毁}int main()
{TestSeqList3();return 0;}3.2 SeqList.h文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#include stdlib.h
#includestdio.h
#includeassert.htypedef int SLDataType;
#define N 10
#define INIT_CAPACITY 4静态顺序表
//typedef struct SeqList
//{
// SLDataType a[N];
// int size;
//};//动态顺序表
typedef struct SeqList
{SLDataType* a; //开辟的空间的起始地址int size; //有效数据的个数int capacity; //空间容量
}SL;void SeqInit(SL* s); //初始化
void SeqDestory(SL* s); //销毁
void SLPushBack(SL* s, SLDataType x); //尾插
void SLPrint(SL* s); //打印
void SLPopBack(SL* s); //尾删
void SLCheckCapacity(SL* s); //扩容
void SLPushFront(SL* s, SLDataType x); //头插
void SLPopFront(SL* s); //头删
void SLInsert(SL* s,int pos, SLDataType x); //从pos位置插入
void SLErase(SL* s, int pos); //删除pos位置的元素
int SLFind(SL* s, SLDataType x); //找某个数在顺序表中的位置
3.3 SeqList.c文件
#include SeqList.h
void SeqInit(SL * ps)
{assert(ps);ps-a (SLDataType*)malloc(INIT_CAPACITY * sizeof(SLDataType));if (ps-a NULL){perror(malloc fail);return;}ps-size 0;ps-capacity INIT_CAPACITY;
}void SeqDestory(SL* ps) //销毁
{free(ps-a);ps-a NULL;ps-size 0;ps-capacity 0;
}void SLPushBack(SL* ps, SLDataType x) //尾插
{assert(ps);SLCheckCapacity(ps);ps-a[ps-size] x;ps-size;
}void SLCheckCapacity(SL* ps) //扩容
{assert(ps);if (ps-size ps-capacity){SLDataType * tmp (SLDataType*)realloc(ps-a, ps-capacity * sizeof(SLDataType)*2);if (tmp NULL){perror(realloc fail);return;}ps-a tmp;ps-capacity * 2;}
}void SLPrint(SL* ps) //打印
{assert(ps);int i 0;for (i 0; i ps-size; i){printf(%d , ps-a[i]);}printf(\n);
}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[end1] ps-a[end];end--;}ps-a[0] x;ps-size;
}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--;
}void SLInsert(SL* ps, int pos, SLDataType x) //从pos位置插入
{assert(ps);assert(pos 0 pos ps-size);SLCheckCapacity(ps);int end ps-size;while (end pos){ps-a[end] ps-a[end - 1];end--;}ps-a[pos] x;ps-size;
}void SLErase(SL* ps, int pos) //删除pos位置的元素
{assert(ps);assert(pos0posps-size);int begin pos;while (begin ps-size - 1){ps-a[begin] ps-a[begin 1];begin;}ps-size--;
}int SLFind(SL* ps, SLDataType x) //找某个数在顺序表中的位置
{assert(ps);int search 0;while (search ps-size){if (x ps-a[search]){return search;}}return -1;
}
四、与顺序表相关的例题
4.1 移除元素
4.1.1 题目描述
题目链接https://leetcode.cn/problems/remove-element/ 给你一个数组 nums 和一个值 val你需要 原地 移除所有数值等于 val 的元素并返回移除后数组的新长度。 不要使用额外的数组空间你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 4.1.2 题目分析
思路一 以空间换时间本方法主要是在创建一个数组arr用一个指针遍历原数组将原数组中不等于val的值依次存放在arr数组中然后将arr数组中的内容拷贝到原数组中。 注意此方法的时间复杂度是O(n)我们要对原数组遍历一遍需要有一个循环基本语句的执行次数是n次此方法的空间复杂度是O(n)由于在力扣环境中不支持C99中的变长数组所以我们这里创建的数组个数按照题目中nums数组的最大个数来看但是它的量级依然属于n。 int removeElement(int* nums, int numsSize, int val)
{int arr[100]{0};int src 0;int dst 0;while(src numsSize){if (nums[src] val){src;}else{arr[dst] nums[src];}}memcpy(nums,arr,dst*sizeof(int));return dst;
}
思路二 双指针定义两个指针src和dst都从下标为0开始如果src处的值不等于val把它赋值到dst处然后dst和src都加1如果src处的值等于val只对src加1依次往后遍历直到srcnumsSize结束。 此方法的时间复杂度为O(n)其中 n 为序列的长度。我们只需要遍历该序列至多两次。空间复杂度是O(1)我们只需要常数的空间保存若干变量。 int removeElement(int* nums, int numsSize, int val)
{int src 0;int dst 0;while (src numsSize){if (nums[src] val){src;}else{nums[dst] nums[src];dst;src;}}return dst;
}
4.2 删除有序数组中的重复项
4.2.1 题目描述
题目链接26. 删除有序数组中的重复项 - 力扣LeetCode 给你一个升序排列的数组 nums 请你原地删除重复出现的元素使每个元素只出现一次 返回删除后数组的新长度。元素的 相对顺序应该保持一致 。
4.2.2 题目分析
思路 双指针如果src和dst下标对应的值相同那么dst加1如果src和dst下标对应的值不相同src加1然后那dst下标对应的值赋给src下标对应的值。 int removeDuplicates(int* nums, int numsSize)
{int src 0;int dst 1;while (dst numsSize){if (nums[dst] nums[src]){dst;}else{src;nums[src] nums[dst];dst;}}return src 1;
}
4.3 合并两个有序数组
4.3.1 题目描述
题目链接88. 合并两个有序数组 - 力扣LeetCode 给你两个按非递减顺序排列的整数数组nums1和nums2另有两个整数m和n 分别表示 nums1和nums2中的元素数目。 请你合并nums2到nums1中使合并后的数组同样按非递减顺序排列。
4.3.2 题目分析
思路 我们要将两个数组合并如果都从前面即下标为0处开始比较会涉及较多的移动数据问题所以我们倒着比用三个指针其中dst是合并好数组的最后一个下标end2是nums2数组的最后一个下标end1是nums1数组的最后一个下标如果nums[end2]大于nums[end1]则移动到nums1[dst]位置上。 void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{int end1 m - 1;int end2 n - 1;int dst m n - 1;while (end1 0 end2 0){if (nums1[end1] nums2[end2]){nums1[dst] nums2[end2];end2--;dst--;}else{nums1[dst] nums1[end1];end1--;dst--;}}while (end2 0){nums1[dst--] nums2[end2--];}
}
五、顺序表的缺陷
顺序表有许多的问题
中间/头部的插入删除时间复杂度为O(N)增容需要申请新空间拷贝数据释放旧空间会有不小的消耗。增容一般呈2倍的增长势必会有一定的空间浪费。 文章转载自: http://www.morning.lgqdl.cn.gov.cn.lgqdl.cn http://www.morning.wsxly.cn.gov.cn.wsxly.cn http://www.morning.jlrym.cn.gov.cn.jlrym.cn http://www.morning.mqfhy.cn.gov.cn.mqfhy.cn http://www.morning.rmmz.cn.gov.cn.rmmz.cn http://www.morning.lbpfl.cn.gov.cn.lbpfl.cn http://www.morning.pmhln.cn.gov.cn.pmhln.cn http://www.morning.mynbc.cn.gov.cn.mynbc.cn http://www.morning.rdxnt.cn.gov.cn.rdxnt.cn http://www.morning.zxhpx.cn.gov.cn.zxhpx.cn http://www.morning.prznc.cn.gov.cn.prznc.cn http://www.morning.hbnwr.cn.gov.cn.hbnwr.cn http://www.morning.hxbps.cn.gov.cn.hxbps.cn http://www.morning.jmlgk.cn.gov.cn.jmlgk.cn http://www.morning.kmjbs.cn.gov.cn.kmjbs.cn http://www.morning.lrmts.cn.gov.cn.lrmts.cn http://www.morning.bfjtp.cn.gov.cn.bfjtp.cn http://www.morning.lqgfm.cn.gov.cn.lqgfm.cn http://www.morning.zbhfs.cn.gov.cn.zbhfs.cn http://www.morning.jkfyt.cn.gov.cn.jkfyt.cn http://www.morning.nchlk.cn.gov.cn.nchlk.cn http://www.morning.lpzqd.cn.gov.cn.lpzqd.cn http://www.morning.rksg.cn.gov.cn.rksg.cn http://www.morning.bxnrx.cn.gov.cn.bxnrx.cn http://www.morning.gnwse.com.gov.cn.gnwse.com http://www.morning.ctlbf.cn.gov.cn.ctlbf.cn http://www.morning.xbkcr.cn.gov.cn.xbkcr.cn http://www.morning.mhmsn.cn.gov.cn.mhmsn.cn http://www.morning.ttfh.cn.gov.cn.ttfh.cn http://www.morning.lzjxn.cn.gov.cn.lzjxn.cn http://www.morning.dlwzm.cn.gov.cn.dlwzm.cn http://www.morning.lqljj.cn.gov.cn.lqljj.cn http://www.morning.dkfrd.cn.gov.cn.dkfrd.cn http://www.morning.lmnbp.cn.gov.cn.lmnbp.cn http://www.morning.srbsr.cn.gov.cn.srbsr.cn http://www.morning.dnqliv.cn.gov.cn.dnqliv.cn http://www.morning.tqxtx.cn.gov.cn.tqxtx.cn http://www.morning.rckmz.cn.gov.cn.rckmz.cn http://www.morning.qdmdp.cn.gov.cn.qdmdp.cn http://www.morning.pwwjs.cn.gov.cn.pwwjs.cn http://www.morning.npbnc.cn.gov.cn.npbnc.cn http://www.morning.fdfsh.cn.gov.cn.fdfsh.cn http://www.morning.trsmb.cn.gov.cn.trsmb.cn http://www.morning.fhjnh.cn.gov.cn.fhjnh.cn http://www.morning.qphcq.cn.gov.cn.qphcq.cn http://www.morning.jokesm.com.gov.cn.jokesm.com http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.mwmtk.cn.gov.cn.mwmtk.cn http://www.morning.wctqc.cn.gov.cn.wctqc.cn http://www.morning.qqrlz.cn.gov.cn.qqrlz.cn http://www.morning.rwwdp.cn.gov.cn.rwwdp.cn http://www.morning.lwdzt.cn.gov.cn.lwdzt.cn http://www.morning.zsgbt.cn.gov.cn.zsgbt.cn http://www.morning.lnrr.cn.gov.cn.lnrr.cn http://www.morning.sxwfx.cn.gov.cn.sxwfx.cn http://www.morning.qtfss.cn.gov.cn.qtfss.cn http://www.morning.ppwdh.cn.gov.cn.ppwdh.cn http://www.morning.rkrl.cn.gov.cn.rkrl.cn http://www.morning.zwyuan.com.gov.cn.zwyuan.com http://www.morning.phzrq.cn.gov.cn.phzrq.cn http://www.morning.fbjnr.cn.gov.cn.fbjnr.cn http://www.morning.spxk.cn.gov.cn.spxk.cn http://www.morning.rlsd.cn.gov.cn.rlsd.cn http://www.morning.cnqdn.cn.gov.cn.cnqdn.cn http://www.morning.pfggj.cn.gov.cn.pfggj.cn http://www.morning.gydth.cn.gov.cn.gydth.cn http://www.morning.jkwwm.cn.gov.cn.jkwwm.cn http://www.morning.ysjjr.cn.gov.cn.ysjjr.cn http://www.morning.fmgwx.cn.gov.cn.fmgwx.cn http://www.morning.dztp.cn.gov.cn.dztp.cn http://www.morning.stcds.cn.gov.cn.stcds.cn http://www.morning.fqqlq.cn.gov.cn.fqqlq.cn http://www.morning.spqtq.cn.gov.cn.spqtq.cn http://www.morning.rrcrs.cn.gov.cn.rrcrs.cn http://www.morning.mxtjl.cn.gov.cn.mxtjl.cn http://www.morning.czzpm.cn.gov.cn.czzpm.cn http://www.morning.ljdjn.cn.gov.cn.ljdjn.cn http://www.morning.kjsft.cn.gov.cn.kjsft.cn http://www.morning.jwbfj.cn.gov.cn.jwbfj.cn http://www.morning.rkkh.cn.gov.cn.rkkh.cn