鱼C论坛

 找回密码
 立即注册
查看: 4047|回复: 0

[学习笔记] 数据结构顺序线性表的例题算法2.2——C语言完整实现

[复制链接]
发表于 2021-9-23 17:54:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 兔子不吃窝边草 于 2021-10-2 16:39 编辑

        已知线性表La,Lb的数据元素是升序排列。将La与Lb合并为一个新的表Lc,Lc中的数据元素也是升序排列。La=(3,5,8,11),Lb=(2,6,8,9,11,15,20)
        求出来的Lc=(2,3,5,6,8,9,11,11,15,20)
               
                        动态数组的插入ListInsert(),加入了判断是否满的情况,因此不用担心溢出的问题。
               
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define ListInitsize 20//初始分配内存数
  4. #define OVERFLOW -2 //异常状态
  5. #define ADD 10        //分配内存增量
  6. typedef struct
  7. {
  8.         int *data;//顺序线性表动态数组名
  9.         int length;//线性表长度
  10.         int Listsize;//线性表当前分配的内存数量;
  11. }List;
  12. int InitList(List *L)//线性表初始化
  13. {
  14.         L->data =malloc(ListInitsize*sizeof(int));//分配内存
  15.         if(!L->data)
  16.                 exit(OVERFLOW);//分配内存失败,则退出。
  17.         L->length = 0;
  18.         L->Listsize = ListInitsize;// 线性表内存为初始化内存数。
  19.         return 1;
  20. }
  21. int GetElem(List *L,int i,int *e)//获取线性表第i个元素
  22. {
  23.        
  24.         if(i<1||i>L->length)//若i不在范围内,则退出。
  25.         return 0;
  26.         *e = L->data[i-1];
  27.         return 1;       
  28. }
  29. int ListInsert(List *L,int i,int e)//插入e至第i个元素位置,需要将i个元素至最后一个元素向后移动一个位置
  30. {
  31.         int *p=malloc(sizeof(int));
  32.         int *q=malloc(sizeof(int));
  33.         int *newbase; //新分配的动态数组名
  34.         if(i<1||i>L->length+1)//若插入位置在最后一个元素的后一个元素之后也要退出
  35.                 return 0;
  36.         if(L->length>=L->Listsize)//判定分配内存空间是否满或溢出了。
  37.         {
  38.                 newbase = realloc(L->data,(L->Listsize+ADD)*sizeof(int));//若满或溢出就重新分配内存 ,将原来的内存空间增加ADD个单位
  39.                 if(!newbase)
  40.                 exit(OVERFLOW);//分配内存失败,则异常退出。
  41.                 L->data = newbase;//新的内存首地址为newbase,将它赋值给data。
  42.                 L->Listsize += ADD;//性表当前分配的内存为原来的增加ADD。
  43.         }
  44.         q= &L->data[i-1];        //将q指向第i个元素。
  45.         for(p=&L->data[L->length-1];p>=q;p--)        //p初始化指向数组最后一个元素,依次递减至指向第i个元素。
  46.                 *(p+1) = *p;//依次将最后一个元素到第i个元素的值,赋给最后一个元素的后一个元素到 i+1个元素。
  47.                                         //相当于i到最后一个元素整体后移一位。        
  48.         *q =e;                        //将e插入第i的位置。
  49.         L->length++;        //线性表的长度增加1。
  50.         return 1;
  51. }
  52. int ListDelete(List *L,int i,int *e)//删除线性表的一个元素,本题用不到。
  53. {
  54.         int *p=malloc(sizeof(int));
  55.         int *q=malloc(sizeof(int));
  56.         if(i<1||i>L->length)
  57.         return 0;
  58.         p = &L->data[i-1];//指向第i个元素的指针。
  59.         *e = *p;                        //将其值保存在*e中。
  60.         q = L->data+L->length-1;//指向最后一个元素的指针。
  61.         for(++p;p<=q;p++)
  62.                 *(p-1) = *p;//将第i+1个元素到最后一个元素向前移动一个位置。
  63.         L->length--;
  64.         return 1;
  65. }
  66. int ListLength(List L)//获取线性表长度
  67. {
  68.         return L.length;
  69. }

  70. void MergeList(List La,List Lb,List *Lc)//将La与Lb中的元素按从小到大的顺序插入到Lc中,从大到小也行,改一下比较符就行。
  71. {
  72.         int i=1,j=1,k=0;                                //i,j,k分别为在表la,lb,lc的位置,即第几个元素,i,j初始化为第一个元素。k初始化为第一个元素之前的位置,后面自增用前缀。
  73.         int La_len,Lb_len,ai,bj;
  74.         InitList(Lc);       
  75.         La_len = ListLength(La);
  76.         Lb_len = ListLength(Lb);
  77.         while(i<=La_len&&j<=Lb_len)        //依次从La和Lb中读取较小的元素插入到 Lc中。
  78.         {
  79.                 GetElem(&La,i,&ai);
  80.                 GetElem(&Lb,j,&bj);
  81.                 if(ai<=bj)       
  82.                 {
  83.                         ListInsert(Lc,++k,ai);
  84.                         i++;
  85.                 }
  86.                 else
  87.                 {
  88.                         ListInsert(Lc,++k,bj);
  89.                         j++;
  90.                 }
  91.         }
  92.         while(i<=La_len)                //当Lb的元素都插入完了,剩下的La的元素依次读取并插入到Lc中。
  93.         {
  94.                 GetElem(&La,i++,&ai);//注意结束上面的循环后,若是Lb的元素插入完,i指向的元素还没有插入到Lc中,因此i自增是后缀。
  95.                 ListInsert(Lc,++k,ai);
  96.         }
  97.         while(j<=Lb_len)                //这是La插入完的情况,这两个只会执行一个因为有一个是插入完的。
  98.         {
  99.                 GetElem(&Lb,j++,&bj);
  100.                 ListInsert(Lc,++k,bj);
  101.         }
  102. }
  103. int main()
  104. {
  105.         int i,e;
  106.         List La,Lb,Lc;
  107.         InitList(&La);
  108.         InitList(&Lb);
  109.         printf("创建链表La\n");
  110.         for(i=0;i<4;i++)
  111.         {
  112.                 scanf("%d",&e);
  113.                 ListInsert(&La,i+1,e);
  114.         }
  115.         printf("创建链表Lb\n");
  116.         for(i=0;i<7;i++)
  117.         {
  118.                 scanf("%d",&e);
  119.                 ListInsert(&Lb,i+1,e);       
  120.         }                //如题创建线性表La,Lb。
  121.         printf("数量:%d\n",ListLength(La)+ListLength(Lb));//新的线性表Lc的元素数量,这里是做一个验证,La与Lb的元素数量和与下面打印的数量应该相同。
  122.         MergeList(La,Lb,&Lc);
  123.         for(i=1;i<=Lc.length;i++)
  124.         {
  125.                 GetElem(&Lc,i,&e);
  126.                 printf("%d ",e);
  127.         }//依次打印新的线性表的元素。
  128.         return 0;
  129. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-12 15:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表