实验二 线性表的链式存储结构
线性表的链式存储结构
22
2.3.4 双向循环链表
在循环链表中,访问结点的特点: 访问后继结点,只需要向后走一步,而访问前驱 结点,就需要转一圈。 结论:循环链表并不适用于经常访问前驱结点的 情况。 解决方法:在需要频繁地同时访问前驱和后继结 点的时候,使用双向链表。所谓双向链表。 双向链表就是每个结点有两个指针域。一个指向 后继结点,另一个指向前驱结点。
//寻找第i-1个结点
s=p->next;
//用s指向将要删除的结点
*e=s->data;
p->next=s->next; //删除s指针所指向的结点
free(s);
return OK;
}//P26图2-10。
18
2.3.3 循环链表 若将链表中最后一个结点的next域指向头结点,如下图:
head
带头结点的单链表结构示意图
5
链式存储结构的特点 (1)线性表中的数据元素在存储单元中的存放顺 序与逻辑顺序不一定一致; (2)在对线性表操作时,只能通过头指针进入链 表,并通过每个结点的指针域向后扫描其余结点,这 样就会造成寻找第一个结点和寻找最后一个结点所花 费的时间不等,具有这种特点的存取方式被称为顺序 存取方式。
27
p
s
图 2-9
28
完整的算法:
int DuListInsert(DuLinkList *L,int i,EntryType e)
25
(1)初始化双向循环链表DL int InitDuList(DuLinkList *DL) { DL->head=(DuLNode*)malloc(sizeof(DuLNode));
实验二 链式存储线性表
实验二 链式存储线性表的基本操作一、 实验目的1. 掌握用Turbo C2.0上机调试线性表的基本方法。
2. 掌握线性表的基本操作,插入、删除、查找,以及线性表合并等运算在链接存储结构上的运算。
二、 实验内容1.typedef int ElemType;typedef struct LNode { //创建结构体数据类型LNodeElemType data; //存放数值的数据域struct LNode *next; //存放后继结点地址的指针域}LNode;2. 链表的创建:创建n 个结点,利用scanf( )函数为每个结点的数据域赋值,一次将每个结点插入链表,形成一个包含n 个元素的链表。
#define NULL 0#define OVERFLOW 0#define OK 1#define ERROR -1typedef int ElemType;typedef struct LNode { //创建LNode 数据类型ElemType data;struct LNode *next;}LNode;typedef LNode *LinkList; //定义LinkList 指针型数据类型int CreateList_L(LinkList L, int n) { //创建拥有n 个元素的线性链表//int i;struct LNode *p;L->next = NULL; //线性链表初始化,见右图for (i = n; i > 0; --i) { //循环n 次在头结点和第一个结点间插入新结点,形成长度为n 的线性链表p =(LNode*)malloc(sizeof(LNode));scanf("%d",&p->data);p->next = L ->next;L->next =p;}return 1;}data next data nextl1)2)3)int VistList_L(LinkList L) { //遍历链表L中每个结点的函数struct LNode *p;p = L->next;while (p) {printf("%d ",p->data); //访问输出p结点的数据域p = p->next; } //p指针前进一位,指向后继结点printf("\n");return OK;}}lmain(){int m;LNode l;ElemType e;printf("please input the length of the linklist that you want to build");scanf("%d",&m);printf("please give the number that you want to insert");CreateList_L(&l,m); //调用创建链表函数VistList_L(&l); //调用遍历链表结点函数}3. 链表的插入算法:向链表中某个位置上插入一个结点#define NULL 0#define OVERFLOW 0#define OK 1#define ERROR -1typedef int ElemType;typedef struct LNode { //创建LNode 数据类型ElemType data;struct LNode *next;}LNode;typedef LNode *LinkList;int CreateList_L(LinkList L, int n) { //创建包含n 个元素的链表int i;struct LNode *p;L->next = NULL;for (i = n; i > 0; --i) {p =(LNode*)malloc(sizeof(LNode));scanf("%d",&p->data);p->next = L ->next;L->next =p;}return 1;}int ListInsert_L(LinkList L, int i, ElemType e) { //向链表中第i位插入数据e struct LNode *s,*p;int j;p = ; j = 0; //p指针指向线性链表的头结点while (p && j < ) //循环查找第i-1位作为数据e的插入位置{ p = ; ++j; } //p指针向前移动if (!p || j > i-1)return ERROR;s =(LNode*)malloc(sizeof(LNode)); //见下图1)if ( s == NULL) return ERROR;s-> = e; //将插入数据e的值赋值给s结点的数据域1)s->next = ; p->next = ; //旧链断开,新链产生2)3)return OK;}1)2)3)int VistList_L(LinkList L) { //遍历链表所有结点的函数struct LNode *p;p = L->next;while (p) {printf("%d",p->data);p = p->next; }return OK;}main(){int m;LNode l;ElemType e;int i;printf("please input the length of the linklist that you want to build");scanf("%d",&m);printf("please give the number that the initial list have");CreateList_L(&l,m);VistList_L(&l);printf("please input the positon and data of the insert number i&e");scanf("%d,%d",&i,&e);ListInsert_L(&l,i,e);VistList_L(&l);}附:一元多项式的相加#include<stdio.h>#include<stdlib.h>#define LEN sizeof(node)typedef struct polynode /*用单链表存储多项式的结点结构*/{int coef; /*多项式的系数*/int exp; /*指数*/struct polynode *next; /*next是struct polynode类型中的一个成员,它又指向struct polynode类型的数据,以此建立链表*/}node;/*若定为"node,*list;",意即node*与list同为结构指针类型*/node * create(void) /*指针函数,返回指针类型;用尾插法建立一元多项式的链表的函数*/ {node *h,*r,*s;int c,e;h=(node *)malloc(LEN); /*建立多项式的头结点,为头结点分配存储空间*/r=h; /*r指针始终动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点*/ printf("coef:");scanf("%d",&c); /*输入系数*/printf("exp: ");scanf("%d",&e); /*输入指针*/while(c!=0) /*输入系数为0时,表示多项式的输入结束*/{s=(node *)malloc(LEN); /*申请新结点*/s->coef=c; /*申请新结点后赋值*/s->exp=e; /*申请新结点后赋值*/r->next=s; /*做尾插,插入新结点*/r=s; /*r始终指向单链表的表尾*/printf("coef:");scanf("%d",&c);printf("exp: ");scanf("%d",&e);}r->next=NULL; /*将表的最后一个结点的next置NULL,以示表结束*/return(h);}void polyadd(node *polya, node *polyb)/*一元多项式相加函数,用于将两个多项式相加,然后将和多项式存放在多项式polya中,并将多项式ployb删除*/{node *p,*q,*pre,*temp;int sum;p=polya->next;/*令p和q分别指向polya和polyb多项式链表中的第一个结点*/q=polyb->next;pre=polya; /*位置指针,指向和多项式polya*/while(p!=NULL&&q!=NULL) /*当两个多项式均未扫描结束时,执行以下操作*/{if(p->exp<q->exp) /*若p指向的多项式指数小于q指的指数*/{pre->next=p; /*将p结点加入到和多项式中*/pre=pre->next;p=p->next;}else if(p->exp==q->exp) /*若指数相等,则相应的系数相加*/{sum=p->coef+q->coef;if(sum!=0){p->coef=sum;pre->next=p;pre=pre->next;p=p->next;temp=q;q=q->next;free(temp);}else /*如果系数和为零,则删除结点p与q,并将指针指向下一个结点*/{temp=p->next;free(p);p=temp;temp=q->next;free(q);q=temp;}}else /*若p指数大于q指数*/{pre->next=q; /*p结点不动,将q结点加入到和多项式中*/pre=pre->next;q=q->next;}}if(p!=NULL) /*多项式A中还有剩余,则将剩余的结点加入到和多项式中*/ pre->next=p;else /*否则将B的结点加入到和多项式中*/pre->next=q;}void print(node * p) /*输出函数,打印出一元多项式*/{while(p->next!=NULL){p=p->next;printf(" %d*x^%d",p->coef,p->exp);}}main() /*主函数*/{node * polya,* polyb;printf("Welcome to use!\n");printf("\nPlease input the ploya include coef && exp:\n");polya=create(); /*调用建立链表函数,创建多项式A*/print(polya);printf("\nPlease input the ployb include coef && exp:\n");polyb=create(); /*同理,创建B*/print(polyb);printf("\nSum of the poly is:\n");polyadd(polya,polyb); /*调用一元多项式相加函数*/print(polya); /*调用输出函数,打印结果*/printf("\n");}。
数据结构实验二链表的链式存储结构
贵州大学实验报告#include<iostream>using namespace std;typedef int Elemtype;struct LNode{Elemtype data;LNode *next;};void BuildLNode(LNode *&hl)/*建立带头结点单链表*/{hl=new LNode;hl->data=NULL;hl->next=NULL;}void ClearList(LNode *&hl)/*清空线性表*/ {LNode *p=hl;LNode *q;while(p!=NULL){q=p->next;delete p;p=q;}hl=NULL;}bool InsertList(LNode *&hl,Elemtype item,int pos)/*在线性表中插入一个元素*/{if(pos<-1){cout<<"位置无效"<<endl;return false;}if(pos==-1||pos==0)pos=1;LNode *p;int i=1;p=hl;while(p!=NULL&&i<pos){p=p->next;i++;}if(p==NULL){cout<<"位置无效"<<endl;return false;}LNode *q;q=new LNode;q->data=item;q->next=p->next;p->next=q;return true;}bool DeleteList(LNode *&hl,int pos)/*删除线性表中的一个元素*/{if(pos<-1){cout<<"位置无效"<<endl;return false;}if(pos==-1||pos==0)pos=1;LNode *p=hl,*q;int i=1;while(p->next!=NULL&&i<pos){p=p->next;i++;}if(p->next==NULL){cout<<"位置无效或该链表为空"<<endl;return false;}q=p->next;p->next=q->next;delete q;return true;}bool GetList(LNode *p,Elemtype &item,int pos)/*线性表中数据的定位*/{if(pos<-1){cout<<"位置无效"<<endl;return false;}if(pos==-1||pos==0)pos=1;int i=0;while(p!=NULL&&i<pos){p=p->next;i++;}if(p==NULL){cout<<"位置无效"<<endl;return false;}item=p->data;return true;}int FindList(LNode *p,Elemtype item)/*线性表中数据的查找*/{int i=0;while(p!=NULL){if(p->data==item)break;i++;p=p->next;}if(p==NULL){cout<<"找不到该元素"<<endl;return 0;}return i;}void DisplayList(LNode *hl)/*显示线性表中所有数据*/{if(hl==NULL){cout<<"该表为空"<<endl;}LNode *p=hl->next;while(p!=NULL){cout<<p->data<<" ";p=p->next;}} void main(){LNode *head;BuildLNode(head);int pos;Elemtype data;for(int i=0;i<10;i++)InsertList(head,2*i+1,i+1);DisplayList(head);cout<<endl;cout<<"一、插入操作"<<endl;cout<<"位置:";cin>>pos;cout<<"数据:";cin>>data;if(InsertList(head,data,pos))cout<<"插入成功"<<endl;elsecout<<"插入失败"<<endl;DisplayList(head);cout<<endl<<endl;cout<<"二、删除操作"<<endl;cout<<"位置:";cin>>pos;if(DeleteList(head,pos))cout<<"删除成功"<<endl;elsecout<<"删除失败"<<endl;DisplayList(head);cout<<endl<<endl;cout<<"三、定位操作:"<<endl;cout<<"位置:";cin>>pos;if(GetList(head,data,pos))cout<<"该位置数据为"<<data<<endl;elsecout<<"定位失败"<<endl;cout<<"四、查找操作:"<<endl;cout<<"数据:";cin>>data;if(FindList(head,data))cout<<"线性表中第一个等于该数据的位置为"<<FindList(head,data)<<endl;elsecout<<"查找失败"<<endl;ClearList(head);}。
线性表的链式存储结构实验报告
实验报告课程名称:数据结构与算法分析实验名称:链表的实现与应用实验日期:班级:数媒1401 姓名:范业嘉学号一、实验目的掌握线性表的链式存储结构设计与基本操作的实现。
二、实验内容与要求⑴定义线性表的链式存储表示;⑵基于所设计的存储结构实现线性表的基本操作;⑶编写一个主程序对所实现的线性表进行测试;⑷线性表的应用:①设线性表L1和L2分别代表集合A和B,试设计算法求A和B的并集C,并用线性表L3代表集合C;②(选做)设线性表L1和L2中的数据元素为整数,且均已按值非递减有序排列,试设计算法对L1和L2进行合并,用线性表L3保存合并结果,要求L3中的数据元素也按值非递减有序排列。
⑸设计一个一元多项式计算器,要求能够:①输入并建立多项式;②输出多项式;③执行两个多项式相加;④执行两个多项式相减;⑤(选做)执行两个多项式相乘。
三、数据结构设计1.按所用指针的类型、个数、方法等的不同,又可分为:线性链表(单链表)静态链表循环链表双向链表双向循环链表2.用一组任意的存储单元存储线性表中数据元素,用指针来表示数据元素间的逻辑关系。
四、算法设计1.定义一个链表void creatlist(Linklist &L,int n){int i;Linklist p,s;L=(Linklist)malloc(sizeof(Lnode));p=L;L->next=NULL;for(i=0;i<n;i++){s=(Linklist)malloc(sizeof(Lnode));scanf("%d",&s->data);s->next=NULL;p->next=s; p=s;}}2.(1)两个链表的合并void Mergelist(Linklist &La,Linklist &Lb,Linklist &Lc) {Linklist pa,pb,pc;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){if(pa->data<=pb->data){pc->next=pa;pc=pa;pa=pa->next;}else {pc->next=pb;pc=pb;pb=pb->next;} }pc->next=pa?pa:pb;free(Lb);}(2)两个链表的并集Linklist unionlist(Linklist &La,Linklist &Lb){Linklist p1,p2,head,q,s;int flag;head=q=(Linklist)malloc(sizeof(Lnode));p1=La->next;while(p1){flag=0;p2=Lb->next;while(p2){if(p1->data==p2->data){flag=1;break;}p2=p2->next;}if(flag==0){s=(Linklist)malloc(sizeof(Lnode));s->data=p1->data;q->next=s;q=s;}p1=p1->next;}q->next=Lb->next;return head;}3.(1)一元多项式的加法List addpoly(List pa,List pb) //一元多项式的加法{int n;List pc,s,p;pa=pa->next;pb=pb->next;pc=(List)malloc(sizeof(struct Linklist));pc->next=NULL;p=pc;while(pa!=NULL&&pb!=NULL){if(pa->expn>pb->expn){s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=pa->coef;s->next=NULL;p->next=s;p=s;pa=pa->next;}else if(pa->expn<pb->expn){s=(List)malloc(sizeof(struct Linklist));s->expn=pb->expn;s->coef=pb->coef;s->next=NULL;p->next=s;p=s;pb=pb->next;}else{n=pa->coef+pb->coef;if(n!=0){s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=n;s->next=NULL;p->next=s;p=s;}pb=pb->next;pa=pa->next;}}while(pa!=NULL){s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=pa->coef;s->next=NULL;p->next=s;p=s;pa=pa->next;}while(pb!=NULL){s=(List)malloc(sizeof(struct Linklist));s->expn=pb->expn;s->coef=pb->coef;s->next=NULL;p->next=s;p=s;pb=pb->next;}return pc;}(2)一元多项式的减法List subpoly(List pa,List pb) //一元多项式的减法{int n;List pc,s,p;pa=pa->next;pb=pb->next;pc=(List)malloc(sizeof(struct Linklist));pc->next=NULL;p=pc;while(pa!=NULL&&pb!=NULL){if(pa->expn>pb->expn){s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=pa->coef;s->next=NULL;p->next=s;p=s;pa=pa->next;}else if(pa->expn<pb->expn){s=(List)malloc(sizeof(struct Linklist));s->expn=pb->expn;s->coef=-pb->coef;s->next=NULL;p->next=s;p=s;pb=pb->next;}else{n=pa->coef-pb->coef;if(n!=0){s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=n;s->next=NULL;p->next=s;p=s;}pb=pb->next;pa=pa->next;}}while(pa!=NULL){s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=pa->coef;s->next=NULL;p->next=s;p=s;pa=pa->next;}while(pb!=NULL){s=(List)malloc(sizeof(struct Linklist));s->expn=pb->expn;s->coef=-pb->coef;s->next=NULL;p->next=s;p=s;pb=pb->next;}return pc;}(3)一元多项式的乘法void mulpolyn(polynomail pa,polynomail pb,polynomail &pc) {LNode *p,*q,*s,*hc;p=pa->next;q=pb->next;hc=pc;while(p!=NULL){while(q!=NULL){s=(polynomail)malloc(sizeof(LNode));hc->next=s;hc=hc->next;hc->coef=q->coef*p->coef;hc->expn=q->expn+p->expn;q=q->next;}p=p->next;q=pb->next;}hc->next=NULL;}五、测试结果2.3.六、心得体会(包括对于本次实验的小结,实验过程中碰到的问题等)1.首先书上给的链表输入是倒序的,写的时候想都没想就抄上去了,结果运行时发现问题,可是上网百度依然没有把问题解决,导致最后输出链表倒序的,并且链表的合并并集依旧是倒序的。
数据结构-线性表链式存储结构
04 线性表链式存储结构的实 现
C语言实现
创建链表
通过动态内存分配,创建链表节 点并逐个连接起来,形成链表。
插入节点
在链表指定位置插入节点,需要 更新插入位置节点的指针域,使 其指向新插入的节点。
删除节点
删除链表中的指定节点,需要更新被 删除节点前一个节点的指针域,使其 指向被删除节点的下一个节点。
01
遍历链表
从头节点开始,依次访问链表中的每 个节点,输出节点的数据值。
05
03
插入节点
在链表指定位置插入节点,需要更新 插入位置节点的引用,使其指向新插 入的节点。
04
删除节点
删除链表中的指定节点,需要更新被 删除节点前一个节点的引用,使其指 向被删除节点的下一个节点。
Python语言实现
在Python中,可以使
THANKS FOR WATCHING
感谢您的观看
适用场景
链式存储结构适用于需要频繁进行插入、删除等操作的数据结构,如动态数组、队列、链表等。
展望
01 02 03
未来发展方向
随着大数据和云计算的普及,数据结构的应用场景越来越 广泛,链式存储结构作为其中的一种重要形式,未来将有 更多的应用场景和优化空间。例如,针对大数据场景下的 链式存储结构优化、新型的链式数据结构等都是值得研究 的方向。
06 总结与展望
总结
定义与特点
链式存储结构是线性表的另一种存储方式,它通过在数据元素之间建立指针链接,实现了数据元素的逻辑顺序与物理 顺序的分离。相比于顺序存储结构,链式存储结构具有更好的动态性,能够方便地插入、删除等操作。
基本操作
链式存储结构支持的主要操作包括插入、删除、查找等,这些操作的时间复杂度通常为O(1)、O(n)、O(n),其中n为链表 长度。
数据结构(二):线性表的链式存储结构
数据结构(⼆):线性表的链式存储结构1、为什么要使⽤链式存储结构?因为我们前⾯讲的线性表的顺序存储结构,他是有缺点的。
最⼤的缺点就是插⼊和删除时需要移动⼤量元素,这显然就需要耗费时间。
要解决这个问题,我们就需要分析⼀下为什么当插⼊和删除时,就要移动⼤量元素,因为相邻两元素的存储位置也具有相邻关系,它们在内存中的位置也是挨着的,中间没有空隙,当然就⽆法快速介⼊,⽽删除之后。
当中就会留出空隙,⾃然就需要弥补。
问题就出在这⾥。
为了解决这个问题,⾃然⽽然的就出现了链式存储结构。
2、线性表链式存储结构的特点:线性表的链式存储结构不考虑元素的存储位置,⽽是⽤⼀组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这就意味着,这些数据元素可以存在内存未被占⽤的任意位置。
顺序存储结构:只需要存储数据元素信息。
链式存储结构:除了要存储数据元素信息之外,还要存储⼀个指⽰其直接后继元素的存储地址。
3、关键词:数据域:存储数据元素信息的域。
指针域:存储直接后继位置的域。
指针或链:指针域中存储的信息。
结点(Node):指针域+数据域组成数据元素的存储映像。
头指针:链表中第⼀个结点的存储位置。
头节点:在单链表的第⼀个结点前附设⼀个结点,成为头结点。
头结点的数据域不可以存储任何信息,可以存储线性表的长度等附加信息,头结点的指针域存储指向第⼀个结点的指针。
4、单链表:定义:n个结点链成⼀个链表,即为线性表的链式存储结构,因此此链表的每个结点中只包含⼀个指针域,所以叫做单链表。
PS:线性链表的最后⼀个结点指针为“空”,通常⽤NILL或“^”符号表⽰。
头节点:在单链表的第⼀个结点前附设⼀个结点,成为头结点。
头结点的数据域不可以存储任何信息,可以存储线性表的长度等附加信息,头结点的指针域存储指向第⼀个结点的指针。
5、头结点与头指针的异同(1)头结点头结点是为了操作的统⼀和⽅便⽽设⽴的,放在第⼀个元素的结点之前,其数据域⼀般⽆意义(也可存放链表的长度)有了头结点,对第⼀元素结点前插⼊和删除第⼀结点,其操作就统⼀了头结点不⼀定是链表的必要素(2)头指针头指针式指向第⼀个结点的指针,若链表有头结点,则是指向头结点的指针。
实验二 链表操作实现
实验二链表操作实现实验日期:2017 年 3 月16 日实验目的及要求1. 熟练掌握线性表的基本操作在链式存储上的实现;2. 以线性表的各种操作(建立、插入、删除、遍历等)的实现为重点;3. 掌握线性表的链式存储结构的定义和基本操作的实现;4. 通过本实验加深对C语言的使用(特别是函数的参数调用、指针类型的应用)。
实验内容已知程序文件linklist.cpp已给出学生身高信息链表的类型定义和基本运算函数定义。
(1)链表类型定义typedef struct {int xh; /*学号*/float sg; /*身高*/int sex; /*性别,0为男生,1为女生*/} datatype;typedef struct node{datatype data; /*数据域*/struct node *next; /*指针域*/} LinkNode, *LinkList;(2)带头结点的单链表的基本运算函数原型LinkList initList();/*置一个空表(带头结点)*/void createList_1(LinkList head);/*创建单链表*/void createList_2(LinkList head);/* 创建单链表*/void sort_xh(LinkList head);/*单链表排序*/void reverse(LinkList head);/*对单链表进行结点倒置*/void Error(char *s);/*自定义错误处理函数*/void pntList(LinkList head);/*打印单链表*/void save(LinkList head,char strname[]);/*保存单链表到文件*/任务一创建程序文件linklist.cpp,其代码如下所示,理解LinkList类型和基本运算函数后回答下列问题。
#include <stdio.h>#include <stdlib.h>/*单链表结点类型*/typedef struct {int xh; /*学号*/float sg; /*身高*/int sex; /*性别,0为男生,1为女生*/} datatype;typedef struct node{datatype data; /*数据域*/struct node *next; /*指针域*/} LinkNode, *LinkList;/*带表头的单链表的基本运算函数*/LinkList initList();/*置一个空表(带头结点)*/void createList_1(LinkList head);/*创建单链表*/void createList_2(LinkList head);/*创建单链表*/void sort_xh(LinkList head);/*单链表排序*/void reverse(LinkList head);/*单链表倒置*/void Error(char *s);/*自定义错误处理函数*/void pntList(LinkList head);/*打印单链表*/void save(LinkList head,char strname[]);/*保存单链表到文件*//*置一个空表*/LinkList initList(){ LinkList p;p=(LinkList)malloc(sizeof(LinkNode));p->next=NULL;return p;}/*创建单链表*/void createList_1(LinkList head){ FILE *fp;int xh;float sg;int sex;LinkList p;if((fp=fopen("records.txt","r"))==NULL){ Error("can not open file !");return ;}while(!feof(fp)){ fscanf(fp,"%d%f%d",&xh,&sg,&sex);p=(LinkList)malloc(sizeof(LinkNode));p->data.xh=xh;p->data.sg=sg;p->data.sex=sex;p->next=head->next;head->next=p;}fclose(fp);}/*创建单链表*/void createList_2(LinkList head){ FILE *fp;int xh;float sg;int sex;LinkList p,rear;if((fp=fopen("records.txt","r"))==NULL){ Error("can not open file !");return ;}rear=head;while(!feof(fp)){ fscanf(fp,"%d%f%d",&xh,&sg,&sex);p=(LinkList)malloc(sizeof(LinkNode));p->data.xh=xh;p->data.sg=sg;p->data.sex=sex;p->next=NULL;rear->next=p;rear=p;}fclose(fp);}/*单链表排序*/void sort_xh(LinkList head){LinkList q,p,u;p=head->next;head->next=NULL;/*利用原表头结点建新的空表*/while(p){ q=p; /*q为被插入的结点*/p=p->next;/*用p记录后继结点*//*遍历新链表查找插入位置*/u=head;while(u->next!=NULL)/*查找插入位置*/{ if(u->next->data.xh>q->data.xh)break;u=u->next;}/*插入在u结点的后面*/q->next=u->next;u->next=q;}}/*单链表倒置*/void reverse(LinkList head){ LinkList p, r;p=head->next;head->next=NULL;while(p){ r=p;p=p->next;/*r指向结点头插到链表*/r->next=head->next;head->next=r;}}/*输出单链表*/void pntList(LinkList head){ LinkList p;p=head->next;while(p!=NULL){printf("%2d: %.2f %d\n",p->data.xh,p->data.sg,p->data .sex);p=p->next;}}/*自定义错误处理函数*/void Error(char *s){ printf("\n %s", s);exit(1); /*返回OS,该函数定义在stdlib.h中*/}/*保存单链表到文件*/void save(LinkList head,char strname[]){ FILE *fp;LinkList p;if((fp=fopen(strname,"w"))==NULL){ printf("can not open file !");return ;}p=head->next;while(p!=NULL){ fprintf(fp,"%2d %5.2f %2d\n",p->data.xh,p->data.sg,p->data.sex);p=p->next;}fclose(fp);}请回答下列问题:(1)由单链表结点类型定义可知,该链表结点类型名为 LinkNode ,结点的指针类型为 LinkList ,向系统申请一个学生结点空间并把起始地址存于上述结点指针变量new 中的语句是: p=(LinkList)malloc(sizeof(LinkNode)); 。
浅析线性表的链式存储结构——链表
插入算法 :
St at us I ns er t L (L i n k L i s t& L , { p = L ; j = 0 ; w h i l e (P & &j < i 一 1 ) {p = p 一 ) n e x t ; j + + ;} i f( P& &j := i 一 1 ) { s = ( L i n k L i s t )m a l l o c( s i z e o f( L N o d e ))
—
S - > d a t a= e ;s - > n e x t = p 一 > n e x t ;
p - > n e x t : s ;r e t u r n o k ; ) r e t u r n e r r o r ;} ( 二) 删 除。 在一个链表 中存在三个相邻 的数据域分别为 a ,b和 C的结点 ,通过删 除数据元素 b实现数据 元素 a ,b和 C 之间逻辑关系的变化 。 我们只需要改变结点 a中指针 的指 向, 让其指 向结点 c即可 。 假设 P为指 向结点 a的指针 ,则删 除过 程 的语 句为 :q = p 一 > n e x t ;p - > n e x t = q一 > n e x t ;f r e e ( q ) ; 删 除算 法: S t a t u s D e l e t eL (L i n k L i s t& L ,i n t i , E l e m T y p e& e ) { p = L ; j = 0 ;
消费 电子
计 算机科学
C o n s u me r E l e c t r o n i c s Ma g a z i n e 2 0 1 3年 4月 下
浅析线性表的链式存储结构
— —
一元多项式相加 数据结构实验报告
南昌航空大学实验报告课程名称:数据结构实验名称:实验二线性表的链式存储结构班级:080611 学生姓名:学号:08指导教师评定:签名:题目:设计并实现以下算法:给出用单链表存储多项式的结构,利用后接法生成多项式的单链表结构,实现两个多项式相加的运算,并就地逆置相加后的多项式链式。
一、需求分析1.用户可以根据自己的需求分别输入两个一元多项式,并且能够实现输入的一元多项式的显示。
2.能够完成两个一元多项式的相加功能,而且还能显示相加后的逆置的一元多项式。
3.程序执行的命令包括:(1)构造链表A (2)构造链表B (3)两个链表的相加(4)求链表的长度(5)打印(显示)已有的链表(6)将已相加的链表进行逆序排列二、概要设计⒈为实现上述算法,需要线性表的抽象数据类型:ADT Polynomial {数据对象:D={a i:|a i∈TermSet,i=1…n,n≥0TermSet 中的每个元素包含一个表示系数的实数和表示指数的整数} 数据关系:R1={<a i-1,a i>|a i-1,a i∈D,且a i-1中的指数值< a i中的指数值i=2,…n≥0}基本操作:initlink(& L)操作结果:构造一个空的链表L。
Creatlink(&L,n)操作结果:输入n项的系数和指数,建立一个非空的一元多项式L。
LinkLength(L)初始条件:链表L已经存在。
操作结果:返回一元多项式L中的项数。
Displaylink(L)初始条件:链表L已经存在。
操作结果:打印输出一元多项式L。
Addpolyn(A,B,&C)初始条件:一元多项式A和B已存在。
操作结果:完成多项式相加运算,即:C=A+B,并且带回C。
subtracypolyn(&La,&Lb,)初始条件:一元多项式La和Lb已存在。
操作结果:完成多项式的相减运算La=La+Lb,并且销毁多项式Lb。
线性表的链式存储结构
石家庄经济学院实验报告学院: 信息工程学院专业: 计算机信息工程学院计算机实验中心制一 实验内容1.进一步熟悉C 语言的上机环境,掌握C 语言的基本结构。
2.会定义线性表的链式存储结构。
3.熟悉对单链表的一些基本操作(建表、插入、删除等)和具体的函数定义。
二 实验目的掌握链式存储结构的特点,了解、掌握并实现单链表的常用的基本算法。
三 需求设计线性表抽象数据类型的描述及实现ADT List{数据对象: {|,,,,,0}i i D a a ElemSet i 12n n =∈=≥数据关系: {,|,,,,}i 1i i 1i R a a a a D i 2n --=<>∈=基本操作:构造一个空的线性表L InitList();销毁线性表L DestroyList();将L 重置为空表 ClearList();判断L 是否为空 ListEmpty();求表长 ListLength();查找元素 LocateElem();求前驱 PriorElem();求后继 NextElem();插入元素ListInsert();删除元素ListDelete();元素调用visit()函数ListTraverse(L,visit())}ADT List;程序具体实现要求:1.创建一个线性表2.能输出所有数据元素3.能求线性表长度4.能插入删除元素5.能查找元素6.能求元素的前驱和后继7.用户操作界面如下:*********************************** 1. 构造线性表* 2. 插入元素* 3. 删除元素* 4. 查找元素* 5. 显示表长* 6. 求后继* 7. 求前驱* 8. 输出所有元素* 0. 结束程序运行*********************************** 请输入您的选择(0,1,...,8):四详细设计步骤4:上机编程与调试主程序如下:#include "stdafx.h"#include "stdio.h"#include "LinkList0515.h"#include "user.h"#include "Fun.h"int main(int argc, char* argv[]){CLinkList0515 L;LinkList l;int flag,flag1=0,loc,e,next_e,pre_e;printf("\n**************************************"); printf("\n* 1. 构造单链表");printf("\n* 2. 插入元素");printf("\n* 3. 删除元素");printf("\n* 4. 查找元素");printf("\n* 5. 显示表长");printf("\n* 6. 求后继");printf("\n* 7. 求前驱");printf("\n* 8. 输出所有元素");printf("\n* 0. 结束程序运行");printf("\n**************************************");while(1){printf("\n请输入您的选择(0,1,...,8): ");scanf("%d",&flag);switch(flag){case 0:++flag1;break;case 1:if(OK==L.InitList_L(l))printf("\n成功完成单链表初始化操作!\n");elseprintf("\n操作失败,内存溢出!\n");break;case 2:printf("\n 请输入插入元素的位序,值(空格隔开): ");scanf("%d %d",&loc,&e);if(ERROR==L.ListInsert_L(l,loc,e))printf("\n操作失败,可能是插入位序不合理!\n");elseprintf("\n成功完成操作!\n");L.ListTraverse_L(l,DisplayData);break;case 3:printf("\n 请输入被删除元素的位序: ");scanf("%d",&loc);if(ERROR==L.ListDelete_L(l,loc,e))printf("\n操作失败,可能是位序不合理!\n");else{ printf("\n元素 %d 成功被删除!\n",e);L.ListTraverse_L(l,DisplayData);}break;case 4:printf("\n 请输入待查找的元素的值: ");scanf("%d",&e);loc=L.LocateElem_L(l,e,compare);if(!loc)printf("\n表中不存在元素 %d !\n",e);elseprintf("\n找到了,元素 %d 在表中的位置是: %d \n",e,loc);break;case 5:printf("\n表长为: %d \n",L.ListLength_L(l));break;case 6:printf("\n 请输入元素的值: ");scanf("%d",&e);if(ERROR==L.NextElem_L(l,e,next_e))printf("\n表中元素 %d 没有后继!\n",e);elseprintf("\n表中元素%d 的后继是: %d\n",e,next_e);break;case 7:printf("\n 请输入元素的值: ");scanf("%d",&e);if(ERROR==L.PriorElem_L(l,e,pre_e))printf("\n表中元素 %d 没有前驱!\n",e);elseprintf("\n表中元素%d 的前驱是: %d \n",e,pre_e);break;case 8:L.ListTraverse_L(l,DisplayData);break;default:break;} //switchif(flag1==1) break;}//whileprintf("\n结束!\n\n\n");return 0;}运行结果如下:图3.1五实验总结1. 基本掌握线性表链式存储结构的特点;2. 基本掌握单链表的常用的基本操作算法;3. 通过线性表的抽象数据类型的学习,进一步掌握抽象数据类型的定义方法;4. 对于同一个线性表,用顺序结构和链式存储结构实现,算法也不同;从而可知,逻辑结构依赖于物理结构;。
线性表的链式存储结构和实现
经济学院实验报告学院: ______专业:计算机班级: ________________学号: ____________姓名:_________________信息工程学院计算机实验中心制实验题目:线性表的链式存储结构和实现实验室:机房4 设备编号: 09 完成日期:2012. ()4. ()9一、实验容1.会定义线性表的链式存储结构。
2.熟悉对单链表的一些基本操作(建表、插入、删除等)和具体的函数定义。
二、实验目的学握链式存储结构的特点,掌握并实现单链表的常用的基本算法。
三、实验的容及完成情况1.需求分析(1)线性表的抽象数据类型ADT的描述及实现。
本实验实现使用Visual c卄6.0实现线性表链式存储结构的表示及操作。
具体实现要求:(2)完成对线性表链式存储结构的表示和实现。
(3)实现对单链表的创建。
(4)实现对单链表的插入和删除操作。
2.概要设计抽象数据类型线性表的定义:ADT LIST{抽象对象:D= {ai | ai<-Elemset, i = l,2, •••,n,n>=0}数据关系:Rl= {<ai-l,ai<-DJ=2.-,n}基本操作:InitList(&L)操作结果:构造一个空的线性表L。
DestoryList(&L)初始条件:线性表L已存在。
操作结果:销毁线性表LCLearList(&L)初始条件:线性表L已存在。
操作结果:将L重置为空表。
ListEmpty(L)初始条件:线性表L已存在。
操作结果:若L为空表,则返回TRUE,否则返回FALSE。
ListLength(L)初始条件:线性表L已存在。
操作结果:返回L中数据元素个数。
GetElem(L,I,&e)初始条件:线性表L已存在,l<=i<=ListLength(L)o操作结果:用e返回L中第i个数据元素的值。
LocateElem(L,e,compare())初始条件:线性表L已存在,compare()是数据元素判定的函数。
线性表的链式存储结构实验报告
贵州大学实验报告学院:计算机科学与信息学院专业:信息安全班级:chaintable *Buildtable(int x[],int y) {chaintable *p,*head;p=new chaintable;head=p;p->data=x[0];for(int i=1;i<y;i++){p->next=new chaintable;p=p->next;p->data=x[i];}p->next=NULL;return head;}bool Deltable(chaintable *&head,int x) {if(x<1)return false;chaintable *relief,*p=head;for(int i=0;i<x-2;i++){if(p->next==NULL)return false;p=p->next;}if(x==1){relief=head;head=head->next;delete relief;if(head!=NULL)return true;elsereturn false;}else{if(p->next!= NULL){relief=p->next;p->next=p->next->next;delete relief;return true;}elsereturn false;}}bool Inserttable(chaintable *&head,int x,int y) {if(y<0)return false;chaintable *p=head,*t=new chaintable;t->data=x;t->next=NULL;if(y==0){t->next=head;head=t;return true;}else{for(int i=0;i<y-1;i++){if(p->next==NULL)return false;p=p->next;}t->next=p->next;p->next=t;return true;}}void Disptable(chaintable *p){while(p!=NULL){cout<<p->data<<' ';p=p->next;}cout<<endl;}bool Searchtable(chaintable *p,int &y,int x) {if(x>=1){for(int i=0;i<x-1;i++){if(p->next==NULL)return false;p=p->next;}y=p->data;return true;}elsereturn false;}int Location(chaintable *p,int x){int i=1;while(p!=NULL){if(p->data==x)return i;i++;p=p->next;}return 0;}void main(){int x,*temp,result;chaintable *head;cin>>x;temp=new int[x];for(int i=0;i<x;i++)cin>>temp[i];head=Buildtable(temp,x);if(Deltable(head,2)){cout<<"删除操作结果:";Disptable(head);}elsecout<<"操作失败!"<<endl;if(Inserttable(head,23,5)){cout<<"将23插入到第五个数字后面的操作结果:";Disptable(head);}elsecout<<"操作失败!"<<endl;if(Searchtable(head,result,4)){cout<<"链表的第四个数是:";cout<<"Search result:"<<result<<endl;}elsecout<<"操作失败!"<<endl;cout<<"Please input your integer:";cin>>x;cout<<"Location:"<<Location(head,x)<<endl;}实验结果:实验总结结果说明:1、第一行的8表示链表初始有8个数2、第二行的8个数是链表初始化的8个数3、第三行的结果是从链表删除了第二个数后的结果4、第五行的结果是搜索链表第四个数5、第六行是输入一个数要搜索的数(图中为25),第七行得出了搜索的结果。
国家开放大学《数据结构》课程实验报告(实验2——线性表)参考答案
//在链表中删除最高分和最低分结点
for(q=head,p=head->next;p!=NULL;q=p,p=p->next)
{
if(p==pmin) { q->next=p->next; p=q; } //删除最低分结点
};
typedef struct pw PW;
//定义链表结点
struct node
{
PW data;
struct node * next;
};
typedef struct node NODE;
NODE *create(int n); //建立单链表
void input(NODE *s,int i); //输入第i个评委信息
(5)遍历链表,累加求和,计算总分及平均分,并输出相关信息。
完整程序
//实验1.1线性表的链接存储结构
#include
#include
#include
#define PWRS 5 //定义评委人数
//定义评委信息
struct pw
{
char name[8]; //姓名
short age; //年龄
float score; //评分
NODE *create(int n)
{
NODE *head,*p,*q;
inti;
p=(NODE*)malloc(sizeof(NODE));
head=p; q=p; p->next=NULL;
for(i=1; i<=n; i++)
{
p=(NODE*)malloc(sizeof(NODE));
ds实验教案2
实验二:线性表基本运算及应用实验项目的和要求:1.掌握线性表的特点2.掌握线性表的顺序存储结构和链式存储结构的基本运算。
3.尽可能考虑算法的健壮性4.实验报告中要写出测试数据、错误分析以及收获。
实验项目名称一:实现两种存储结构的主要基本运算1.用结构体类型描述线性表的两种存储结构2.完成课堂上所讲的两种存储结构的基本运算3.要求用二级菜单实现****************************** 1-------顺序表 ** 2-------链表 ** 0-------退出 ******************************请输入的选择:(0-2):线性表的链式存储############################### 1----前插建立链表## 2----后插建立链表 ## 3----访问第i个元素 ## 4----插入 ## 5----删除 ## 6----求线性表的表长 ## 0----退出 ###############################请输入选择(0-6):实验项目名称2:超市密码存储箱系统的设计与实现问题描述:1.顾客使用箱子的流程为“投一元硬币”--------“找到一个空箱子,同时产生密码”(系统完成)--------“打印密码,打开箱子”(系统完成)--------“取密码并存包,并关闭箱子,入超市购物”--------“购物结束”--------“输入密码”--------“找到对应箱子并打开”(系统完成)--------“取包”。
2.现要求设计程序模拟以上系统完成的功能①界面:在我们的模拟系统中,箱子在屏幕上被画出来,并编号,空箱为蓝色,被使用时变成红色,再变为空后则恢复蓝色;②通过按“1”键模拟顾客投币;③当空箱子被顾客申请得到的同时,系统自动生成6位数密码,此密码不能与正在被使用的任何一个箱子的密码相同。
3.设计分析在设计时,可利用链表来组织所有的箱子,所有的箱子以结点的形式表示,结点中存放箱号、密码(满箱有,空箱无)以及指向下一个结点的指针。
线性表的链式存储结构实验报告
线性表的链式存储结构实验报告文件编码(008-TTIG-UTITD-GKBTT-PUUTI-WYTUI-8256)实验报告课程名称:数据结构与算法分析实验名称:链表的实现与应用实验日期:班级:数媒1401 姓名:范业嘉学号 08一、实验目的掌握线性表的链式存储结构设计与基本操作的实现。
二、实验内容与要求⑴定义线性表的链式存储表示;⑵基于所设计的存储结构实现线性表的基本操作;⑶编写一个主程序对所实现的线性表进行测试;⑷线性表的应用:①设线性表L1和L2分别代表集合A和B,试设计算法求A和B的并集C,并用线性表L3代表集合C;②(选做)设线性表L1和L2中的数据元素为整数,且均已按值非递减有序排列,试设计算法对L1和L2进行合并,用线性表L3保存合并结果,要求L3中的数据元素也按值非递减有序排列。
⑸设计一个一元多项式计算器,要求能够:①输入并建立多项式;②输出多项式;③执行两个多项式相加;④执行两个多项式相减;⑤(选做)执行两个多项式相乘。
三、数据结构设计1.按所用指针的类型、个数、方法等的不同,又可分为:线性链表(单链表)静态链表循环链表双向链表双向循环链表2.用一组任意的存储单元存储线性表中数据元素,用指针来表示数据元素间的逻辑关系。
四、算法设计1.定义一个链表void creatlist(Linklist &L,int n){int i;Linklist p,s;L=(Linklist)malloc(sizeof(Lnode));p=L;L->next=NULL;for(i=0;i<n;i++){s=(Linklist)malloc(sizeof(Lnode));scanf("%d",&s->data);s->next=NULL;p->next=s; p=s;}}2.(1)两个链表的合并void Mergelist(Linklist &La,Linklist &Lb,Linklist &Lc) {Linklist pa,pb,pc;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){if(pa->data<=pb->data){pc->next=pa;pc=pa;pa=pa->next;}else {pc->next=pb;pc=pb;pb=pb->next;} }pc->next=papa:pb;free(Lb);}(2)两个链表的并集Linklist unionlist(Linklist &La,Linklist &Lb){Linklist p1,p2,head,q,s;int flag;head=q=(Linklist)malloc(sizeof(Lnode));p1=La->next;while(p1){flag=0;p2=Lb->next;while(p2){if(p1->data==p2->data){flag=1;break;}p2=p2->next;}if(flag==0){s=(Linklist)malloc(sizeof(Lnode));s->data=p1->data;q->next=s;q=s;}p1=p1->next;}q->next=Lb->next;return head;}3.(1)一元多项式的加法List addpoly(List pa,List pb)3.六、心得体会(包括对于本次实验的小结,实验过程中碰到的问题等)1.首先书上给的链表输入是倒序的,写的时候想都没想就抄上去了,结果运行时发现问题,可是上网百度依然没有把问题解决,导致最后输出链表倒序的,并且链表的合并并集依旧是倒序的。
链式存储的实验报告
实验名称:线性表的链式存储结构实验日期:2022年X月X日班级:XX班姓名:XXX学号:XXXXXXX指导教师:XXX一、实验目的1. 理解线性表的链式存储结构及其特点。
2. 掌握链表的基本操作,如创建、插入、删除、查找和遍历等。
3. 通过实际编程实现链表,加深对链式存储结构概念的理解。
二、实验内容与要求1. 定义线性表的链式存储表示,包括节点结构和链表结构。
2. 实现链表的基本操作,如创建链表、插入节点、删除节点、查找节点和遍历链表等。
3. 编写测试代码,验证链表操作的正确性。
三、实验步骤1. 定义链表节点结构体,包含数据和指向下一个节点的指针。
2. 创建链表结构体,包含指向头节点的指针和节点数量。
3. 实现链表创建操作,初始化链表。
4. 实现链表插入操作,包括在链表头部、尾部和指定位置插入节点。
5. 实现链表删除操作,包括删除链表头部、尾部和指定位置的节点。
6. 实现链表查找操作,根据节点数据查找节点在链表中的位置。
7. 实现链表遍历操作,打印链表中的所有节点数据。
8. 编写测试代码,验证链表操作的正确性。
四、实验代码```c#include <stdio.h>#include <stdlib.h>// 定义链表节点结构体typedef struct Node {int data;struct Node next;} Node;// 创建链表Node createList() {Node head = (Node)malloc(sizeof(Node));if (head == NULL) {printf("Memory allocation failed!\n"); return NULL;}head->next = NULL;return head;}// 在链表头部插入节点void insertAtHead(Node head, int data) {Node newNode = (Node)malloc(sizeof(Node)); if (newNode == NULL) {printf("Memory allocation failed!\n"); return;}newNode->data = data;newNode->next = head->next;head->next = newNode;}// 在链表尾部插入节点void insertAtTail(Node head, int data) {Node newNode = (Node)malloc(sizeof(Node)); if (newNode == NULL) {printf("Memory allocation failed!\n"); return;}newNode->data = data;newNode->next = NULL;Node current = head;while (current->next != NULL) {current = current->next;}current->next = newNode;}// 删除链表头部节点void deleteAtHead(Node head) {if (head->next == NULL) {printf("List is empty!\n");return;}Node temp = head->next;head->next = temp->next;free(temp);}// 删除链表尾部节点void deleteAtTail(Node head) {if (head->next == NULL) {printf("List is empty!\n");return;}Node current = head;while (current->next->next != NULL) { current = current->next;}Node temp = current->next;current->next = NULL;free(temp);}// 删除指定位置的节点void deleteAtPosition(Node head, int position) {if (head->next == NULL || position < 0) {printf("Invalid position!\n");return;}Node current = head;int index = 0;while (current->next != NULL && index < position - 1) { current = current->next;index++;}if (current->next == NULL) {printf("Invalid position!\n");return;}Node temp = current->next;current->next = temp->next;free(temp);}// 查找节点Node findNode(Node head, int data) {Node current = head->next;while (current != NULL) {if (current->data == data) { return current;}current = current->next;}return NULL;}// 遍历链表void traverseList(Node head) {Node current = head->next;while (current != NULL) {printf("%d ", current->data); current = current->next;}printf("\n");}// 释放链表内存void freeList(Node head) {Node current = head;while (current != NULL) {Node temp = current;current = current->next;free(temp);}}int main() {Node head = createList();insertAtHead(head, 3);insertAtHead(head, 2);insertAtHead(head, 1);insertAtTail(head, 4);insertAtTail(head, 5);printf("Original list: ");traverseList(head);deleteAtHead(head);deleteAtTail(head);printf("List after deleting head and tail: ");traverseList(head);deleteAtPosition(head, 1);printf("List after deleting node at position 1: ");traverseList(head);Node node = findNode(head, 3);if (node != NULL) {printf("Node with data 3 found at position: %d\n", (head->next == node ? 1 : (head->next != NULL ? 2 : 3)));} else {printf("Node with data 3 not found.\n");}freeList(head);return 0;}```五、实验结果与分析1. 通过实验,成功实现了线性表的链式存储结构,包括创建、插入、删除、查找和遍历等基本操作。
线性表的链式存储结构完整版-数据结构版
AgeJudge(p->age);
L->next=p;p->next=NULL;
//链到表头后面
}
else{
//当输入非第一组数据时
s=(LinkList)malloc(sizeof(LNode)); //生成新结点
if(!s){printf("空间申请失败!");} //生成新结点失败
printf("请输入第%d 个人的姓名: ",i+1);
typedef struct LNode{
int ID;
//序号为整型
char name[20]; //姓名为字符型数组
char age[10]; //年龄为字符型数组
struct LNode *next; //struct LNode 的直接后继指针
}LNode, *LinkList;
//LNode 为结构体名,*LinkList 为指针型结构体名
//将输入的数据链到目前已存在的数据后面,并使下一指针为空,为下一次输入
做好准备
p=p->next;
//指针后移
}
}
printf("\n 信息录入完成!\n\n");
//链表创建完成
}//CreateList_L
void PrintElem_L(LinkList L){
//输出单链表中的数据
LinkList p;
或 p 为空
p=p->next;++j;
}
if(!p||j>i){printf("\n 没有找到你输入的序号信息!\n\n");}
//第 i 个元素不存在
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南昌航空大学实验报告
课程名称:数据结构实验名称:实验二线性表的链式存储结构
班级:学生姓名:冯华华学号:11046213 指导教师评定: XXX 签名: XXX
一、问题描述
1单链表的实现与操作。
2设计一个程序求出约瑟夫环的出列顺序。
约瑟夫问题的一种描述是:编号为1,2,…,
n的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数)。
一开始任选一个正整
数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m 值,从他在顺时针方向上的下一个人开始重新从1
报数,如此下去,直到所有人全部出列为止。
例如,n=7,7个人的密码依次为:
3,1,7,2,4,8,4,m的初值取6,则正确的出列顺序应为6,1,4,7,2,3,5。
要求使用单向循环
链表模拟此出列过程。
二、程序分析
约瑟夫环的大小是变化的,因此相应的结点也是变化的,使用链式存储结构可以动态的
生成其中的结点,出列操作也非常简单。
用单向循环链表模拟其出列顺序比较合适。
用结构指针描述每个人:
struct Joseph
{int num;/*环中某个人的序号*/
int secret;/环中某个人的密码*/
struct Joseph *next;/指向其下一个的指针*/};
1)初始化约瑟夫环:
调用函数struct Joseph *creat()生成初始约瑟夫环。
在该函数中使用head 指向
表头。
输入序号为0时结束,指针p1指向的最后结束序号为0的结点没有加入到
链表中,p2 指向最后一个序号为非0 的结点(最后一个结点)。
2)报数出列:
调用函数voil sort(struct Joseph * head,int m),使用条件p1->next!=p1判断
单向链表非空,使用两个指针变量p1和p2,语句p2=p1;p1=p1->next;移动指针,
计算结点数(报数);结点p1出列时直接使用语句:p2->next=p1->next,取出该
结点中的密码作为新的循环终值。
三、调试过程及实验结果
最后程序运行结果如下所示:
输入数据:数据格式为序号,密码
输入0,0为结束
1,3↙<回车>
2,1↙<回车>
3,7↙<回车>
4,2↙<回车>
5,4↙<回车>
6,8↙<回车>
7,4↙<回车>
0,0↙<回车>
输入m值
6↙<回车>
出列的序号是
6→1→4→7→2→3→5
四、附录
源程序文件清单:
该程序的源代码如下:
#define NULL 0
#define LENGTH sizeof(struct Joseph)
#include <stdlib.h>
#include <stdio.h>
struct Joseph
{
int num;
int secret;
struct Joseph *next;
};/*定义结点num为序号,secret为密码*/
/*创建初始链表函数*/
struct Joseph *creat()
{
struct Joseph *head;
struct Joseph *p1,*p2;
int n=0;
p1=p2=(struct Joseph *)malloc(LENGTH);
scanf("%d,%d",&p1->num,&p1->secret);
head=NULL;
while(p1->num!=0)
{
n=n+1;
if(n==1)
{
head=p1;
}
else p2->next=p1;
p2=p1;
p1=(struct Joseph *)malloc(LENGTH);
scanf("%d,%d",&p1->num,&p1->secret);
p2->next=head;
return(head);
}
}
/*报数出列*/
void sort(struct Joseph * head,int m)
{
struct Joseph *p1,*p2;
int i;
if(head==NULL)
printf("\n链表为空!\n");
p1=head;
while(p1->next!=p1)
{
for(i=1;i<m;i++)
{
p2=p1;p1=p1->next;
}
p2->next=p1->next;
m=p1->secret;
printf("%d ",p1->num);
p1=p2->next;
if(p1->next==p1)
{
printf("%d ",p1->num);
}
}
}
int main()
{
struct Joseph *head;
int m;
printf("\n输入数据:数据格式为序号,密码\n输入0,0为结束\n");
head=creat();
printf("输入 m值\n");
scanf("%d",&m);
if(m<1)printf("error! 请输入一个合法的 m值!");
printf("出列的序号是:\n");
sort(head,m);
}。