上机实验报告学院:计算机与信息技术学院专业:计算机科学与技术(师范)课程名称:数据结构实验题目:单链表建立及操作班级序号:师范1班学号:201421012731学生姓名:邓雪指导教师:杨红颖完成时间:2015年12月25号一、实验目的:(1)动态地建立单链表;(2)掌握线性表的基本操作:求长度、插入、删除、查找在链式存储结构上的实现;(3)熟悉单链表的应用,明确单链表和顺序表的不同。
二、实验环境:Windows 8.1Microsoft Visual c++ 6.0三、实验内容及要求:建立单链表,实现如下功能:1、建立单链表并输出(头插法建立单链表);2、求表长;3、按位置查找4、按值查找结点;5、后插结点;6、前插结点7、删除结点;四、概要设计:1、通过循环,由键盘输入一串数据。
创建并初始化一个单链表。
2、编写实现相关功能函数,完成子函数模块。
3、调用子函数,实现菜单调用功能,完成顺序表的相关操作。
五、代码:#include<stdio.h>#include<stdlib.h>typedef char datatype;typedef struct node{datatype data;struct node *next;}linklist;linklist *head,*p;//头插法建立单链表linklist *Creatlistf(){char ch;linklist *head,*s;head=NULL;ch=getchar();printf("请输入顺序表元素(数据以$结束):\n");while(ch!='$'){s=(linklist *)malloc(sizeof(linklist));s->data=ch;s->next=head;head=s;ch=getchar();}return head;}//求单链表的长度void get_length(struct node *head){struct node *p=head->next;int length=0;while(p){length++;p=p->next;}head->data=length;printf("该单链表的长度为:%d\n",head->data);}//按序号查找结点linklist *Get(linklist *head,int i){int j;linklist *p;p=head;j=0;while((p->next!=NULL)&&(j<i)){p=p->next;j++;}if(i==j)return p;}//按值查找结点linklist *Locate(linklist *head,datatype key){int pos=0;p=head->next;printf("查找结点位置为:");while(p!=NULL){if(p->data!=key){p=p->next;pos++;}else{pos++;break;}}return p;}//后插结点void Insertafter(linklist *p,datatype x) {linklist *s;s=(linklist *)malloc(sizeof(linklist));s->data=x;s->next=p->next;p->next=s;printf("插入成功");}//前插结点void Insertbefore(linklist *p,datatype x) {linklist *s;s=(linklist *)malloc(sizeof(linklist));s->next=p->next;s->data = p->data;p->data=x;p->next=s;}//删除结点linklist *Deleteafter(linklist *head){int i;linklist *r,*p;printf("请输入要删除的结点位置:");scanf("%d",&i);if(i==1){r=head;head=head->next;}else{p=Get(head,i-1-1);r=p->next;p->next=r->next;}free(r);return head;}//输出单链表void output(linklist *p){while(p->next!=NULL){printf("%c ",p->data);p=p->next;}printf("\n");}void main(){linklist *head;int k,i,pos;char x;datatype key;printf("_____________单链表的操作_____________\n");printf("\t1.头插法建立单链表\n");printf("\t2.输出单链表\n");printf("\t3.求单链表的长度\n");printf("\t4.按序号查找结点\n");printf("\t5.按值查找结点\n");printf("\t6.后插结点\n");printf("\t7.前插结点\n");printf("\t8.删除接点\n");printf("\t9.退出\n");do{printf("选择所需功能: ");scanf("%d",&k);switch(k){case 1:head=Creatlistf();break;case 2:printf("单链表为:\n");output(head);break;case 3:get_length(head);break;case 4:printf("请输入要查找的结点序号:");scanf("%d",&i);getchar();printf("结点的值为:%c\n",Get(head,i-1)->data);break;case 5:printf("请输入要查找的结点值:");scanf("%c",&key);getchar();printf("%d",Locate(head,key));printf("\n");break;case 6:printf("输入要插入的结点位置:");scanf("%d",&pos);getchar();printf("请输入插入的结点值:");scanf("%c",&x);getchar();Insertafter(Get(head,pos-1),x);printf("插入成功");break;case 7:printf("输入要插入的结点位置和结点值(前插)(p,x):");scanf("%d,%c",&pos,&x);getchar();Insertbefore(Get(head,pos-1),x);printf("插入成功");break;case 8:head=Deleteafter(head);break;case 9:printf("退出");exit(0);default:printf("输入错误\n");exit(0);}}while(1);}六、运行界面菜单功能七、实验中遇到的问题及总结二次输出链表元素时链表的第一个结点会变成乱码字符。
第一次输出没有错误。
顺序表和单链表的区别:在顺序表中,我们是用一组地址连续的存储单元来依次存放线性表的结点,因此结点的逻辑次序和物理次序一致。
而链表则不然,链表是用一组任意的存储单元来存放线性表的结点,这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任何位置上,因此,链表中结点的逻辑次序和物理次序不一定相同。
为了能够正确表示结点间的逻辑关系,在存储每个结点值得同时,还必须存储指示后继结点的地址(或位置)信息,这个信息称为指针或链。
本次实验采用头插法建立链表,虽然头插法简单,但生成的链表中结点的的次序和输入的顺序相反。
若希望二者次序一致,可采用尾插法建表。
通过这次程序设计,对单链表的应用理解更深刻更透彻了。
单链表相对于顺序表,插入和删除更加方便,而且不需要考虑存储空间的大小。
但是频繁的读取和数据的查找不甚便捷。
在以后的实验中希望能学到更多。
八、参考文献《数据结构——用C语言描述》。