试设计算法在O(n) 时间内将数组A[0…n-1]划分为左右两个部分,使得左边的所有元素为奇数,右边的所有元素均为偶数,要求所使用的辅助存储空间大小为O(1)。
void DivideArr ( int A[ ] , int n) {
int i = 0 , j = n - 1 ;
while ( i < j) {
while ( i < j && A[ i] % 2 != 0 )
++ i;
while ( j > i && A[ j] % 2 == 0 )
-- j;
if ( i < j) {
int temp = A[ i] ;
A[ i] = A[ j] ;
A[ j] = temp;
}
}
}
判断两个非递减有序的线性表中是否存在相同(关键字值相等)的元素,如果有相同的元素,返回第一个相同元素在第一个有序表中的位置,否则返回0,请选择合适的物理存储结构,用C语言给出该物理存储结构的类型定义,并在其上编写算法。
int A[ maxn] , B[ maxn] ;
int n1 , n2;
int FirstElement ( int A[ ] , int n1 , int B[ ] , int n2) {
int i = 0 , j = 0 ;
while ( i < n1 && j < n2) {
if ( A[ i] == B[ j] )
return i;
else if ( A[ i] > B[ j] )
++ j;
else
++ i;
}
return 0 ;
}
在n个元素中,找出第k大的元素,用C语言写出数据结构,设计算法实现上述要求,并分析算法复杂度,最好是平均时间复杂性为O(n)。
int A[ maxn] , n;
int partition ( int A[ ] , int L , int R) {
int i = L , j = R;
int temp = A[ L] ;
while ( i < j) {
while ( i < j && A[ j] >= temp) -- j;
if ( i < j) {
A[ i] = A[ j] ;
++ i;
}
while ( i < j && A[ i] <= temp) ++ i;
if ( i < j) {
A[ j] = A[ i] ;
-- j;
}
}
A[ i] = temp;
return i;
}
int FindKElement ( int A[ ] , int n , int k) {
int low = 0 , high = n - 1 ;
while ( low <= high) {
int m = partition ( A , low , high) ;
if ( m == k)
return A[ m] ;
else if ( m < k) {
low = m + 1 ;
k = k - m;
}
else
high = m - 1 ;
}
}
输入M个数从中取出N个数进行组合并输出所有组合项。M、N都是不固定的,例如输入M可以是3、5、9、24也可以是8、4、7、21、6、11,N可以是2也可以是5,当然N<M。
void CombineArr ( int A[ ] , int M , int N , int t , int B[ ] , int visit[ ] ) { 55
if ( t == N) {
for ( int i = 0 ; i < N ; ++ i)
printf ( "%d%c" , B[ i] , " \n" [ i == N - 1 ] ) ;
return ;
}
for ( int i = 0 ; i < M ; ++ i) {
if ( visit[ i] == 0 ) {
B[ t] = A[ i] ;
visit[ i] = 1 ;
CombineArr ( A , M , N , t + 1 , B , visit) ;
visit[ i] = 0 ;
B[ t] = 0 ;
}
}
}
一个仅由0,1,2三种数构成的数组A共有n个元素,乱序排列在一起,0,1,2的数量大于0,但具体个数未知。请设计一种时间复杂度为O(n)的算法,将数组排成形状00…111…222,(即前面都是0,中间都是1,后面都是2)
void swap ( int A[ ] , int i , int j) {
int temp = A[ i] ;
A[ i] = A[ j] ;
A[ j] = temp;
}
void partition ( int A[ ] , int n) {
int index = 0 ;
int less = - 1 , more = n;
while ( index < more) {
if ( A[ index] == 0 )
swap ( A , index++ , ++ less) ;
else if ( A[ index] == 1 )
++ index;
else if ( A[ index] == 2 )
swap ( A , index , -- more) ;
}
}
给出一系列整数,设计算法求出总和最大的子系列,要求算法的时间复杂性在O(n)之内。比如对于整数系列-1,2,-1,3,-2,总和最大的子系列是2,-1,3。
int getMaxSum ( int A[ ] , int n) {
int maxSum = 0 , sum = 0 ;
for ( int i = 0 ; i < n ; ++ i) {
sum + = A[ i] ;
if ( sum < 0 ) sum = 0 ;
maxSum = maxSum > sum ? maxSum : sum;
}
return maxSum;
}
1,2,……,n这n个数,无序地保存在数组c[1…n]中。请编写一个时间复杂度为O(n)的排序算法,将数组c[1…n]按小到大排序。
void Sort ( int c[ ] , int n) {
int x;
for ( int i = 1 ; i <= n ; ++ i) {
while ( c[ i] != i) {
x = c[ i] ;
c[ i] = c[ x] ;
c[ x] = x;
}
}
}