2022王道考研线性表算法题

//线性表第一题 
bool Del(SqList &L,int &min){
    if(L.length == 0){        //表为空返回false 
        return false;
    }
    int min = L.data[0];    //假设第一个元素的值最小 
    int pos;               //最小元素的位置 
    for(int i = 0; i < L.length; i++){
        if(L.data[i] < min){       //如果线性表中有比min更小的,交换它们 
            swap(min, L.data[i]);
            pos = i;              // 交换一次,记录一次最小元素的位置 
        }
    }
    L.data[pos] == L.data[Length - 1];    //那个位置用最后一个元素补充 
    L.length--;
    return true;

 
/*双指针 反向 
第二题 
*/

void Reverse(SqList &L){
    int left, right;   //指向表头表尾的指针 
    
    for(int left = 0; right = L.length - 1; left < right; left ++, right--){   //两头指针向中间移动,如果前面的比后面的大,交换它们 
        if(L.data[left] < L.data[right]){
            swap(L.data[left], L.data[right]);
        }
    }

//第三题  双指针 同向 
void DelX(SqList &L, int x){
    int i, j = 0;           //初始化同向指针的位置为0 
    while(j < L.length){   
        if(L.data[j] != x){   //如果 J 所指的值不等于x ,就让两个指针同时向前移动 ,否则只让 J向前移动,最后返回 i  
            L.data[i++] = L.data[j++];
        }else{
            j++;
        }
        
    }
    return i;

//第四题 
void DelXs(SqList &L, int s, int t){
    if(s < 0 && t > L.length && t < s){  //位置不合法 
        return false;
    }
    int i, j;                             
    for(int i = 0; i < L.length - 1; i++){    
        if(L.data[i] > s)     //寻找值大于s的第一个元素 
        int left = i;
    }
    for(int j = 0; j < L.length - 1; j++){
        if(L.data[j] > t)     //寻找值大于t的第一个元素 
        int right = j;
    }
    for(;j < L.length; i++, j++){   //前移,填补删除元素的位置 
        L.data[i] = L.data[j];
    }
    return true;
}

//第六题 双指针(同向) 
void RemoveDup(SqList &L){
    int i, j = 0;    //初始化同向双指针的位置 
    while(j < L.length){
        if(i == 0 || L.data[j] != L.data[i - 1])   //如果发现重复元素, 让 j ++ ,如果没有发现重复元素,让 i和 j 都 ++ 
          L.data[i++] = L.data[j++]; 
        else
          j++;
    }
    return i;
}

//第七题   归并排序思想   (不多解释) 
bool Merge(SqList A, SqList B, SqList &C){
    int i, j, k = 0;
    if(A.length + B.length > C.Maxsize)
       return false;
    
    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;
}

//第八题(妙)
//先交换整个线性表,再对前n个和后m个使用逆置算法 

void REVS(SqList &A, int left, int right){
    int left, right;
    
    for(int left = 0; right = L.length - 1; left < right; left ++, right--){
            swap(L.data[left], L.data[right]);
    }

void change(SqList& A){
    REVS(A, 0, m + n - 1);  //将整个表反转  表 1 长度为 m ,表2长度为 n 
    REVS(A, 0, n - 1);  //将在前面的表2逆转
    REVS(A, n, m + n - 1);  //m + n - 1中包含了 m 个元素 
}

//第九题
void Search(int A[], int x){    //先使用二分查找查找元素x 
    int low = 0;
    int high = L.length - 1;
    int mid;
    
    while(low <= high){
        mid = (low + high) / 2;
        if(A[mid] > x){
            high = mid - 1;
        }else if(A[mid] < x){
            low = mid + 1;
        }
    }
    
    if(A[mid] == x && mid != n - 1)   //若交换后一个元素与x值相等,则不存在与其后继交换的操作 
        swap(A[mid],A[mid + 1]);
        
    if(low > high){
        for(int i = n -1; i > high; i--){   //查找失败 , 插入x 
            A[i + 1] = A[i];
            A[i + 1] = x;
        }
    }    

 

//第十题
//把数组看成2部分,A中元素再前面,A中有P个元素,B中元素在后面,左移P个位置, 相当于将A 、B逆置 ,再整体取逆 ( AB --> BA ) 
void Reverse1(int R[ ], int r, int l){
    for(int i = 0; i < l - r; i++){
        swap(R[i + r], R[l - i]);
    }

void MoveLeft(int R[], int n, int p){
    Reverse1(R, 0, p - 1);
    Reverse1(R, p, n - 1);
    Reverse1(R, 0, n - 1);
}

// 第十一题
//使用归并排序的思想进行合并数组,再找出中位数,优化:仅进行判断,不进行排序,仅按顺序进行访问,访问 [L / 2]后为所求降低空间复杂度 

void Merge(int A[], int B[], int &C[]){
    int i, j, k = 0;
    
    while(L1.data[i] < L2.data[j]){
        L3.data[k++] = L1.data[i++];
        
    }
    while(L1.data[i] > L2.data[j]){
        L3.data[k++] = L2.data[j++];
    }
    
    while(i < L1.length){
        L3.data[k++] = L1.data[i++];
    }
    while(j < L2.length){
        L3.data[k++] = L2.data[j++];
    }

// 求出中位数 
int Mid(int C[]){
    
    int mid;
    int n = L.length;
    if(n % 2 == 0){
        mid = (C[n / 2] + C[n / 2 - 1] ) / 2;
    }else{
        mid = C[(n - 1)/ 2];
    }
    
    
    return mid;
    
}
 
//第十二题
int MajorElm(int A[],int n){
    int tmp = A[0];
    int count;
    for(int i = 1; i <= n; i++){
        if(A[i] == tmp)
          count++;
          //记录下一个元素的时候先要清空count 
    }else{                   //处理的不是主元素的情况 
    if(count > 0)
       count--;
    else{                      //妙啊,这里统计的count不是最终的count值,遇到的下一个整数 = tmp ,计数器加一 ,遇到的下一个整数 != tmp 计数器减一 
       tmp = A[i];
       count = 1;
      }   
    }
    
    if(count > 0){    //统计主元素实际出现的次数 
        count = 0;
        for(int i = 0; i < n; i++){
            if(A[i] = tmp)
               count++;
        }
    }
    if(count > n / 2)
      return tmp;
    else
      return -1;  
}
 
//第十三题
//采用空间换时间的策略 

int MaxPositiveNum(int A[], int n){
    int *B;
    B = (int*)malloc(sizeof(int) * n);
    memset(B, 0, sizeof(int) * n);
    
    for(int i = 0; i < n; i++){   //标记数组B 
        if(A[i] > 0 && A[i] < n)
          B[A[i] - 1] = 1; 
    }
    for(int i = 0; i < n; i++){
        if(B[i] == 0)
          break;        
    }
    return i + 1;

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值