线性表:三看一问题

问题:已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。(O(1)表示算法是辅助空间为常数)

解题过程:这问题不难,很快可以写出算法:

void Delete(SqList *L, int item)

{

         int i,j=0;

         for(i=0;i<L->length;i++)

                   if(L->elem[i]!=item)

                            L->elem[j++]=L->elem[i];

                   L->length=j;

}

但书上给出的解法为:

void Delete(SqList *L, int item)

{

         int i=0;

         int j=L->length-1;          //设立数组头尾指针

         while(i<j)

         {

                   while(i<j&&L->elem[i]!=item)

                            i++;               //若值不为item,头指针右移

                   while(i<j&&L->elem[j]==item)

                            j--;               //若值为item,尾指针左移

                   if(i<j)

                            L->elem[i++]=L->elem[j--];

         }

         L->length=j+1;

}

乍一看,并没有看懂(算法似乎很复杂),认真重看一遍,终于搞懂了,不禁一阵狂喜,简单的问题被他搞得这么复杂(三个while循环)。但再仔细想想,其实是两种不同的思路:第一种是将表中不等于item的元素复制到原表中,覆盖原来的数据元素;第二种是从前往后寻找第一个为item的元素,用最后不为item的元素覆盖它。就本题而言,第一种方法应该更简单一些,但第二种不失是一个思路,比如下面这一问题

 

问题:顺序存储的线性表A,其数据元素为整型,试编写一算法,将A拆成BCD三个表,使得A中的负数放入B,零放入C,正数放入D,要求BCD不另外设置而利用A的空间。

程序:

#include<stdio.h>

#include<malloc.h>

#define ListSize 50

 

typedef struct

{

         int *elem;

         int length;

         int listsize;

} SqList;

 

void Initiate(SqList *L)

{

         L->elem=(int *)malloc(ListSize*sizeof(int));

 

         L->length=0;

         L->listsize=ListSize;

}

 

 

void Divide(SqList *A, SqList *B, SqList *C, SqList *D)

{

         int i=0;

         int j=A->length-1;               //设立数组头尾指针

         int k=0,m;

         while(i<j)

         {

                   while(i<j&&A->elem[i]<0)

                            i++;                    //若值为负数,头指针右移

                   while(i<j&&A->elem[j]>0)

                            j--;                    //若值为正数,尾指针左移

                   if(i<j&&A->elem[i]!=0)

                   {

                            m=A->elem[i];

                            A->elem[i]=A->elem[j];

                            A->elem[j--]=m;

                   }

                   else if(i<j&&A->elem[i]==0)

                   {

                            k=i+1;

                            while(k<j&&A->elem[k]==0) 

                                     k++;                     //寻找elem[i]后第一个不为零的元素下标

                            m=A->elem[i];

                            A->elem[i]=A->elem[k];

                            A->elem[k]=m;

 

                            if(k==j)

                                     break;

                   }

         }

 

         if(i==0)                           //如果有负数,放入B

         B->length=0;

         else if(j==A->length-1)

         {

                   B->elem=&A->elem[0];

                   B->length=i+1;

         }

         else

         {

                   B->elem=&A->elem[0];

                   B->length=i;

         }

 

         if(k==0)                           //如果有零,放入C

                   C->length=0;

         else

         {

                   C->elem=&A->elem[i];

                   C->length=k-i+1;

         }

 

         if(j==A->length-1)                 //如果有正数,放入D

                   D->length=0;

         else if(i==0)

         {

                   D->elem=&A->elem[j];

                   D->length=A->length-j;

         }

         else

         {

                   D->elem=&A->elem[j+1];

                   D->length=A->length-j-1;

         }

}

 

 

 

void main()

{

         int i,item;

         SqList AList,BList,CList,DList;

         Initiate(&AList);

 

         for(i=0;i<10;i++)

         scanf("%d",&AList.elem[i]);

         AList.length=10;

    for(i=0;i<AList.length;i++)

                   printf("elem[%d]=%d/n",i,AList.elem[i]);

 

         item=5;

         Divide(&AList,&BList,&CList,&DList);

   

         for(i=0;i<AList.length;i++)

                   printf("A[%d]=%d/n",i,AList.elem[i]);

         for(i=0;i<BList.length;i++)

                   printf("B[%d]=%d/n",i,BList.elem[i]);

         for(i=0;i<CList.length;i++)

                   printf("C[%d]=%d/n",i,CList.elem[i]);

         for(i=0;i<DList.length;i++)

                   printf("D[%d]=%d/n",i,DList.elem[i]);

}

 

运行结果:(从左到右依次是全为0、全为正、全为负和正常情况)

全部正确。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值