总结归纳
- 动态分配对内存有着更大的控制权,但也会花费相应的时间。
- 顺序表的查找时间复杂度为O(1),这是单链表所不具备的。
- 顺序表的插入,要从后往前遍历,因为数据要后移;顺序表的删除,要从前往后遍历,因为数据要前移。
顺序表存储
原理:顺序表存储是将数据元素放到一块连续的内存存储空间,存取效率高,速度快。但是不可以动态增加长度
优点:存取速度高效,通过下标来直接存储
缺点:1.插入和删除比较慢,2.不可以增长长度
比如:插入或者删除一个元素时,整个表需要遍历移动元素来重新排一次顺序
链表存储
原理:链表存储是在程序运行过程中动态的分配空间,只要存储器还有空间,就不会发生存储溢出问题
优点:插入和删除速度快,保留原有的物理顺序,比如:插入或者删除一个元素时,只需要改变指针指向即可
缺点:查找速度慢,因为查找时,需要循环链表访问
从它们的存储优缺点来看,各自有各自的使用场景,比如:频繁的查找却很少的插入和删除操作可以用顺序表存储,如果频繁的插入和删除操作很少的查询就可以使用链表存储
线性顺序表的定义
一种方法是 :在静态分配时,由于数组的大小和空间实现已经固定,一旦空间占满,再加入新的数据将产生溢出,就会导致程序崩溃
#define InitSize 5 // 顺序表初始长度, 注意,不能放分号
struct SqList {
int* data; // 数组
int MaxSize; // 顺序表的最大长度
int length; // 顺序表的当前长度
};
另一种方法是:动态分配时,储存数组的空间实在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,可以另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储数组空间的目的,而不需要一次性地划分所有所需空间给线性表。
#define InitSize = 100 //表长度的初始定义
typedef struct {
int* data; //只是动态分配数组的指针
int MaxSize, length; //数组的最大容量和当前个数
}SqList;
具体操作
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
题目:
1. 从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错误信息并退出运行。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
2. 设计一个高效算法,将顺序表的所有元素逆置,要求算法的空间复杂度为O(1)。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
3. 长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
4. 从有序顺序表中删除其值在给定值s和t之间(要求s < t)的所有元素,如果s或t不合理或者顺序表为空则显示出错信息并退出运行。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
5. 从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
6. 将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
7. 已知在一维数组A[m+n]中一次存放着两个线性表(a1,a2,a3,…,am)和(b1,b2,b3,…,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,…,bn)放在(a1,a2,a3,…,am)的前面。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
8. 线性表(a1,a2,a3,…,an)中元素递增有序且按顺序存储于计算机内。要求设计一算法完成用最少时间在表中查找数值为x的元素,若找到将其与后继元素位置相交换,若找不到将其插入表中并使表中元素扔递增有序。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
9. 设将n(n>1)个整数存放到一维数组R中,试设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0 < p < n)个位置,即将R中的数据由(X0,X1,…,Xn-1`)变换为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1)。要求:
1)给出算法的基本设计思想
2)根据设计思想,采用C或++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
10. 一个长度为L(L≥1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在又两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数,要求:
1)给出算法的基本设计思想
2)根据设计思想,采用C或++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
11.已知一个整数序列A=(a0,a1,…,an-1),其中0≤ai≤n(0 ≤ i< n)。若存在ap1=ap2=…=apm=x且m > n / 2 ( 0 ≤ pk < n,1 ≤ k ≤ m),则称x为A的主元素。例如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素。假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素;否则输出-1。要求:
1)给出算法的基本设计思想
2)根据设计思想,采用C或++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
备注:其实按大小排序以后再统计是最优的办法,上面的方法也可以接受。