zoukankan      html  css  js  c++  java
  • 考研数据结构-顺序表(综合应用2)

    本节代码主要来自王道单科18页的综合应用题。

    四、从有序顺序表中删除其值在给定值s与t之间(要求s<t)的所有元素。如果s与t不合理或者顺序表为空则显示出错信息并退出运行

    找到第一个比s大的元素的位置。(和下面那道题的区别就是是否有序)

    核心代码:

    bool DeleteElemBetweenST(Sqlist &L,int s,int t){
        if(L.length==0||t<=s)return false;
        int i=0,j;
        while(i<=L.length-1&&L.data[i]<s)i++;  //找到第一个>=s的位置 ,即为i 
        if(i>L.length-1)return false;
        j=i;
        while(j<=L.length-1&&L.data[j]<=t)j++;  //找到第一个>t的位置 ,即为j 
        //也可以用for循环  for(j=i;j<=L.length-1&&L.data[j]<=t;j++);
        int count=j-i;
        for(int k=j;k<=L.length-1;k++){
             L.data[k-count]=L.data[k];    
        }
        L.length-=count; 
    } 

    也可以不用count统计个数,不用新定义k来遍历。

        for(;j<=L.length-1;j++){
            L.data[i]=L.data[j];    
        } 
        L.length=i+1;

    五、从顺序表中删除其值在给定值s与t之间(要求s<t)的所有元素。如果s与t不合理或者顺序表为空则显示出错信息并退出运行

    找到第一个比s大的元素的位置。

    这道题一看就和第三道题差不多。

    核心代码:

    bool DeleteElemBetweenST2(Sqlist &L,int s,int t){
        if(L.length==0||t<=s)return false;
            int count=0;
        for(int i=0;i<L.length;i++){
            if(L.data[i]>=s&&L.data[i]<=t)
                count++;
            else
                L.data[i-count]=L.data[i];
        } 
        L.length-=count;  
        return true;
    } 

    六、从有序顺序表中删除所有其值重复的元素,使表中所有的值均不同。

    我的做法:从上面删除值为x的元素得到启示,用count来指代所要删除元素的个数。不符合要求时运行L.data[i-count]=L.data[i]。

    当元素与后一个元素相同时,说明存在相同元素,count++。

    第一种:(与书上的做法不同)

    bool DeleteSameElem1(Sqlist &L){
        if(L.length==0)return false;
        int count=0;
        for(int i=0;i<=L.length-1;i++){
            if(L.data[i]==L.data[i+1]){
                count++;
            }
            else{
                L.data[i-count]=L.data[i];
            }
        }
        L.length-=count;
        return true;
    }

    第二种:与书上的做法基本可以说一样,只是变量不同而已

    bool DeleteSameElem2(Sqlist &L){
        if(L.length==0)return false;
        int count=0;
        for(int i=0;i<L.length-1;i++){
            if(L.data[i]!=L.data[i+1]){
                L.data[++count]=L.data[i+1];   //注意覆盖位置要从L.data[1]开始,否则第一个元素会被覆盖掉。 
                //而且覆盖的元素应该来自后一个。否则最后面的元素会与倒数第二个一样。 
            }
        }
        L.length=count+1;        //注意count会被少算一次,因为假设不相同的元素有5个,但它比较的次数只有4 个 
        return true;
    }

    第三种:即书上的做法

    bool DeleteSameElem3(Sqlist &L){
        if(L.length==0)return false;
        int i,j;
        for(i=0,j=1;j<L.length;j++){
            if(L.data[i]!=L.data[j]){
                L.data[++i]=L.data[j];
            }
        }
        L.length=i+1;
        return true;
    }

    思维扩展:如果把只要存在相同元素的就全部删除,如2 2 3 3 4 5删除以后为4 5。

    bool DeleteSameElem1(Sqlist &L){
        if(L.length==0)return false;
        int count=0;
        ElemType x;
        for(int i=0;i<=L.length-1;i++){
            if(L.data[i]==L.data[i+1]){
                x=L.data[i]; 
                count++;
            }
            else if(L.data[i]==x)count++;
    else{
                L.data[i-count]=L.data[i];
            }
        }
        L.length-=count;
        return true;
    }

    以下是以上三道题的全部测试代码(可直接运行):

    #include<stdio.h>
    #define true 1
    #define false 0
    #define MaxSize 100        
    #define ElemType int
    #define Status int 
    
    
    typedef struct{
        ElemType data[MaxSize];       
        int length;            
    }Sqlist;
    
    //构造一个空的线性表L 
    void InitList(Sqlist &L){
        L.length=0;
    }
    
    
    bool ListInsert(Sqlist &L,int i,ElemType e){ 
    //将元素e插到顺序表L中第i个位置 
        if(i<1||i>L.length+1)
            return false;
        if(L.length>=MaxSize)
            return false;
        for(int j=L.length;j>=i;j--)
            L.data[j]=L.data[j-1];
        L.data[i-1]=e;
        L.length++;
        return true;
    }
    
    void ListLoad(Sqlist L){
        if(L.length==0){
            printf("当前顺序表为空
    ");
            return;
        }
        printf("当前顺序表元素为:");
        for(int i=0;i<L.length;i++)
            printf("%d ",L.data[i]);
        printf("
    ");
        return;
    }
    
    
    bool DeleteElemBetweenST1(Sqlist &L,int s,int t){
        if(L.length==0||t<=s)return false;
        int i=0,j;
        while(i<=L.length-1&&L.data[i]<s)i++;  //找到第一个>=s的位置 ,即为i 
        if(i>L.length-1)return false;
        j=i;
        while(j<=L.length-1&&L.data[j]<=t)j++;  //找到第一个>t的位置 ,即为j 
        //也可以用for循环  for(j=i;j<=L.length-1&&L.data[j]<=t;j++);
        int count=j-i;
        for(int k=j;k<=L.length-1;k++){
             L.data[k-count]=L.data[k];    
        }
        L.length-=count;
        
        //也可以不用count统计个数。
    //    for(;j<=L.length-1;j++){
    //        L.data[i]=L.data[j];    
    //    } 
    //    L.length=i+1;
         
    } 
    
    
    bool DeleteElemBetweenST2(Sqlist &L,int s,int t){
        if(L.length==0||t<=s)return false;
            int count=0;//计算元素等于x的个数
        for(int i=0;i<L.length;i++){
            if(L.data[i]>=s&&L.data[i]<=t)
                count++;
            else
                L.data[i-count]=L.data[i];
        } 
        L.length-=count;  
        return true;
    } 
    
    
    //我的做法:从上面删除值为x的元素得到启示,用count来指代所要删除元素的个数。不符合要求时运行L.data[i-count]=L.data[i]。
    
    //当元素与后一个元素相同时,说明存在相同元素,count++,并先记录这个元素,便于统计最后一个与后面的值不相同的元素。
    bool DeleteSameElem1(Sqlist &L){
        if(L.length==0)return false;
        int count=0;
        ElemType x;
        for(int i=0;i<=L.length-1;i++){
            if(L.data[i]==L.data[i+1]){
                x=L.data[i]; 
                count++;
            }
            else if(L.data[i]==x)count++;
            else{
                L.data[i-count]=L.data[i];
            }
        }
        L.length-=count;
        return true;
    }
    
    bool DeleteSameElem2(Sqlist &L){
        if(L.length==0)return false;
        int count=0;
        for(int i=0;i<L.length-1;i++){
            if(L.data[i]!=L.data[i+1]){
                L.data[++count]=L.data[i+1];   //注意覆盖位置要从L.data[1]开始,否则第一个元素会被覆盖掉。 
                //而且覆盖的元素应该来自后一个。否则最后面的元素会与倒数第二个一样。 
            }
        }
        L.length=count+1;        //注意count会被少算一次,因为假设不相同的元素有5个,但它比较的次数只有4 个 
        return true;
    }
    
    bool DeleteSameElem3(Sqlist &L){
        if(L.length==0)return false;
        int i,j;
        for(i=0,j=1;j<L.length;j++){
            if(L.data[i]!=L.data[j]){
                L.data[++i]=L.data[j];
            }
        }
        L.length=i+1;
        return true;
    }
    
    int main(){
        Sqlist T;
        ElemType e,s,t;
        int a,i;
        InitList(T);
        ListInsert(T,1,5);
        ListInsert(T,1,5);
        ListInsert(T,1,5);
        ListInsert(T,1,4);
        ListInsert(T,1,4);
        ListInsert(T,1,4);
        ListInsert(T,1,2);
        ListInsert(T,1,1);    
        ListInsert(T,1,1);    
        ListLoad(T);
        while(1){
            printf("1:删除值在s与t之间的元素(有序)
    ");  //DeleteElemBetweenST1
            printf("2:删除值在s与t之间的元素(无序)
    ");   //DeleteElemBetweenST2 
            printf("3:删除所有的相同元素(方法1)
    ");  //DeleteSameElem1
            printf("4:删除所有的相同元素(方法2)
    ");  //DeleteSameElem2 
            printf("5:删除所有的相同元素(方法3)
    ");  //DeleteSameElem3
            printf("请选择:");
            scanf("%d",&a); 
            switch(a){
                case 1:scanf("%d %d",&s,&t);
                        if(DeleteElemBetweenST1(T,s,t))printf("删除成功
    ");
                        else printf("删除失败
    "); 
                        break;
                case 2:scanf("%d %d",&s,&t);
                        if(DeleteElemBetweenST2(T,s,t))printf("删除成功
    ");
                        else printf("删除失败
    "); 
                        break;
                case 3:if(DeleteSameElem1(T)) printf("删除成功
    ");
                        else printf("删除失败
    "); 
                        break;
                case 4:if(DeleteSameElem2(T)) printf("删除成功
    ");
                        else printf("删除失败
    "); 
                        break;
                case 5:if(DeleteSameElem3(T)) printf("删除成功
    ");
                        else printf("删除失败
    "); 
                        break;        
                default:return 1;
            }
            ListLoad(T);
        } 
    } 


    删除值在s与t之间的元素(有序):

    删除值在s与t之间的元素(无序):

    删除所有的相同元素(方法1):
    删除所有的相同元素(方法2):

    删除所有的相同元素(方法3):
     
    
    
    
  • 相关阅读:
    linux最简单项目部署
    sql索引
    /etc/profile和~/.bash_profile区别
    Linux下查找软件的目录位置
    为什么要使用消息队列?
    idea中常用的快捷键
    PAT 甲级 1023 Have Fun with Numbers (20分)
    PAT《算法笔记》
    Text 2
    Text-1
  • 原文地址:https://www.cnblogs.com/double891/p/9125735.html
Copyright © 2011-2022 走看看