重新系统的过一遍数据结构
现在先回顾下它的定义
#define MaxSize 50 //定义线性表的最大长度
typedef struct{
ElemType data[MaxSize]; //顺序表的元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义
#define InitSize = 100 //表长度的初始定义
typedef struct{
ElemType *data; //只是动态分配数组的指针
int MaxSize,length; //数组的最大容量和当前个数
}SqList; //动态分配数组顺序表的类型定义
注意,题中如果没有强调有序顺序表,那么默认无序 比如下面的第四题
一维数组可以是静态分配的,也可以是动态分配的。在静态分配时,由于数组的大小和空间实现已经固定,一旦空间占满,再加入新的数据将产生溢出,就会导致程序崩溃。
而动态分配时,储存数组的空间实在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,可以另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储数组空间的目的,而不需要一次性地划分所有所需空间给线性表。
1. 从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错误信息并退出运行。
2. 设计一个高效算法,将顺序表的所有元素你只,要求算法的空间复杂度为O(1)。
3. 长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素。
4. 从有序顺序表中删除其值在给定值s和t之间(要求s < t)的所有元素,如果s或t不合理或者顺序表为空则显示出错信息并退出运行。
5. 从顺序表中删除其值在给定值s与t之间(包含s和t,要求s < t)的所有元素,如果s或t不合理或者顺序表为空则显示出错误信息并退出运行。
6. 从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
7. 将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表。
8. 已知在一维数组A[m+n]中一次存放着两个线性表(a1,a2,a3,…,am)和(b1,b2,b3,…,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,…,bn)放在(a1,a2,a3,…,am)的前面。
9. 线性表(a1,a2,a3,…,an)中元素递增有序且按顺序存储于计算机内。要求设计一算法完成用最少时间在表中查找数值为x的元素,若找到将其与后继元素位置相交换,若找不到将其插入表中并使表中元素扔递增有序。
10. 设将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)说明你所设计算法的时间复杂度和空间复杂度
11. 一个长度为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)说明你所设计算法的时间复杂度和空间复杂度
12.已知一个整数序列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)说明你所设计算法的时间复杂度和空间复杂度
解答部分
第一题
思想:搜索整个顺序表,查找最小值元素并记住其位置,搜索结束后用最后一个元素填补空出的原最小值元素位置。
bool Del_Min(sqList &L,int &value) {
//删除顺序表L中最小值元素结点,并通过引用性参数value返回其值
//如果删除成功,返回true;否则,返回false
if(L.length == 0)
return false; //表空
value = L.data[0];
int pos = 0; //假设第一个元素是最小的
for(int i =1;i<L.length;i++) //循环,寻找具有最小值的元素
if(L.data[i]<value){ //让value记忆当前具有最小值的元素
value = L.data[i];
pos = i;
}
L.data[pos] = L.data[L.length-1];//空出的位置由最后一个元素填补
L.length--;
return ture; //辞职时,value即为最小值
}
第二题
算法思想:扫描顺序表L的前半部分元素,对于元素L.data[i] (0 ≤ i < L.length/2),将其余后半部分对应元素L.data[L.length-i-1]进行交换。
void Reverse(SqList &L) {
Elemtype temp; //辅助变量
for(i=0;i<L.length/2;i++) {
temp = L.data[i]; //交换L.dta[i]与L.data[L.length-i-1]
L.data[i] = L.data[L.length-i-1];
L.data[L.length-i-1]=temp;
}
}
其实经过测试,表内元素是奇数或者偶数时都符合条件,所以可以当做一个典型题来记
第三题
有两种方法:
第一种:
用k记录顺序表L中不等于x的元素个数(即需要保存的元素个数),边扫描L边统计k,并将不等于x的元素向前放置k位置上,最后修改L的长度
void del_x_1(SqList &L,Elemtype x){
//本算法实现删除顺序表L中所有值为x的数据元素
int k = 0 ; //记录值不等于x的元素个数
for(i=0;i<L.length;i++){
if(L.data[i]! = x){
L.data[k]=L.data[i];