链表(提高)-数据结构(一)

自己理解,方便自己21考研使用

目前在通过西北大学的耿国华老师的上课课程实录视频在学习数据结构。在链表的提高课程上给出了三个习题,分别为:

1.分解链表奇和偶两部分,前半部分为奇数,后半部分为偶数,算法复杂度要求为O(1)。

2.单链表就地逆置

3.二进制数加1运算

本篇先介绍第一个问题:

(一)前提知识

首先是顺序表的定义,应该为:

#define MAXSIZE 100
typedef struct    //定义了数组类型结构,实现顺序存储
{
 int elem[MAXSIZE];
 int last;  //就是数组的最大下标
}SeqList;
SeqList L; //实例化一个结构体

定义了一个结构体,在对顺序表的操作,也仅仅是对这一个结构体中的数组进行操作,不同于单链表有多个结构体,每个结构体串联形成一个表。

注意:下面语句:

SeqList *p=&L;

意思是定义一个上面定义的结构体类型的指针,全程代码视线中,也仅仅就此一个指针,这个指针指到上面的结构体,通过这个指针就可做到访问数组elem[]与last的值的操作。通过下面语句访问:

p->elem[i];   //访问数组elem[]中,下标为i的值
p->last;    //访问last

(二)实现算法

本题目需要实现奇数与偶数分两边存储,其实现代码如下:

AdjustSqlist(SeqList *L)/*利用顺序表调整其为左右两部分,左边的为奇数,右边的为偶数*/
{
 int i=0,j=L->last;
 int t;
 while(i<j) 
 {
  while(L->elem[i]%2!=0)
   i++;
  while(L->elem[j]%2==0)
   j--;
  if(i<j)
  {
   t=L->elem[i];
   L->elem[i]=L->elem[j];
   L->elem[j]=t;
  }
 }
}

代码解释:
由于题目要求复杂度为O(1),故也就是说复杂度就是访问一遍就能得出结果,故选择以此算法来实现。
代码中定义了变量i 与变量j,其初始为这个数组的第一个元素的下标与最后一个元素的下标。
左边的变量i用于寻找偶数,找到偶数,停下来;见了奇数就往后移动一位;这样变量i,前面的就能保证全是奇数。
右边的变量j用于寻找奇数,找到奇数,停下来;见了偶数就往前移动一位:这样变量j,后面的就能保证全是偶数。

使用while循环,当i找到第一个偶数,j找到第一个奇数时,停下来时,对这两个数进行交换。
交换过后,继续寻找,找到继续交换
什么时候停下来呢?

在i>j的时候,因为此时,说明i与j已经相交,也就说明实现了对全数组的遍历和操作。那实现了这些,数组真的就是左边奇数,有边偶数吗?

是的,因为变量i,前面的就能保证全是奇数。变量j,后面的就能保证全是偶数。
一重合就表明已经实现了要求。

(三)完整代码

/*利用顺序表调整其为左右两部分,左边的为奇数,右边的为偶数*/
#define MAXSIZE 100
typedef struct    //定义了数组类型结构,实现顺序存储
{
 int elem[MAXSIZE];
 int last;  //就是数组的最大下标
}SeqList;

AdjustSqlist(SeqList *L)/*利用顺序表调整其为左右两部分,左边的为奇数,右边的为偶数*/
{
 int i=0,j=L->last;
 int t;
 while(i<j) 
 {
  while(L->elem[i]%2!=0)
   i++;
  while(L->elem[j]%2==0)
   j--;
  if(i<j)
  {
   t=L->elem[i];
   L->elem[i]=L->elem[j];
   L->elem[j]=t;
  }
 }
}


void main()//主函数
{
    SeqList l;
 int p,q,r,i,j;
 printf("请输入线性表的长度:");
 scanf("%d",&p);
 l.last=p-1;
 printf("/n请输入线性表中各元素的值:");
 for(i=0;i<=l.last;i++)
 scanf("%d",&l.elem[i]);

 AdjustSqlist(&l);//参数为指向结构体l的指针

 printf("/n调整后的顺序表为");
 for(i=0;i<=l.last;i++)
 //scanf("%d",&l.elem[i]);
 printf("%d ",l.elem[i]);

}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验一 线性及其应用 一、 实验目的和要求 1、掌握线性的插入、删除、查找等基本操作设计与实现 2、学习利用线性提供的接口去求解实际问题 3、熟悉线性的的存储方法 二、 实验内容和原理 1、实验内容:设计一个一元多项式的简单计算器,其基本功能有①输入并建立多项式;②输出多项式;③多项式相加。可利用单链表或单循环链表实现之。 2、实验原理:以线性来描述一元多项式,存储结构采用单链表,每个结点存储的多项式中某一项的系数和指数,建立单链表时指数高的结点列于指数低的 结点之后,即线性的元素按指数递增有序排列。 三、 实验环境 Visual C++ 6.0 及PC机 四、 算法描述及实验步骤 思想算法: 以线性来描述一元多项式,存储结构采用单链表,每个结点存储的多项式中某一项的系数和指数,建立单链表时指数高的结点列于指数低的结点之后,即线性的元素按指数递增有序排列。 例如构造个多项式ha: 5X3+4X2+3X+2 hb: X2+X+1 多项式加法:定义指针p,q分别指向ha,hb i.p->exp==q->exp ,r->coef=p->coef+q->coef,pa,pb下移; ii.p->expexp ,r->coef=q->coef;r->exp=q->exp;,q下移 iii.pa->exp>pb->exp, r->exp=p->exp;r->coef=p->coef;,p下移 iv.p!=NULL,pb==NULL.相当于iii. V.q==NULL,pb!=NULL.相当于ii. 其流程图如下: 多项式乘法:定义指针fp,gp分别指向f,g 1.将多项式最大指数相加并赋于maxp,并置g 2.用for循环求指数等于maxp时相乘的系数 3. (fp!=NULL)&&(gp!=NULL), p=fp->exp+gp->exp 1.p>maxp, fp=fp->next; 2. pnext; 3.p=maxp, x+=fp->coef*gp->coef; fp=fp->next;gp=gp->next; 五、 实验结果 1.分别输入个多项式: 5X3+4X2+3X+2 和X2+X+1,然后输出结果如下: 2.分别输入个多项式:6X4+4X2+2和5X+6,然后输出结果如下: 六、 总结 此次上机实验应用了线性实现了一次实际操作,完成了一个一元多项式的简单计算器,不仅对此次编译程序的算法思想有了新的认识,还让我深刻的体会到了线性的重要性以及其应用的方便,并且对指针加深了映象,应用了书本中的算法思想,对我以后的编译以及完成新的程序有很大的帮助。 附录: 1.建立多项式列代码如下: mulpoly *creatpoly()/*建立多项式列*/ {mulpoly *head,*r,*s;/*设中间变量*/ int m,n; head=(mulpoly *)malloc(sizeof(mulpoly));/*头结点申请空间*/ printf("\ninput coef and exp:\n"); scanf("%d%d",&n,&m);/*输入多项式系数和指数*/ r=head;/*尾指针指向头指针*/ while(n!=0)/*将输入的多项式存放在S中*/ {s=(mulpoly*)malloc(sizeof(mulpoly)); s->coef=n; s->exp=m; r->next=s; r=s; /*printf("input coef and exp:\n");*/ scanf("%d%d",&n,&m);/*再次输入多项式系数和指数*/ } r->next=NULL;/*将尾指针置空*/ head=head->next;/*将head哑结点向前跑一个结点,使其不为空*/ return (head);/*返回多项式*/ } 2.个多项式相加代码如下: mulpoly *polyadd(mulpoly *ha,mulpoly *hb)/*个多项式相加*/ {mulpoly *hc,*p,*q,*s,*r;/*声明结构体型*/ int x; p=ha; q=hb; hc=(mulpoly *)malloc(sizeof(mulpoly));/*申请结点空间*/ s=hc; while((p!=NULL)&&(q!=NULL))/*多项式不为空*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值