C++数据结构之链表排序

C++数据结构之链表排序
C++数据结构之链表排序

2009级数据结构实验报告

实验名称:使用链表实现各种排序算法

学生姓名:桂柯易

班级:2009211120

班内序号:07

学号:09210580

日期:2010年12月19日

1.实验要求

【实验目的】

通过选择实验内容中的两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法的使用的情况。

【实验内容】

使用链表实现下面各种排序算法,并进行比较。

排序算法如下:

①插入排序;

②冒泡排序;

③快速排序;

④简单选择排序;

⑤其他。

具体要求如下。

①测试数据分成三类:正序、逆序、随机数据。

②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键

字交换计为3次移动)。

③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)。

④对②和③的结果进行分析,验证上述各种算法的时间复杂度。

⑤编写main()函数测试各种排序算法的正确性。

2.程序分析

2.1 存储结构

存储结构:链表

2.2 关键算法分析

【设计思想】

以直接插入排序为例:首先将待排序数据建立一个带头结点的单链表。在单链表中进行直接插入排序的基本思想是:将单链表划分为有序区和无序区,有序区只包含一个元素节点,依次取无序区中的每一个结点,在有序区中查找待插入结点的插入位置,然后把该结点从单链表中删除,再插入到相应位置。

分析上述排序过程,需设一个工作指针q在无序区中指向待插入的结点,为了查找正确的插入位置,每趟排序前需将工作指针pre和p指向头结点和开始结点,在找到插入位置后,将结点q插在结点pre和p之间。这相当于在单链表中删除结点q,因此为了保证链表不断开,须在删除结点q之前保留结点q的后继结点的地址。

【复杂度】

(1)建立链表存储数据的算法:

Node *CreateSortNode(int count,int *array)

{

Node *p1,*p2,*head;

int i;

head=NULL;

for(i=0;i

{

p1=new Node;

p1->data=array[i];

p1->next=NULL;

if (i==0)

head=p1;

else

p2->next=p1;

p2=p1;

}

p2->next=NULL;

return head;

}

该算法的时间复杂度为T(N)=O(N)

(2)输出数据的算法:

void ListSortNode(Node *start)

{

Node *p;

p=start;

while(p!=NULL)

{

cout<data<<'\0';

p=p->next;

}

cout<

}

该算法的时间复杂度T(N)=O(N)

(3)插入排序算法:

Node *Insert_Sort_LinkTable(Node *head)

{

_LARGE_INTEGER time_start;

_LARGE_INTEGER time_over;

double dqFreq;

LARGE_INTEGER f;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

Node *s,

*newhead,

*p,

*pre,

*min;

s=head;

newhead=NULL;b1+=2;

while(s!=NULL)

{

a1++,b1+=3;

min=s;

p=newhead;

while(p!=NULL&&p->datadata){pre=p,p=p->next;b1+=2,a1+=2;}

s=s->next;

if(p==newhead)

{

a1++,b1+=2;

newhead=min;

newhead->next=p;

}

else

{

a1++,b1+=2;

pre->next=min;

min->next=p;

}

}

QueryPerformanceCounter(&time_over);

return newhead;

}

该算法的时间复杂度T(N)=O(N2)

(4)冒泡排序算法:

Node *Ebullient_Sort_LinkTable(Node *head)

{

_LARGE_INTEGER time_start;

_LARGE_INTEGER time_over;

double dqFreq;

LARGE_INTEGER f;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

Node *q,

*tail,

*p,

*t;

q=new Node;

q->next=head;

head=q;b2+=3;

for(tail=NULL;tail!=head;tail=p)

{

b2+=2,a2+=2;

for(p=q=head;q->next->next!=tail;q=q->next)

{

b2+=3,a2+=2;

if(q->next->data>q->next->next->data)

{

a2++,b2+=5;

t=q->next->next;

q->next->next=t->next;

t->next=q->next;

q->next=t;

p=q->next->next;

}

}

}

q=head;

head=head->next;b2+=2;

delete q;

QueryPerformanceCounter(&time_over);

return head;

}

该算法的时间复杂度T(N)=O(N2)

(5)快速排序算法:

Node *Fast_Sort_LinkTable(Node *head,Node *tail)

{

_LARGE_INTEGER time_start;

_LARGE_INTEGER time_over;

double dqFreq;

LARGE_INTEGER f;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

if(head==NULL||tail==NULL)return NULL;

if(head==tail)return NULL;

Node *p,

*r,

*pre;

pre=head;

p=head->next;

r=head;b3+=3;

while(p&&p!=tail->next)

{

a3+=2;

if(p->data<=head->data)

{

a3++,b3+=5;

r=pre;

pre=pre->next;

swamp(pre->data,p->data);

}

p=p->next;b3++;

}

swamp(head->data,pre->data);b3+=3;

Fast_Sort_LinkTable(head,r);

Fast_Sort_LinkTable(pre->next,tail);

QueryPerformanceCounter(&time_over);

return head;

}

该算法的时间复杂度T(N)=O(NlogN)

(6)简单选择排序算法:

Node *Select_Sort_LinkTable(Node *head)

{

_LARGE_INTEGER time_start;

_LARGE_INTEGER time_over;

double dqFreq;

LARGE_INTEGER f;

QueryPerformanceFrequency(&f);

dqFreq=(double)f.QuadPart;

QueryPerformanceCounter(&time_start);

Node *newhead,

*tail,

*p,

*pre,

*min;

newhead=NULL;b4++;

while(head!=NULL)

{

a4++;

for(p=min=head;p->next!=NULL;p=p->next)

{

a4++,b4+=3;

if(p->next->datadata)

{

a4++,b4+=2;

pre=p;

min=p->next;

}

}

if(min==head){head=head->next;a4++,b4++;}

else{pre->next=min->next;a4++,b4++;}

if(newhead==NULL){tail=newhead=min;a4++,b4++;}

else{tail=tail->next=min;a4++,b4++;

}

if(newhead!=NULL){tail->next=NULL;a4++,b4++;}

QueryPerformanceCounter(&time_over);

return newhead;

}

该算法的时间复杂度T(N)=O(N2)

2.3 其他

由于程序源代码在上述时间复杂度分析中已基本全部提及,此处不再附加。

3.程序运行结果

1.测试主函数流程:

2.测试条件:如上图所示,输入的数据为10个乱序数据:45,678,22,4,17,98,77,56,234,780。

3.测试结论:依次测试了插入排序,冒泡排序,快速排序,简单选择排序,结果都为正序,而且全部给出了算法运行时间和关键字的比较及移动次数,应可得出函数正常工作的结论。

4.总结

1.调试时出现的问题及解决办法:

(1)由于选择的是第二个,书上没有任何的参考代码,甚至在一些存储和实现方法上由于使用的是链表,因而出现了和数组不太一样的思想。遇到的第一个难题是插入排序,因为使用的是单链表,不可能从后往前遍历,所以不适合使用书上的插入排序算法,对此我做了一些调整,把每次往前寻找改成每次从头往后寻找合适的插入点,由于测试数据包括正序、乱序、逆序,因此这样修改并不会导致算法整体时间复杂度的增加。

(2)第二个遇到的问题是快速排序算法,按照书上的算法,快速排序需要从双向往中间靠拢,最后定下权值的位置,对此我曾一度想要改成用双向链表存储数据以实现书上的算法。但是后来感觉到这样会使整个程序显得异常臃肿(编完还需要加入时间算法和关键字统计算法),于是我又上网搜了一下,发现单链表的快速排序是有的,和书上的改进的快速排序算法思想是一样的,先将所有的数据根据权值左右分开,最后留下中间的位置给权值,然后不断递归求得最终结果。根据这个思想我顺利地编出了快速排序的算法。

(3)在加入时间函数的时候也出现了一些问题,这主要是由于缺乏经验,不知道什么样的函数能够显示微秒级别的程序运行时间,这个问题在和同学讨论并上网搜索的过程中顺利地解决了。

(4)再有就是关键字的统计方面,由于是最后加入,所以从整个程序来看,加入了8个静态全局变量,用来分别记录4个排序算法的关键字比较次数和移动次数。在具体的函数内部实现上,可能由于测试数据数量太小,线性或者平方的关系表现的并不是很明显。

2.心得体会:

这次编写代码延续了上次编写哈夫曼的良好风格,几乎是全程独自编写,只参考了网上的个别算法思想。这对我的编程能力又是一次极大的加强,以前编的程序简单,可以参考的代码多,几乎编出来的就已经是正确的,几乎很少调试。但是现在全是自己编,出现的问题很多,经常编译出来是一长串的问题,即时编译通过,运行时也经常达不到想要的效果,所以不得不多次使用但不调试F11来查找程序错误。在这个过程中有苦有乐,但是不管怎样,编译通过,运行成功那一时刻的喜悦,我想每一个喜欢编程的人都是能够理解的!

3.下一步的改进:

其实有个第五项其他选项我没有完成,原因是虽然只编4个函数,但已花费了大量时间。从时间上来说确实是不允许的。如果时间足够,我想再多编几个函数,实现链表的其他排序。话又说回来,链表的排序确实没有数组来的方便,我想有机会还是多和书上的数组的排序算法亲近亲近。

实验九 结构体与链表程序设计(解答)

《结构体与链表程序设计》实验解答 1、改错题 (1) #include struct stud { char name[20]; int age; } ; struct stud fun(struct stud person[],int n) //fun(struct stud person[],int n) { int min,i; min=0; for(i=0;i #include struct Poly { float a; /*系数*/ int n; /*指数*/ }; double fpvalue() { struct Poly p; double pvalue=0; float x; printf("输入多项式X:\n"); scanf("%f",&x); printf("输入多项式系数(a)和指数(n,n=-10000,结束):\n"); scanf("%f %d",&p.a,&p.n); //scanf("%f %d", p.a, p.n) while(p.n!=-10000) {pvalue+=p.a*pow(x,p.n); // pvalue+=p.a*pow(x, n);

结构体和链表编程题目

第四阶段(结构体与链表) 1.对候选人得票的统计程序。设有三个候选人,每次输入一个得票的候选人的 名字,要求最后输出各候选人得票结果。本题应该先定义一个结构体,结构体中包含姓名和票数两个变量。 2.建立一个描述个人信息的结构体,包括ID号,姓名,性别,年龄等信息,定 义该结构体数组并初始化,将按年龄分成三个部分(小于18岁,18-60岁,大于60岁),每一部分放在一起打印。 3.建立一个描述个人信息的结构体,包括ID号,姓名,性别,年龄等信息,定 义该结构体数组并初始化,将按年龄分成三个部分(小于18岁,18-60岁,大于60岁),然后定义一个该结构体的二维数组,二维数组的每一行按年龄分别存放同一部分的个人信息。 4.定义一个关于学生成绩的结构体,结构体中包含学生学号,姓名,英语成绩, 数学成绩,总分等信息,你可以定义该结构体的数组并初始化,总分可以通过程序获得,然后按总分为第一关键字,英语成绩为第二关键字将学生成绩信息从高到低排列并存到原数组中。(尽量不要定义新的数组)。 5.在屏幕上模拟显示一个数字式时钟(不要求1秒钟为频率)。结构体中应当定 义三个int变量,hour,minute,second。如何让second加1呢?这个可以使用延时程序,如: Delay() { Int I,j; For(i=0;i<1000;i++) For(j=0;j<1000;j++) {} } 这个延时程序不一定是1秒,只要模拟一下数字时钟就可以了。同时,你可能要用到形式如printf(“%d\r”)的打印,”\r”表示打印时又重新回到本行开头处打印,因为你每更新一次数据时都需要打印,打印的位置没有变化才会像一个电子时钟。 6.设计一结构体,包括ID号(int型),名称(字符串),请定义该结构体的数 组,并给这些数组赋初值,根据ID号将数组进行排序,把ID从小到大排序,不能再定义新的数组。比如:数组的第一个元素的ID号放ID号最小的值,并将这个ID号对应的名称也放在第一个元素的名称中。 7.给定单链表头结点,删除链表中倒数第K个结点。请实现函数struct node* del(struct node *head,int k);返回新链表的头结点。

(完整版)数据结构实验报告全集

数据结构实验报告全集 实验一线性表基本操作和简单程序 1 .实验目的 (1 )掌握使用Visual C++ 6.0 上机调试程序的基本方法; (2 )掌握线性表的基本操作:初始化、插入、删除、取数据元素等运算在顺序存储结构和链表存储结构上的程序设计方法。 2 .实验要求 (1 )认真阅读和掌握和本实验相关的教材内容。 (2 )认真阅读和掌握本章相关内容的程序。 (3 )上机运行程序。 (4 )保存和打印出程序的运行结果,并结合程序进行分析。 (5 )按照你对线性表的操作需要,重新改写主程序并运行,打印出文件清单和运行结果 实验代码: 1)头文件模块 #include iostream.h>// 头文件 #include// 库头文件------ 动态分配内存空间 typedef int elemtype;// 定义数据域的类型 typedef struct linknode// 定义结点类型 { elemtype data;// 定义数据域 struct linknode *next;// 定义结点指针 }nodetype; 2)创建单链表

nodetype *create()// 建立单链表,由用户输入各结点data 域之值, // 以0 表示输入结束 { elemtype d;// 定义数据元素d nodetype *h=NULL,*s,*t;// 定义结点指针 int i=1; cout<<" 建立一个单链表"<> d; if(d==0) break;// 以0 表示输入结束 if(i==1)// 建立第一个结点 { h=(nodetype*)malloc(sizeof(nodetype));// 表示指针h h->data=d;h->next=NULL;t=h;//h 是头指针 } else// 建立其余结点 { s=(nodetype*) malloc(sizeof(nodetype)); s->data=d;s->next=NULL;t->next=s; t=s;//t 始终指向生成的单链表的最后一个节点

数据结构实验二

洛阳理工学院实验报告 系部计算机系班级学号姓名 课程名称数据结构实验日期 实验名称链表的基本操作成绩 实验目的: (1)掌握线性表的链式存储结构的特点; (2)掌握线性表的基本操作:初始化、插入、删除、查找数据元素等运算在链式存储结构上的实现。 实验条件:计算机一台,vc++6.0 实验内容与算法思想: 内容: 建立一有序的链表,实现下列操作: 1.把元素x插入表中并保持链表的有序性; 2.查找值为x的元素,若找到将其删除; 3.输出表中各元素的值。 算法思想:先创建并初始化一个顺序表(void init_linklist(LinkList)),通过循环,输入一串数据void CreateFromTail(LinkList L);创建主函数;编写算法,完成子函数(查找locate,插入insList,删除DelList,输出output)模块;调用子函数,完成实验要求 运行结果:

附:源程序: #include #include #define OK 1 #define ERROR 0 typedef char ElemType; typedef struct Node { ElemType data; struct Node* next; }Node,*LinkList; void init_linklist(LinkList *l) { *l=(LinkList)malloc(sizeof(Node)); (*l)->next=NULL; } void CreateFromTail(LinkList L) { Node *r, *s; char c; int flag =1; r=L; while(flag) { c=getchar(); if(c!='$') {

数据结构 单链表详解

数据结构的概念: 数据的逻辑结构+ 数据的存储结构+ 数据的操作; 数据的数值:=====》数据===》数值型数据整形浮点数ASCII 非数值型数据图片声音视频字符 =====》数据元素=====》基本项组成(字段,域,属性)的记录。 数据的结构: 逻辑结构 ----》线性结构(线性表,栈,队列) ----》顺序结构 ----》链式结构 ----》非线性结构(树,二叉树,图) ----》顺序结构 ----》链式结构 存储结构 -----》顺序存储 -----》链式存储 -----》索引存储 -----》哈希存储==散列存储 数据的操作: 增 删 改 查 DS ====》数据结构===》DS = (D,R); 数据结构中算法: 1、定义:有穷规则的有序集合。 2、特性: 有穷性 确定性

输入 输出 3、算法效率的衡量 时间复杂度计算===》算法中可执行依据的频度之和,记为:T(n)。 是时间的一种估计值不是准确值。 计算结果的分析:1 将最终结果的多项式中常数项去掉 2 只保留所有多项式中最高阶的项 3 最后的最高阶项要去掉其常数项 时间复杂度的量级关系: 常量阶====》对数阶===》线性阶===》线性对数阶====》平方阶===》立方阶===》指数阶 以上关系可以根据曲线图来判断算法对时间复杂度的要求 空间复杂度计算====》算法执行过程中所占用的存储空间的量级,记为:D(n)。 计算方法是在运行过程中申请的动态内存的量级计算。 ///////////////////////////////////////////////////////////////////////////////////////////////// 线性表 顺序存储====》顺序表(数组) 链式存储====》单链表 特征:对于非空表,a0是表头没有前驱。 an-1 是表尾没有后继 ai的每个元素都有一个直接前驱和直接后继 基本操作:创建表=====》增加元素====》删除元素====》改变元素值====》查询元素 1、顺序表的操作 1.1 创建顺序表=====》定义个指定类型的数组====》int a[100] ={0};

约瑟夫问题数据结构实验报告汇总.

中南民族大学管理学院学生实验报告 实验项目: 约瑟夫问题 课程名称:数据结构 年级: 专业:信息管理与信息系统 指导教师: 实验地点:管理学院综合实验室 完成日期: 小组成员: 2012 学年至2013 学年度第1 学期

一、实验目的 (1)掌握线性表表示和实现; (2)学会定义抽象数据类型; (3)学会分析问题,设计适当的解决方案; 二、实验内容 【问题描述】:编号为1,2,…,n的n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自 1 开始顺序报数,报到m 时停止报数。报m 的人出列,将他的密码作为新的m 值,从他在顺时针方向上的下一个人开始重新从1 报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。 【基本要求】:利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。 【测试数据】:m 的初值为20;密码:3,1,7,2,4,8,4(正确的结果应为6,1,4,7,2,3,5)。 三、实验步骤 (一)需求分析 对于这个程序来说,首先要确定构造链表时所用的插入方法。当数到m 时一个人就出列,也即删除这个节点,同时建立这个节点的前节点与后节点的联系。由于是循环计数,所以才采用循环列表这个线性表方式。 程序存储结构利用单循环链表存储结构存储约瑟夫数据(即n个人的编码等),模拟约瑟夫的显示过程,按照出列的顺序显示个人的标号。编号为1,2,…,n 的 n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值 m,从第一个人开始按顺时针方向自1 开始顺序报数,报到 m 时停止报数。报 m 的人出列,将他的密码作为新的 m 值,从他在顺时针方向上的下一个人开始重新从 1 报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。基本要求是利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。 程序执行的命令(1)构造单向循环链表。 (2)按照出列的顺序引出各个人的标号。 测试数据 m 的初值为 20;密码:3,1,7,2,4,8,4(正确的结果应为 6,1,4,7,2,3,5) (1)、插入:在把元素插入到循环链表中时,由于是采用的头插法,所以我保留了front头结点。在每加入一个节点时,都会直接连接在front后面,从而保证一开始就赋值的rear尾节点不用修改。 伪代码阐释如下:

计10--数据结构专题实验rev2

上机实验要求及规范 《数据结构》课程具有比较强的理论性,同时也具有较强的可应用性和实践性,因此上机实验是一个重要的教学环节。一般情况下学生能够重视实验环节,对于编写程序上机练习具有一定的积极性,但是容易忽略实验的总结,忽略实验报告的撰写。对于一名大学生必须严格训练分析总结能力、书面表达能力。需要逐步培养书写科学实验报告以及科技论文的能力。拿到一个题目,一般不要急于编程,而是应该按照面向过程的程序设计思路(关于面向对象的训练将在其它后继课程中进行),首先理解问题,明确给定的条件和要求解决的问题,然后按照自顶向下,逐步求精,分而治之的策略,逐一地解决子问题。具体步骤如下: 1.问题分析与系统结构设计 充分地分析和理解问题本身,弄清要求做什么(而不是怎么做),限制条件是什么。按照以数据结构为中心的原则划分模块,搞清数据的逻辑结构(是线性表还是树、图?),确定数据的存储结构(是顺序结构还是链表结构?),然后设计有关操作的函数。在每个函数模块中,要综合考虑系统功能,使系统结构清晰、合理、简单和易于调试。最后写出每个模块的算法头和规格说明,列出模块之间的调用关系(可以用图表示),便完成了系统结构设计。 2.详细设计和编码 详细设计是对函数(模块)的进一步求精,用伪高级语言(如类C语言)或自然语言写出算法框架,这时不必确定很多结构和变量。 编码,即程序设计,是对详细设计结果的进一步求精,即用某种高级语言(如C/C++语言)表达出来。尽量多设一些注释语句,清晰易懂。尽量临时增加一些输出语句,便于差错矫正,在程序成功后再删去它们。 3.上机准备 熟悉高级语言用法,如C语言。熟悉机器(即操作系统),基本的常用命令。静态检查主要有两条路径,一是用一组测试数据手工执行程序(或分模块进行);二是通过阅读或给别人讲解自己的程序而深入全面地理解程序逻辑,在这个过程中再加入一些注释和断言。如果程序中逻辑概念清楚,后者将比前者有效。 4.上机调试程序 调试最好分块进行,自底向上,即先调试底层函数,必要时可以另写一个调用驱动程序,表面上的麻烦工作可以大大降低调试时所面临的复杂性,提高工作效率。 5.整理实验报告 在上机实验开始之前要充分准备实验数据,在上机实践过程中要及时记录实验数据,在上机实践完成之后必须及时总结分析,写出实验报告。

数据结构停车场问题实验报告汇总

数据结构课程设计 ——停车场管理问题 姓名: 学号: 问题描述 设有一个可以停放n辆汽车的狭长停车场,它只有一个大门可以供车辆进出。车辆按到达停车场时间的早晚依次从停车场最里面向大门口处停放(最先到达的第一辆车放在停车场的最里面)。如果停车场已放满n辆车,则后来的

车辆只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一辆车就进入停车场。停车场内如有某辆车要开走,在它之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。每辆车在离开停车场时,都应根据它在停车场内停留的时间长短交费。如果停留在便道上的车未进停车场就要离去,允许其离去,不收停车费,并且仍然保持在便道上等待的车辆的次序。编制一程序模拟该停车场的管理。 二、实现要求 要求程序输出每辆车到达后的停车位置(停车场或便道上),以及某辆车离开停车场时应交纳的费用和它在停车场内停留的时间。 三、实现提示 汽车的模拟输入信息格式可以是:(到达/离去,汽车牌照号码,到达/离去的时刻)。例如,(‘A',,1,5)表示1号牌照车在5这个时刻到达,而(‘ D ',,5,20)表示5号牌照车在20这个时刻离去。整个程序可以在输入信息为(‘ E ',0,0)时结束。本题可用栈和队列来实现。 四、需求分析 停车场采用栈式结构,停车场外的便道采用队列结构(即便道就是等候队列)。停车场的管理流程如 下 ①当车辆要进入停车场时,检查停车场是否已满,如果未满则车辆进栈(车辆进入停车场);如果停车场已满,则车辆进入等候队列(车辆进入便道等候)。 ②当车辆要求出栈时,该车到栈顶的那些车辆先弹出栈(在它之后进入的车辆必须先退出车场为它让路),再让该车出栈,其他车辆再按原次序进栈(进入车场)。当车辆出栈完毕后,检查等候队列(便道) 中是否有车,有车则从队列头取出一辆车压入栈中。

数据结构课程设计单链表

目录 1 选题背景 (2) 2 方案与论证 (3) 2.1 链表的概念和作用 (3) 2.3 算法的设计思想 (4) 2.4 相关图例 (5) 2.4.1 单链表的结点结构 (5) 2.4.2 算法流程图 (5) 3 实验结果 (6) 3.1 链表的建立 (6) 3.2 单链表的插入 (6) 3.3 单链表的输出 (7) 3.4 查找元素 (7) 3.5 单链表的删除 (8) 3.6 显示链表中的元素个数(计数) (9) 4 结果分析 (10) 4.1 单链表的结构 (10) 4.2 单链表的操作特点 (10) 4.2.1 顺链操作技术 (10) 4.2.2 指针保留技术 (10) 4.3 链表处理中的相关技术 (10) 5 设计体会及今后的改进意见 (11) 参考文献 (12) 附录代码: (13)

1 选题背景 陈火旺院士把计算机60多年的发展成就概括为五个“一”:开辟一个新时代----信息时代,形成一个新产业----信息产业,产生一个新科学----计算机科学与技术,开创一种新的科研方法----计算方法,开辟一种新文化----计算机文化,这一概括深刻影响了计算机对社会发展所产生的广泛而深远的影响。 数据结构和算法是计算机求解问题过程的两大基石。著名的计算机科学家P.Wegner指出,“在工业革命中其核心作用的是能量,而在计算机革命中其核心作用的是信息”。计算机科学就是“一种关于信息结构转换的科学”。信息结构(数据结构)是计算机科学研究的基本课题,数据结构又是算法研究的基础。

2 方案与论证 2.1 链表的概念和作用 链表是一种链式存储结构,链表属于线性表,采用链式存储结构,也是常用的动态存储方法。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。 以“结点的序列”表示线性表称作线性链表(单链表) 单链表是链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。 因此,查找第 i 个数据元素的基本操作为:移动指针,比较 j 和 i 单链表 1、链接存储方法 链接方式存储的线性表简称为链表(Linked List)。 链表的具体存储表示为: ① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的) ② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link)) 注意: 链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。 2、链表的结点结构 ┌───┬───┐ │data │next │ └───┴───┘ data域--存放结点值的数据域 next域--存放结点的直接后继的地址(位置)的指针域(链域) 注意: ①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。 ②每个结点只有一个链域的链表称为单链表(Single Linked List)。

数据结构实验报告

数据结构实验报告 一.题目要求 1)编程实现二叉排序树,包括生成、插入,删除; 2)对二叉排序树进行先根、中根、和后根非递归遍历; 3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。 4)分别用二叉排序树和数组去存储一个班(50人以上)的成员信息(至少包括学号、姓名、成绩3项),对比查找效率,并说明在什么情况下二叉排序树效率高,为什么? 二.解决方案 对于前三个题目要求,我们用一个程序实现代码如下 #include #include #include #include "Stack.h"//栈的头文件,没有用上 typedefintElemType; //数据类型 typedefint Status; //返回值类型 //定义二叉树结构 typedefstructBiTNode{ ElemType data; //数据域 structBiTNode *lChild, *rChild;//左右子树域 }BiTNode, *BiTree; intInsertBST(BiTree&T,int key){//插入二叉树函数 if(T==NULL) { T = (BiTree)malloc(sizeof(BiTNode)); T->data=key; T->lChild=T->rChild=NULL; return 1; } else if(keydata){ InsertBST(T->lChild,key); } else if(key>T->data){ InsertBST(T->rChild,key); } else return 0; } BiTreeCreateBST(int a[],int n){//创建二叉树函数 BiTreebst=NULL; inti=0; while(i

数据结构实验报告单链表

数据结构实验报告单链 表 Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】

2016级数据结构实验报告 实验名称:实验一线性表——题目1 学生姓名:李文超 班级: 班内序号: 15 学号: 47 日期: 2016年11月13日 1.实验要求 实验目的: 根据线性表的抽象数据类型的定义,选择下面任一种链式结构实现线性表,并完成线性表的基本功能。 线性表存储结构(五选一): 1、带头结点的单链表 2、不带头结点的单链表 3、循环链表 4、双链表 5、静态链表 线性表的基本功能: 1、构造:使用头插法、尾插法两种方法 2、插入:要求建立的链表按照关键字从小到大有序

3、删除 4、查找 5、获取链表长度 6、销毁 7、其他:可自行定义 编写测试main()函数测试线性表的正确性。 2.程序分析 存储结构 单链表的存储: (1)链表用一组任意的存储单元来存放线性表的结点。这组存储单元既可以是连续的,也可以是不连续的,甚至零散地分布在内存的某些位置。 (2)链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个元素值的同时,还要存储该元素的直接后继元素的位置信息,这个信息称为指针或链。 结点结构 ┌──┬──┐ data域---存放结点值的数据域 │data│next│ next域---存放结点的直接后继的地址的指针域└──┴──┘? 单链表在内存中的存储示意 地址内存单元

1000H 头指针 1020H 1080H 10C0H ………… 关键算法分析 1、关键算法: (1)头插法 自然语言描述: a:在堆中建立新结点 b:将a[i]写入到新结点的数据域 c:修改新结点的指针域 d:修改头结点的指针域。将新结点加入链表中 伪代码描述 a:Node * s=new Node b:s->data=a[i] c:s->next=front->next; d:front->next=s (2)尾插法 自然语言描述: a:在堆中建立新结点:

数据结构链表代码

#include typedef struct lnode{ int data; lnode *next; }lnode; void initlist(lnode *&head){ head=new lnode; head->next=NULL; }//带头结点空链表的判断条件 /*void initlistn(lnode *&head,int n){ initlist1(head); lnode *s; for(int i=0;i>s->data; s->next=head->next; head->next=s; } }//逆序*/ void initlistn(lnode *&head,int n){ initlist(head); lnode *p=head,*s; for(int i=0;i>s->data; s->next=NULL; p->next=s; p=s; } }//正序 void print(lnode *head){ lnode *p=head->next; while(p){ cout<data<<' '; p=p->next; } cout<next;j++;}

if(!p||j>i-1) return; lnode *s=new lnode; s->data=e; s->next=p->next; p->next=s; }//插入 void deletelist(lnode *&head,int i,int &e){ lnode *p=head; int j=0; while(p->next&&jnext;j++;} if(!p->next||j>i-1) return; lnode *q=p->next; e=q->data; p->next=q->next; }//删除 void main(void){ lnode *head; initlistn(head,10); print(head); inserlist(head,6,200); print(head); int e; deletelist(head,8,e); print(head); }

数据结构实验报告及心得体会

2011~2012第一学期数据结构实验报告 班级:信管一班 学号:201051018 姓名:史孟晨

实验报告题目及要求 一、实验题目 设某班级有M(6)名学生,本学期共开设N(3)门课程,要求实现并修改如下程序(算法)。 1. 输入学生的学号、姓名和 N 门课程的成绩(输入提示和输出显示使用汉字系统), 输出实验结果。(15分) 2. 计算每个学生本学期 N 门课程的总分,输出总分和N门课程成绩排在前 3 名学 生的学号、姓名和成绩。 3. 按学生总分和 N 门课程成绩关键字升序排列名次,总分相同者同名次。 二、实验要求 1.修改算法。将奇偶排序算法升序改为降序。(15分) 2.用选择排序、冒泡排序、插入排序分别替换奇偶排序算法,并将升序算法修改为降序算法;。(45分)) 3.编译、链接以上算法,按要求写出实验报告(25)。 4. 修改后算法的所有语句必须加下划线,没做修改语句保持按原样不动。 5.用A4纸打印输出实验报告。 三、实验报告说明 实验数据可自定义,每种排序算法数据要求均不重复。 (1) 实验题目:《N门课程学生成绩名次排序算法实现》; (2) 实验目的:掌握各种排序算法的基本思想、实验方法和验证算法的准确性; (3) 实验要求:对算法进行上机编译、链接、运行; (4) 实验环境(Windows XP-sp3,Visual c++); (5) 实验算法(给出四种排序算法修改后的全部清单); (6) 实验结果(四种排序算法模拟运行后的实验结果); (7) 实验体会(文字说明本实验成功或不足之处)。

三、实验源程序(算法) Score.c #include "stdio.h" #include "string.h" #define M 6 #define N 3 struct student { char name[10]; int number; int score[N+1]; /*score[N]为总分,score[0]-score[2]为学科成绩*/ }stu[M]; void changesort(struct student a[],int n,int j) {int flag=1,i; struct student temp; while(flag) { flag=0; for(i=1;ia[i+1].score[j]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; flag=1; } for(i=0;ia[i+1].score[j]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; flag=1;

结构体与链表习题 附答案

一、选择题 1、在说明一个结构体变量时系统分配给它的存储空间是(). A)该结构体中第一个成员所需的存储空间 B)该结构体中最后一个成员所需的存储空间 C)该结构体中占用最大存储空间的成员所需的存储空间 D)该结构体中所有成员所需存储空间的总和。 2.设有以下说明语句,则以下叙述不正确的是( ) struct stu {int a;float b;}stutype; A. struct 是结构体类型的关键字 B. struct stu 是用户定义的结构体类型 C. stutype 是用户定义的结构体类型名 D. a 和b 都是结构体成员名 3、以下对结构体变量stu1中成员age的合法引用是() #include struct student { int age; int num; }stu1,*p; p=&stu1; A)stu1->age B)student.age C)p->age D) p.age 4、有如下定义: Struct date { int year,month,day; }; Struct worklist { Char name[20]; Char sex; Struct date birthday; }person; 对结构体变量person的出生年份进行赋值时,下面正确的赋值语句是( ) 。 A worklist .birthday.year=1978 B birthday.year=1978 C person.birthday.year=1958 D person.year=1958 5、以下程序运行的结果是( ) 。 #include”stdio.h” main() { struct date { int year , month , day ; } today ;

数据结构实验报告顺序表和链表

实验报告 课程名称数据结构 实验项目实验一线性表的生成与操作 题目一顺序表和链表的创建与基本操作 系别___ _计算机学院 _ ______ 专业____计算机大类_ __ 班级/学号__(1406/2014011288)_____ 学生姓名 _______(孙文学)_________ 实验日期_(2015年10月19日) 成绩_______________________ 指导教师黄改娟 实验题目:实验一线性表的生成与操作 ------顺序表和链表的创建与基本操作(自己所选择实验题目,必 填) 一、实验目的 1)掌握线性表的顺序存储和链式存储结构; 2)验证顺序表及链表的基本操作的实现;(验证)

3)理解算法与程序的关系,能够将算法转换为对应程序; 4)体会线性表在实际应用中能够解决的问题。(设计、综合) 二、实验内容 1)根据实验一题目列表,选定题目,说明题目的主要需求; 2)结合所选定的题目,定义存储结构,并完成对应应用的线性表创建、插入、删除、 查找等基本操作的算法描述; 3)程序编码实现,并获得运行结果。 三、报告内容 1)实验题目及主要存储结构定义 (提示:请根据所选定题目,描述存储结构) 题目:顺序表和链表的创建及基本操作 顺序表我是采用数组存储的,链表是采用结构体存储的 2)结合题目,说明对相应线性表的基本操作算法描述 (提示:可用自然语言、流程图、伪代码等均可,要求对每一个操作,都给出具体的算法描述) 基本操作: #顺序表# (1)插入:在线性表中的x位置插入y----将x位置及之后的元素都往后挪一位,将y的值赋给a[x]. (2)删除:删除位置为x的元素----另y=a[x],然后x之后的元素都往前挪一位。 (3)查找:寻找值为y的元素----从a[0]开始,若a[i]==y,则返回i,否则i++。 #链表# (1)插入:当i小于要插入的位置x时,i++,插入p->data------p->next=s->next;s->next=p; (2)删除:当p->data不等于要删除的值x时,p=p->next; q=p->next; p->next=q->next; free(q); (3)查找:当p->data!=x时,p=p->next,找到之后返回p->data 3)程序源码 (提示:列出所编写程序的代码。如果利用图形界面IDE等编程,这里只要求写出关键操作的程序代码。此外,程序一定要有注释说明) 1.顺序表的基本操作(用数组实现) #include #include int main(){

数据结构实验 链表

实验名称:链表 班级:学号___________姓名:报告日期: 一、实验目的及要求 1. 掌握单链表的存储结构形式及其描述。 2. 掌握单链表的建立、查找、插入和删除操作。 二、实验内容 1. 编写函数,实现随机产生或键盘输入一组元素,建立一个带头结点的单链表(无序)。 2. 编写函数,实现遍历单链表。 3. 编写函数,实现把单向链表中元素逆置(不允许申请新的结点空间)。 4. 编写函数,建立一个非递减有序单链表。 5. 编写函数,利用以上算法,建立两个非递减有序单链表,然后合并成一个非递减链表。 6. 编写函数,在非递减有序单链表中插入一个元素使链表仍然有序。 7. 编写函数,实现在非递减有序链表中删除值为x的结点。 8. 编写一个主函数,在主函数中设计一个简单的菜单,分别调试上述算法。 三、实验结果

四、实验总结: 这次实验使我在已经掌握单链表的存储结构,单链表的建立、查找、插入和删除操作的思想的基础上,可以对其利用C语言进行编程的实现,不仅对单链表的有关内容有了更深的理解,同时也对C语言编程的学习有了很大的进步。期间也遇到不少麻烦,;例如在编好程序后,编译运行时出现很多错误,但是在同学和网络的帮助下,将其成功解决。此外,需要注意的就是在用C语言进行编程时,一定要细心,注意基础知识的积累。同时算法思想也很重要。 源代码: #include #include typedef int ElemType;

typedef struct LNode { ElemType data; struct LNode *next; }LNode,*Linklist; void Createlist(Linklist &L) { Linklist p,s; ElemType x; L=(Linklist)malloc(sizeof(LNode)); L->next=NULL; p=L; scanf("%d",&x); while(x) { s=(Linklist)malloc(sizeof(LNode)); s->data=x; s->next=NULL; p->next=s; p=s; scanf("%d",&x);} } void printlist(Linklist &L) { Linklist p; p=L; while(p->next!=NULL){ p=p->next; printf("%d ",p->data);} printf("\n"); } void nizhi(Linklist &L) { Linklist p,s; p=L->next; L->next=NULL; while(p) { s=p; p=p->next; s->next=L->next; L->next=s;} } void charu(Linklist &L,ElemType x)

链表的插入、删除实例,C语言 结构体

int main() { pNode pHead = NULL; // 定义初始化头节点,等价于struct Node *pHead == NULL int data; // 作为Insert_Node函数的第三个参数 int num; // 作为Inset_Node函数第二个参数 int choose; int return_val; pHead = CreateList(); // 创建一个非循环单链表,并将该链表的头结点的地址付给pHead printf("你输入的数据是:"); TraverseList(pHead); // 调用遍历链表函数 printf("是否还要进行如下操作:\n"); printf("1.插入数据 2.删除数据\n"); printf("请输入:"); scanf("%d",&choose); switch (choose) { case 1: { printf("请输入要在第几个节点前插入数据:"); scanf("%d",&num); printf("请输入要插入的数据:"); scanf("%d",&data); if(Insert_Node(pHead,num,data) == true) { printf("插入成功\n插入后的数据是:\n"); TraverseList(pHead); } else { printf("插入失败\n"); } printf("操作完成后的数据是:"); TraverseList(pHead); break; } case 2: { printf("请输入要删除第几个节点的数据:"); scanf("%d",&num); return_val = Del_Node(pHead,num); if (return_val == 0) {

数据结构实验报告 - 答案汇总

数据结构(C语言版) 实验报告

专业班级学号姓名 实验1 实验题目:单链表的插入和删除 实验目的: 了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。 实验要求: 建立一个数据域定义为字符串的单链表,在链表中不允许有重复的字符串;根据输入的字符串,先找到相应的结点,后删除之。 实验主要步骤: 1、分析、理解给出的示例程序。 2、调试程序,并设计输入数据(如:bat,cat,eat,fat,hat,jat,lat,mat,#),测试程序 的如下功能:不允许重复字符串的插入;根据输入的字符串,找到相应的结点并删除。 3、修改程序: (1)增加插入结点的功能。 (2)将建立链表的方法改为头插入法。 程序代码: #include"stdio.h" #include"string.h" #include"stdlib.h" #include"ctype.h" typedef struct node //定义结点 { char data[10]; //结点的数据域为字符串 struct node *next; //结点的指针域 }ListNode; typedef ListNode * LinkList; // 自定义LinkList单链表类型 LinkList CreatListR1(); //函数,用尾插入法建立带头结点的单链表 LinkList CreatList(void); //函数,用头插入法建立带头结点的单链表 ListNode *LocateNode(); //函数,按值查找结点 void DeleteList(); //函数,删除指定值的结点 void printlist(); //函数,打印链表中的所有值 void DeleteAll(); //函数,删除所有结点,释放内存

数据结构实验二链表

云南大学数学与统计学实验教学中心 实 验 报 告 一、实验目的: 通过实验掌握线性链表的建立及基本操作,巩固课堂内容,练习其程序的设计与实现。 由于顺序存储结构的操作相对比较简单,而且在前期课程《高级语言程序设计》中使用得也多, 所以本次实验侧重于对线性链表存储结构上的操作及应用的实现。 二、实验内容: 本实验包含以下几个子问题: 1、 采用表尾挂入法建立一个以LA 为头指针的单链表: 2、 3、 就地逆转以LB 为头指针的单链表,即得到如下形式的单链表: 4、 将逆转后的LB 表接到LA 表之尾并构成循环链: LA 二、实验要求: 1. 每一个子问题用一个C 语言的函数来完成。 2. 对每一个子问题的结果用一个打印函数输出其结果以验证程序运行是否正确。 打印函数必须是公共的,即:用一个输出函数,既可以对单链表又可对循环链表实现,

打印输出。 3.用主函数调用各个子函数,以完成题目要求。 4.程序设计时应尽量考虑通用性,若改变题给数据仍能实现要求。 [实现提示]: .第3小题题中的“就地逆转”即只允许引入除LB外的两个工作指针来实现。 即可以以循环方式从链表首部起逐个地修改各个结点的指针:从NEXT(向后)指针改变为PRIOR(向前)的指针,并注意保存搜索时的指针。 三、实验环境 Windows win7 程序设计语言C 四、实验过程(请学生认真填写): 1. 实验设计的(各)流程图:

2. 程序设计的代码及解释(必须给出): /*----------------------------------LinkList-------------------------------------*/ /*基本要求---------------------------------------------------------------------*/ /*采用表尾挂入法建立一个以LA为头指针的单链表--------------*/ /*采用表首插入法建立一个以LB为头指针的单链表.---------------*/ /*就地逆转以LB为头指针的单链表,即得到如下形式的单链表.*/ /*将逆转后的LB表接到LA表之尾并构成循环链-------------------*/ /*每一个子问题用一个C语言的函数来完成--------------------------*/ /* 打印函数必须是公共的-------------------------------------------------*/ /*-------------------------------------Start-------------------------------------*/ /*--------------------------------------------------------------------------------*/ #include #include #include #define LIST_SIZE 10 /*--------------------------------------------------------------------------------*/ /*定义链表类型--------------------------------------------------------------*/ typedef struct LNode{ int data; struct LNode *next; }LinkList; /*--------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------*/ main(){ LinkList *InitialList1(); LinkList *InitialList2(); LinkList *reverse(LinkList *L); void connect(LinkList *L1,LinkList *L2); void putList(LinkList *L); LinkList *L1,*L2; L1=InitialList1(); L2=InitialList2(); printf("The original of list L1:\n"); putList(L1); printf("The original of list L2:\n");

相关文档
最新文档