数据结构线性表部分习题(二)
最近有考研的打算,准备考研科目,先是数据结构部分。习题如下:
1.设计两个集合A和B,设计生成集合C=A并B的算法,集合A、B和C均用数组存储
算法思想描述
算法思想算是暴力找,让a中所有元素一个一个与b中元素作比较
算法代码描述如下:
void HBLinklist(Sqlist A[], Sqlist B[] ,Sqlist C[]){
int k =0;
for(int i = 0; i < A.len; i++){
for(int j = 0; j < B.len; i++){
if(A.data[i] == B.data[j]){
C.data[k] = A.data[i];
k++;
C.len++;
}
}
}
for(int h = 0; h < C.len; h++){
printf("%d",C.data[h])
}
}
2.给定一个由n(n>1)个不同整数组成的升序序列,同时包含负数和正数,设计一个在时间和空间两方面都尽量高效的算法,求序列中绝对值最小的数,如序列{-8, -3, -1, 4, 5}中绝对值最小的数为-1
算法思想描述
利用二分法找到0元素的点或者0最近点,附近绝对值最小
算法代码描述如下:
void Minvalue(int a[],int n){
int high = n-1;
int weight = 0;
int mid;
while(weight<high){
mid = (high + weight)/2;//利用二分法求0元素位置或者0最近位置
if(a[mid]>=0){
weight = mid;
}
else{
high = mid+1;
}
}
if(abs(a[weight]) < abs(a[weight-1]))//abs绝对值意思
printf("%d",a[weight]);
else
printf("%d",a[weight-1]);
}
3.设有一个正整数序列组成的有序单链表(按递增次序有序,且允许有相等的整数存在),试编写能实现下列功能的算法:(要求用最少的时间和最小的空间。) (1)确定在序列中比正整数x大的数有几个(相同的数只计算一次,如序列{20,20,17,16,15,15,11,10,8,7,7,5,4}中比10大的数有5个); (2)在单链表中将比正整数x小的数按递减次序排列; (3)将正整数(比)x大的偶数从单链表中删除
算法思想描述
1.这是个递增有序的单链表,可以遍历,找到第一个大于x的元素,如何判断与后面元素的关系,等于计数不变,否则计数+1,然后p后移一个单元,直到p的后继为NULL为止 2.找到第一个大于x的元素后,让前面所有逆置即可 3. 然后就是判断所有大于x的偶数元素直接删除就行
算法代码描述如下:
void Reverse(linklist h, linklist q){
node *p = h->next;
h->next = q;//q此时指向第一个大于x的元素,后序逆置相当于是在q前面进行头插法。
while(p=!q){
node *tem = p;
p = p->next;
tem->next = h->next;
h->next = tem;
}
}
int Function(linklist head, int x){
node *p = head->next;//
while(p&&p->data<x){//不停的遍历找第一个大于等于x的元素
p = p->next;
}
Reverse(head, p);//当执行到这个时候相当于已经不满足上面的while了,已经到了大于等于x的元素了,然后从头到大于x的第一个元素之间进行逆置操作
while(p&&p->data == x){//因为计数时不需要记录相等的数字,故需要跳过等于x的后续数
p = p->next;
}
if (p == NULL) {//x为最后一个元素,直接退出
return 0;
}
int count = 1;
node *q = p;
while(p->next){
if(p->data != p->next->data){//从大于x第一个数开始不断计数
count += 1;
}
p = p->next;
}
p = q;
while (p->next) {
if(p->next->data>x&&p->next->data%2 == 0){//然后大于x这个元素开始遍历判断偶数然后删除
node *tem = p->next;
p->next = tem->next;
free(tem);
}
else {
p = p->next;
}
}
return count;
}
4.在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计一个空间复杂度为0(1)且时间上尽可能高效的算法,去掉数值相同的元素,使表中不再有重复的元素。例如,将(7,10,10,21,30,42,42,42,51,70)变为(7,10,21,30,42,51,70)。
算法思想描述
判断当前结点值和后面结点是否一样,不一样后移,一样删除后面一个在判断
算法代码描述如下:
void Delete_Duplication(linklist head){
if(!head->next){
return ERROR;
}
node *p = head->next;
while(p->next){
if(p->data == p->next->data){
node *tem = p->next;
p->next = tem->next;
free(tem);
}
else {
p = p->next;
}
}
}