1.设将 n(n>1)个整数存放在一维数组 R 中。试着设计一个在时间复杂度和空间复杂度都尽可能高效的算法,将 R 中保存的序列循环左移 ( 0<p<n ) 个 位 置 , 即 将 R 中 的 数 据 由 ( x 0 ,x 1 ,…,x n-1 ) 变 换 为 ( x p ,x p+1 ,…,x n-1 ,x 0 ,x 1 ,…,x p-1 )
//先将 n 个数据 x 0 ,x 1, …,xn-2,xn-1 原地逆置,得到 x n-1 ,x n-2 ,…,x,x 0 ,然后再将 n-p 个数据和后 p 个数据分别原地逆置,得到最终结果: x p ,x p+1 ,…,x n-1 ,x 0 ,x 1 ,…,x p-1
typedef struct LNode{
int data;
struct LNode *next;
}LNode;
void Reverse(int R[], int left, int right)
{
//将数组原地逆置
i = left, j = right;
while(i < j)
{
int tmp = r[i];
r[i] = r[j];
r[j] = tmp;
i++; //i 右移动一个位置
j--; //j 左移一个位置
}
}
void LeftShift(int R[], int n, int p)
{ //将长度为 n 的数组 R 中的数据循环左移 p 个位置
if(p>0 && p<n)
{
Reverse(r,0,n-1); //将数组全部逆置
Reverse(r,0,n-p-1); //将前 n-p 个数据逆置
Reverse(r,n-p,n-1); //将后 p 个数据逆置
}
}
2.在长度为n的顺序表L中,编写一个时间复杂度为0(n),空间复杂度为O(1)的算法,该算法删除所有值为X的数据元素
//顺序表
//时间复杂度为0(n),空间复杂度为O(1)
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //顺序表的长度
}SqList;
void Del_X(SqList &L, Elemtype X){
int k=0,i=0;
while(i < L.length){
if(L.data[i] == X){
k++;
}else{
L.data[i-k] = L.data[i];
}
i++;
}
L.length = L.length-k;
}
3.已知线性表(a 1 ,a 2 ,…,a n )按顺序结构存储且每个元素为不相等的整数。设计把所有奇数移动到所有偶数前边的算法 (要求时间最少,辅助空间最少)
//从左向右找到偶数 L.data[i],从右向左找到奇数L.data[j],将两者交换。循环这个过程直到 i 大于 j 为止
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //顺序表的长度
}SqList;
void move(){
int i=0, j=L.length-1, temp;
while(i <= j){
while(L.data[i]%2 == 1)
i++; //i 指向一个偶数
while(L.data[j]%2 == 0)
j--; //j 指向一个奇数
if(i < j)
{
temp = L.data[i]; //交换 L.data[i]和 L.data[j]
L.data[i] = L.data[j];
L.data[j] = temp;
}
}
}
4.设计一个高效算法,将顺序表 L 中所有元素逆置,要求算法的空间复杂度为 O(1)
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //顺序表的长度
}SqList;
void reverse(SqList &L)
{
int i;
ElemType x;
for(i = 0; i<L.length/2; i++)
{
x = L.data[i];
L.data[i] = L.data[L.length-i-1]; //L.data[i]与 L.data[L.length-i-1]交换
L.data[L.length-i-1] = x;
}
}
5.将两个有序表合并为一个新的有序顺序表,并由函数返回结果顺序表
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //顺序表的长度
}SqList;
bool Merge(SqList A, SqList B, SqList &C)
{
if(A.length + B.length > C.length) //表长超过
return false;
int i = 0, j = 0, k = 0;
while(i <A.length && j<B.length)
{ //循环,两两比较,小者存入结果表
if(A.data[i] <= B.data[j])
C.data[k++] = A.data[i++];
else
C.data[k++] = B.data[j++];
}
while(i <A.length)
C.data[k++] =A.data[i++];
while(j < B.length)
C.data[k++] = B.data[j++];
C.length = k;
return true;
}
6.从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除元素的值。空出的位置由最后一个元素填补
//搜素整个顺序表,查找最小值元素并记在其位置,搜索结束后用最后一个元素填补空出的原最小值元素的位置。
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //顺序表的长度
}SqList;
bool Delete_Min(SqList &L ,ElemType &value)
{
//删除顺序表 L 中最小值元素结点,并通过引用型参数 value 返回其值
if(L.length == 0)
return false; //表空,终止操作
value = L.data[0];
int pos = 0; //假设 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 true;
}
7.设计一个算法,从一给定的顺序表 L 中删除元素值在 x 到 y(x≤y)之间的所有元素,要求以较高的效率来实现,空间复杂度为 O(1)。
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //顺序表的长度
}SqList;
void del_xy(SqList &L, ElemType x, ElemType y)
{
int i = 0, k = 0;
while(i < L.length)
{
if(L.data[i] >= x && L.data[i] <= y)
k++; //k 记录被删除记录的个数
else
L.data[i-k] = L.data[i];
i++;
}
L.length -= k;
}