回 帖 发 新 帖 刷新版面

主题:[讨论]顺序表合并的简单问题

这是我最近找出来的题目 想用和书上不同的方式写写 但好像一到合并函数部分就出错
希望各位帮忙看看 指教指教 就是合并函数那块 看看怎么改 那个 题目是:将两个升序顺序表合并成一个升序表
#include"stdio.h"
#define MAXSIZE 100
typedef int ElemType;
typedef struct
{ ElemType *data;
  int listsize;
  int length;
}sqlist;

void creslist(sqlist *L)           /*初始化表*/
{ L->data=(ElemType *)malloc(sizeof(ElemType) *MAXSIZE);
  L->length=0;
  L->listsize=MAXSIZE;
}

void combine(sqlist *L1,sqlist *L2,sqlist *L) /*合并函数*/
{ int i,j,k;
  k=L1->length+L2->length;        /*k是用来得到L的表长的*/
   for(i=L1->length-1;i>=0;i--)    /*这两个循环是用来判断
     for(j=L2->length-1;j>=0;j--)    哪个数大就将那个放到
      { if(L1->data[i]>=L2->data[j]) L表的尾部,故K在此有 
      L->data[k]=L1->data[i];         用*/         
    else
      L->data[k]=L2->data[j];
    k--;L->length++;          
       }
     if(L1->length<L2->length)                 
    while(j) {L->data[k]=L2->data[j];--j;--k;L->length++;}/*这里我是想将    
     else                           剩余的表中的    
    while(i) {L->data[k]=L1->data[i];--i;--k;L->length++;}  元素放到L中,
}                           即收尾工作*/    

void inputlist(sqlist *L)        /*输入*/
{ int i,k;
  printf("please input the K and numbers: \n");
  scanf("%d",&k);
  if(k>L->listsize) printf("Sorry,it is overflow\n");
  else
    for(i=1;i<=k;i++)
     { scanf("%d",&L->data[i-1]);
       L->length++;
     }
}

void outputlist(sqlist *L)        /*输出*/
{ int i;
  for(i=1;i<=L->length;i++)
   printf("%d,",L->data[i-1]);
  printf("\n");
}

main()
{ sqlist L1,L2,L3;
  creslist(&L1);
  creslist(&L2);
  creslist(&L3);
  inputlist(&L1);
  inputlist(&L2);
  combine(&L1,&L2,&L3);
  outputlist(&L1);
  outputlist(&L2);
  outputlist(&L3);
}

回复列表 (共4个回复)

沙发

这问题 我想还是注释下好吧 可是 我自己就是还想不出来啊 到底怎样改合并部分才对 只要给我一小点指点就行了

板凳

for(i=L1->length-1;i>=0;i--)    /*这两个循环是用来判断
     for(j=L2->length-1;j>=0;j--)    哪个数大就将那个放到
      { if(L1->data[i]>=L2->data[j]) L表的尾部,故K在此有 
      L->data[k]=L1->data[i];         用*/         
    else
      L->data[k]=L2->data[j];
    k--;L->length++;          
       }

在这个for(j=L2->length-1;j>=0;j--)中j会变小 L2从尾到头的遍历 
但i是不会变的 每当L1->data[i]>=L2->data[j] 时  L1->data[i]会被重复的放入L中
如果要修改就要在L1->data[i]>=L2->data[j]后面加上 break;

3 楼

虽然给的分较低 但是 我很感谢你 我知道怎样改啦 是两个循环处出错了 等我改好了 再放上来

4 楼

这是修改以后的合并函数部分 之前的函数写错的原因有几点:先是L3表的元素放置应从K-1开始,而不是K;接着循环部分 如上面的朋友所说的 这是for复合循环没用好的问题 即在总循环结束前 K的值就已经不够用了 而导致内部出错 结束程序 可要根据上面那位朋友说的用break 跳出该循环后 值的输入就不对了 因此我改过后的为这样:
void combine(sqlist *L1,sqlist *L2,sqlist *L)
{   int i=L1->length-1,j=L2->length-1,k;
    creslist(L);
    L->length=L1->length+L2->length;
       k=L->length-1;
    while(i>=0&&j>=0)
      { if(L1->data[i]>=L2->data[j])
     { L->data[k]=L1->data[i];--k;i--;}
    else
     { L->data[k]=L2->data[j];--k;j--;}
       }
    while(j>=0) {L->data[k]=L2->data[j];--k;--j;}
    while(i>=0) {L->data[k]=L1->data[i];--k;--i;}
}
在此 谢谢上面那位朋友的提醒

我来回复

您尚未登录,请登录后再回复。点此登录或注册