从顺序表中删除具有最小值的元素( 假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
//算法思路:遍历顺序表,如果比value小,value就等于它,并且记录该数据的下标,最后将最后一个字符与之交换
bool Del_Min(SL& ps, SLDateType& value)
{
//如果为空,返回错误
if (ps.size == 0)
{
return false;
}
//记录数组下标
size_t index = 0;
for (size_t i = 0; i < ps.size; i++)
{
//如果比value小赋值给value
if (value > ps.a[i])
{
value = ps.a[i];
index = i;
}
}
//交换
//ps.a[index] = ps.a[ps.size - 1];
//这里template void swap (T& a, T& b);
swap(ps.a[index], ps.a[ps.size - 1]);
ps.size--;
return true;
}
设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为0(1)。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
//算法思路:两个指针指向left和right,向中间首尾交换,直到相遇
void Reverse(SL& ps)
{
size_t left = 0;
size_t right = ps.size - 1;
//直到中间相等或者right比left大退出循环
while (left < right)
{
//交换
swap(ps.a[left], ps.a[right]);
//向中间移动
left++;
right--;
}
}
对长度为n的顺序表L,编写一个时间复杂度为0(n)、空间复杂度为0(1)的算法,该算法删除线性表中所有值为x的数据元素。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
//算法思路:遍历,一个指针遇到x停下,另一个指针寻找不是x元素的数值,将该值赋值给该位置。
void Del_Value(SL& ps, SLDateType x)
{
//记录可以替换的位置
int cur = 0;
//寻找x元素
int index = 0;
while(index < ps.size -1)
{
if (ps.a[index] != x)
{
ps.a[cur] = ps.a[index];
cur++;
}
//遇到相等的时候cur停止移动,而index继续右移动,将数值赋值给cur(覆盖掉x)
index++;
}
ps.size = cur;
}
从有序顺序表中删除其值在给定值s与t之间(要求s
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*算法思路:
和第三题差不多,遇到s-t范围内k++,
范围外将其赋值给该位置减去k,最终数组最后k个数就是s-t中数组
*/
bool Del_ValueRange(SL& ps, const SLDateType& s, const SLDateType& t)
{
//s和t不合法,数组为空
if (s >= t || ps.size == 0)
{
return false;
}
size_t k = 0;
for (size_t i = 0; i < ps.size; i++)
{
if (ps.a[i] > s && ps.a[i] < t)
{
k++;
}
else
{
ps.a[i - k] = ps.a[i];
}
}
ps.size -= k;
return true;
}
从顺序表中删除其值在给定值s与t之间(包含s和t,要求s
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*算法思路:
和第三题差不多,遇到s-t范围内k++,
范围外将其赋值给该位置减去k,最终数组最后k个数就是s-t中数组
*/
bool Del_ValueRange(SL& ps, const SLDateType& s, const SLDateType& t)
{
//s和t不合法,数组为空
if (s >= t || ps.size == 0)
{
return false;
}
size_t k = 0;
for (size_t i = 0; i < ps.size; i++)
{
if (ps.a[i] >= s && ps.a[i] =< t)
{
k++;
}
else
{
ps.a[i - k] = ps.a[i];
}
}
ps.size -= k;
return true;
}
从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*算法思路:
记录cur和index,index记录寻找和cur不同的数组元素下标;
如果cur等于index,index++;
如果cur不等于index,cur++,cur=index,index++;
index无论在哪种情况都需要++,所以index可以为for循环的i
*/
void Del_Dup_Ele(SL& ps)
{
size_t cur = 0;
for (size_t i = 0; i < ps.size - 1; i++)
{
if (ps.a[cur] != ps.a[i])
{
cur++;
ps.a[cur] = ps.a[i];
}
}
ps.size = cur;
}
将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*算法思路:
ps3存放,分别遍历ps1和ps2,小的先赋给ps3
*/
bool Merge_Ordered_List(const SL& ps1, const SL& ps2, SL& ps3)
{
if (ps1.size + ps2.size > ps3.size)
{
return false;//放不下
}
int i = 0;
int j = 0;
int k = 0;
while (i < ps1.size && j < ps2.size)
{
if (ps1.a[i] < ps2.a[j])
{
ps3.a[k++] = ps1.a[i++];
}
else
{
ps3.a[k++] = ps2.a[j++];
}
}
while (i < ps1.size)
{
ps3.a[k++] = ps1.a[i++];
}
while (j < ps2.size)
{
ps3.a[k++] = ps2.a[j++];
}
ps3.size = k;
return true;
}
已知在一维数组A[m + n]中依次存放两个线性表(an, a2, a… am)和(b, b2, b3…… bn)。编写一
个函数,将数组中两个顺序表的位置互换,即将(b1, b2, b3… bn,)放在(a1, a2, a3…… am)的前面。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*
算法思路:
a表逆置,b表逆置,整个链表逆置
*/
void Reverse_List(SLDateType* a, int sz)
{
int begin = 0;
int end = sz - 1;
while (begin < end)
{
swap(a[begin], a[end]);
}
}
void Dul_List_Swap_Position(SL& pl, int m, int n)
{
Reverse_List(pl.a, m);
Reverse_List(pl.a + m, n);
Reverse_List(pl.a, m + n);
}
线性表(a1, a2, a3…… an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换,若找不到,则将其插入表中并使表中元素仍递增有序。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*
算法思路:
寻找中间数,如果比x大找右边,比x小,找左边
在按照这个思路继续查找
*/
void Binary_Search(SL& pl, SLDateType x)
{
int left = 0;
int right = pl.size;
int mid = (left + right) / 2;
while (left <= right)
{
if (x > pl.a[mid])
{
left = mid + 1;
mid = (left + right) / 2;
}
if (x < pl.a[mid])
{
right = mid - 1;
mid = (left + right) / 2;
}
//找到了
if (pl.a[mid] == x)
{
break;
}
}
if (pl.a[mid] == x && mid != pl.size - 1)
{
swap(pl.a[mid], pl.a[pl.size - 1]);
}
else
{
for (int i = pl.size - 1; i > mid ; i--)
{
pl.a[i + 1] = pl.a[i];
}
pl.a[mid + 1] = x;
}
}
设将n (n> 1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0
要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C+或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*
算法思路:
a表逆置,b表逆置,整个链表逆置
时间复杂度:On 空间复杂度O1
*/
void Reverse_List(SLDateType* a, int sz)
{
int begin = 0;
int end = sz - 1;
while (begin < end)
{
swap(a[begin], a[end]);
}
}
void Dul_List_Swap_Position(SL& pl, int m, int n)
{
Reverse_List(pl.a, m);
Reverse_List(pl.a + m, n);
Reverse_List(pl.a, m + n);
}
一个长度为L (L≥1) 的升序序列s,处在第[L/2]个位置的数称为s的中位数。例如,若序列S1=(11,13,15,17,19),则S的中位数是15, 两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2, 4, 6, 8, 20),则S;和S2的中位数是11.现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述箕法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*
算法思路:
类似两个链表合并成一个链表
时间复杂度:On 空间复杂度O1
*/
/*
int Find_Mid(SL& p1, SL& p2)
{
int i = 0;
int j = 0;
int len = (p1.size + p2.size)/2;
int x = 0;
while (i < p1.size && j < p2.size)
{
if (p1.a[i] < p2.a[j])
{
i++;
x = p1.a[i];
}
else
{
j++;
x = p1.a[i];
}
if (i + j == len)
{
break;
}
}
return x;
}
*/
/*
算法思路:
分别查找两个数组的中位数
a = b,则为中位数
a < b, 中位数在 a的数组右边,b的左边
a > b, 反之
最后分别剩1个数,较小为中位数
*/
int Find_Mid(SL& p1, SL& p2)
{
int left1 = 0;
int right1 = p1.size - 1;
int mid1 = (left1 + right1) / 2;
int left2 = 0;
int right2 = p1.size - 1;
int mid2 = (left2 + right2) / 2;
while (left1 != right1 && left2 != right2)
{
if (p1.a[mid1] < p2.a[mid2])
{
//留下右边
if (left1 < right1)
{
left1 = mid1 + 1;
mid1 = (left1 + right1) / 2;
}
//留下左边
if (left2 < right2)
{
right2 = mid2 - 1;
mid2 = (left2 + right2) / 2;
}
}
//反之
if (p1.a[mid1] > p2.a[mid2])
{
//留下右边
if (left2 < right2)
{
left2 = mid2 + 1;
mid2= (left2 + right2) / 2;
}
//留下左边
if (left1 < right1)
{
right1 = mid1 - 1;
mid1 = (left1 + right1) / 2;
}
}
}
return p1.a[mid1] > p1.a[mid2] ? p1.a[mid1] : p2.a[mid2];
}
已知一个整数序列A = (a0, a1,an-1),其中0
若存在ap1=ap2= … =apm=x且m> n/2 (0≤pk
出A的主元素。若存在主元素,则输出该元素;否则输出-1. 要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释.
3)说明你所设计算法的时间复杂度和空间复杂度。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*
算法思路:
出现并计数,不出现--,直到0,重新计数,最终次数大于0是备选人
再进行遍历查看出现次数
空间复杂度O1,时间复杂度On
*/
int Main_Ele(SL& pl)
{
int x = 0;
int count = 0;
for (size_t i = 0; i < pl.size; i++)
{
if (x != pl.a[i])
{
if (count == 0)
{
x = pl.a[i];
}
else
{
count--;
}
}
else
{
count++;
}
}
if (count > 0)
{
int count = 0;
for (size_t i = 0; i < pl.size; i++)
{
if (x == pl.a[i])
{
count++;
}
}
}
if (count > pl.size / 2)
{
return x;
}
return -1;
}
给定一个含n (n≥1)个整数的数组,请设计一个在时间上尽可能高.
效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3, 2,3}中未出现的最小正
整数是1;数组{1,2,3}中未 出现的最小正整数是4.要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。.
3)说明你所设计算法的时间复杂度和空间复杂度。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
/*
算法思路:遇到负数忽略,寻找最小正数,
时间复杂度On,空间复杂度O1
*/
int Min_Pos_Int(SL& pl)
{
int x = INT_MAX;
for (size_t i = 0; i < pl.size; i++)
{
if (pl.a[i] > 0)
{
if (pl.a[i] < x)
{
x = pl.a[i];
}
}
}
return x;
}
定义三元组(a, b,c) (a、 b、c均为正数)的距离D=|a-b| + |b-c| +|c-a|
给定3个非空整数集合S1、S2和S3按升序分别存储在3个数组中。请设计一个尽可能高效的算法 ,计算并输出所有可能的三元组(a,b,c) (a∈S|, b∈S2, cESj) 中的最小距离
例如Si={-1,0,9}, S2={-25,-10, 10,11}, S3= {2, 9, 17,30, 41},则最小距离为2,相应的三元组为(9, 10, 9)。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C语言或C++语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a;
size_t size;
size_t capacity;
}SL;
bool Min(int a , int b, int c)
{
if (a <= b && a <= c)
{
return true;
}
return false;
}
int ThreeArray_Min_Distance(SL& s1, SL& s2, SL& s3)
{
//距离
int d = INT_MAX;
//数组下标
int i = 0, j = 0, k = 0;
while (i < s1.size && j < s2.size && k < s3.size)
{
int ret = abs(s1.a[i] - s2.a[j]) + abs(s1.a[i] - s3.a[k]) + abs(s2.a[j] - s3.a[k]);
if (ret < d)
{
d = ret;
}
if (Min(s1.a[i], s2.a[j], s3.a[k]))
{
i++;
}
else if (Min(s2.a[j], s1.a[i], s3.a[k]))
{
j++;
}
else
{
k++;
}
}
return d;
}