数据结构-王道课后题-线性表(1)

 顺序表

1. 从顺序表中是删除最小元素,并返回该元素的值空出位置由最后一位填充。

bool Delete_min(sqList &L, ElemType &value){
    if(L.length<=0){
        //表为空,直接返回
        return false ;
    }
    value=L.data[0];
    int pos=0;
    for(int i=0;i<L.length;i++){
        //找到最小值后,记录数据和位置
        if(L.data[i]<value){
        pos = i;
        value = L.data[i];
        }

    }
    L.data[pos]=L.data[L.length-1];
    L.length--;//将最后一位填补到pos后,最后一位就不用了
    return true;
}

2. 将顺序表L所有元素逆置,并要求算法空间复杂度为O(1)。

//由于限制了空间复杂度,所以不能创建新的线性表用来逆向存储
//直接设置起点和终点两个标志位,在原数组的基础上交换
void Reverse(sqList &L){
    int i=0;
    int j=L.length-1;
    ElemType temp=0    
    for(;i>=j;i++,j++){
        temp = L.data[i];
        L.data[i] = L.data[j];
        L.data[j] = temp;    
        //每次计算完后,i,j也要自增
    }
    /*只用一个变量
    for(i=0;i<L.length/2;i++){
        tmep = L.data[i];
        L.data[i]=L.data[L.length-i-1];
        L.data[L.length-i-1]=temp;
     }
    */
}

 3. 对长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有的值为X的数据元素。

bool Delete_x(sqList &L, ElemType x){
    //遍历每个元素,若之前无x则不动
    //若前面有i个,移动i次
    //移动的实现是通过差值实现的    
    int k=0;//通过k记录不等于x的个数,最后也是线性表的长度
    for(int i=0;i<L.length;i++){
    //每次i都会递增,如果x=data[i],k就不会递增,也就会产生差值,也就是x的个数
        if(L.data[i!=x]){
            //当前方无x时,i=k,相当于没有移动
            //当前方有x时,i!=k,他们之间的差值,就是要移动的个数
            L.data[k]=L.data[i];        
            k++;
    }
    L.length = k;

}
//方法二
void del_x_2(sqList &L){
    int k=0,i=0;
    while(i<L.length){
        if(L.data[i]=x){
            k++;//k为x的个数
        }
        else{
            L.data[i-k]=L.data[i];//直接对每个元素向前位移k位
        }
        i++;
    }
    L.length=L.length-k;

}

 4. 从有序顺序表中删除其给定值s与t之间的所有元素,如果s或t不合理则退出

//由于有序,因此删除s,t之间就是将t之后的元素移动到s之后
bool del_st(sqList &L,ElemType s,ElemType t){
    if(s>t||L.length==0){
        //违规范围直接返回
        return false
    }
    int i,j;
    //使用i记录大于t的第一个数的位置,
    for(i;i<L.length&&L.data[i]<=t;i++);
    //使用j记录大于等于s的第一个数的位置
    for(j;j<L.length&&L.data[j]<s;j++)
    while(i<L.lenght){
        L.data[j++] = L.data[i++];
    }
    L.length = j;
    return true
}

 5. 从顺序表中删除给定的s到t之间的所有元素

//与删除所有的x类似,唯一不同是判断条件
bool del_st_h(sqList &L,ElemType s,ElemType t){

    int i,k=0;
    if(s>t||L.length==0){
        return false;
    }
    while(i<L.length){
        if(L.data[i]<t&&L.data[i]>s){
            //计算出有多少个差值
            //用于接下来的位移
            k++;
        }
        else{
            //类似于之前的删掉所有x
            L.data[i-k]=L.data[i];
         }
     i++;
     }
     L.length -=k;
     return true;

}

6. 从有序表中删除所有重复的元素

//审好题,是有序表,因此重复的都堆在一起了
//如果该表是无序的,就应使用散列表
bool delete_Same(sqList &L){
    if(L.length==0){
        return false;
    }
    for(i=0,j=1;j<L.length;j++){
        if(L.data[i]!=L.data[j]){
            L.data[++i]=L.data[j];
        //++i也可在if内写成i++;总之重复的元素个数就是j-i
        //通过i,j的差值来实现在遍历的同时移动到对应的位置    
        }
    }
    L.length = i+1;
    return true;
}

7. 将两个有序顺序表合并为一个新的有序顺序表

bool Merge(sqList &A,sqList &B,sqList &C){
    if(A.length+B.length>C.MaxSize){
        return false;
    }
    //ABC三个顺序表各自使用自己的变量
    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++];
        }
     }
    //当一个表都添加完后,剩余的直接全部加到c的末尾即可
     while(i<A.length){
        C.data[k++] = A.data[i++];    
    }
    while(i<B.length){
        C.data[k++] = B.data[j++];
    }

    C.length = k;
    return true;
}

8. 将数组A[m+n] (a1,,,am,b1...bn)转换为(b1...bn,a1...am)

//三次逆置即可,先整体逆置,然后将b部分逆置,最后a部分逆置即可
//传参数注意不要出错即可
typedef int DataType;
void Reverse(DataType A[] ,int left,int right,int arraySize){
    if(left>=right||right>=arraySize)
        return ;
    int mid = (left+right)/2;
    for(int i=0;i<mid-left;i++){
        DataType temp = A[left+i];
        A[Left+i] = A[right-i];
        A[right-i] = temp;
    }
}
void Exchange(DataType A[],int m,int n,int arraySize){
    Reverse(A,0,m+n-1,arraySize);
    Reverse(A,0,n-1,arraySize);
}

9. 折半查找

//注意折半查找的条件是有序
void search(ElemType A[],ElemType x){
    int low =0,high=n-1,mid;
    while(low<high){
        mid = (low+high)/2;
        if(A[mid]==x){
            break;
        }    
        else{//折半
            if(A[mid]<x){
                low = mid+1;
            }   
            else{
                high=mid-1;
            } 
        }
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_40693859/article/details/94281592
今日推荐