已知在一维数组A[m+n]中一次存放着两个线性表(a1,a2,a3,...am) 和 (b1,b2,b3,...bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,...,bn) 放在 (a1,a2,a3,...,am)的前面
void Reverse(DataType A[], int left, int right, int arraySize){
// 先对整个数组逆置,在分别对线性表b和线性表a进行逆置
if(left >= right || right >= arraySize){
return false;
}
int mid = (left + right) / 2;
DataType temp;
for(int i = 0; i < mid; ++i){
temp = A[left + i];
A[left + i] = A[right - i];
A[right - i] = temp;
}
}
void Exchange(){
Reverse(A, 0, m+n-1, arraySize);
Reverse(A, 0, n-1, arraySize);
Reverse(A, n, m+n-1, arraySize);
}
void SearchExchangeInsert(ElemType A[], ElemType x){
// 使用折半查找法
int low = 0, high = n - 1, mid;
while(low <= high){
mid = (low+hight)/2;
if(A[mid] == x){
break;
}else if(A[mid] < x){
low = mid + 1;
}else{
high = mid - 1;
}
}
if(A[mid] == x && mid != n - 1){// 若最后一个元素与x相等,不存在与其后继交换的操作
ElemType t = A[mid];
A[mid] = A[mid + 1];
A[mid + 1] = t;
}
if(low > high){
for(i = n - 1; i > high; i--){
A[i+1] = A[i];
}
A[i+1] = x;
}
}
思路:
把这个问题看作把数组ab转为数组ba(a代表数组的前p个元素,b代表数组余下的n-p个元素),先将a逆置得到
a逆b,再将b逆置得到a逆b逆,最后将整个a逆b逆逆置为ba
void Reverse(int R[], int from, int to){
int i, temp;
for(i = 0; i < (to - from + 1)/2; i++){
temp = R[from + i];
R[from + i] = R[to - i];
R[to - i] = temp;
}
}
void Converse(int R[], int n int p){
Reverse(R, 0, p-1);
Reverse(R, p, n-1);
Reverse(R, 0, n-1);
}
时间复杂度分别为O(p/2),O((n-p)/2),O(n/2)
故时间复杂度为O(n),空间复杂度为O(1)
分别求两个序列的中位数,设为a和b,求序列A和B的中位数
若a=b,则a或b即所求中位数
若ab,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,两次舍弃的长度相等
在保留的两个升序序列中,重复以上过程,直到两个序列中均只含一个元素时为止,较小者即为所求中位数
int M_search(int A[], int B[], int n){
int s1=0, d1 = n - 1, m1, s2 = 0, d2 = n-1, m2
while(s1 != d1 || s2 != d2){
m1 = (s1+d1)/2;
m2 = (s2+d2)/2;
if(A[m1] == B[m2]){
return A[m1];
}
if(A[m1] < B[m2]){
if((s1 + d1)%2 == 0){// 数量为奇数个,保留中间点
s1 = m1;// 舍弃A中较小的部分
d2 = m2;// 舍弃B中较大的部分
}else{
s1 = m1 + 1;
d2 = m2;
}
}else{
if((s2 + d2)%2 == 0){// 数量为奇数个,保留中间点
d1 = m1;// 舍弃A中较大的部分
s2 = m2;// 舍弃B中较小的部分
}else{
d1 = m1;
s2 = m2 + 1;
}
}
}
return A[s1] < B[s2]? A[s1]:B[s2];
}
重复次数多于整个数组一半数量的元素即为主元素
标记一个可能的主元素,然后扫描统计出现次数,判断是否为真的主元素
记录遇到的第一个整数Num,若下次遇到的整数仍等于Num,计数+1;否则,计数-1
计数减到0的时候,将遇到的下一个整数作为Num,计数重新计为1,重复以上过程
判断标记的整数是否为真的主元素,扫描数组,统计标记整数的出现次数
int Majority(int A[], int n){
int i, c, count = 1;
c = A[0];
for(i = 1; i < n; i++){
if(A[i] == c){
count++;
}else{
if(count > 0){
count--;
}else{
c = A[i];
count = 1;
}
}
}
if(count > 0){
for(i = count = 0; i < n; i++){
if(A[i] == c){
count++;
}
}
if(count < n/2){
return c;
}
}else{
return -1;// 不存在主元素
}
}
时间复杂度O(n),空间复杂度O(1)