实验二 线性表的链式存储结构

合集下载

线性表的链式存储结构

线性表的链式存储结构
只是判断循环结束的条件不同:如果找不到结点e,循 环链表结束在头结点,而单链表结束在最后一个结点。 ****思考题。有的时候,若在循环链表中设立尾指针而 不设立头指针,可使某些操作简化。如合并两个循环 链表时。图示表达:P28图2.13。
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月 下
浅析线性表的链式存储结构
— —
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);
}。

相关文档
最新文档