归并La和Lb得到新的线性表Lc (2)
[数据结构]线性表合并
[数据结构]线性表合并⼀、问题描述线性表合并是程序设计语⾔编译中的⼀个最基本的问题,现在有两个线性表LA和LB,其中的元素都是按照⾮递减有序排列的,要将两个LA 和LB归并为⼀个新的线性表LC,使得LC中的元素仍然是⾮递减有序的。
本实验的合并⽅式有两种。
第⼀种是分别取LA和LB的第⼀个元素,即各⾃的最⼩的元素进⾏⽐较,选择较⼩的元素加⼊LC尾部,然后重复以上步骤;当LA表空了或者LB表空了的时候,将另⼀个表剩下的元素按照顺序加⼊LC的尾部,从⽽保证LC中元素有序。
第⼆种⽅式是以LA为母表,将LB中的元素向LA中插⼊,直到LB表空,得到的新的LA表就是最终需要的LC表。
本实验采⽤线性表实现,采⽤了链式表⽰和顺序表⽰两种实现⽅式。
根据各⾃的特点,链式表⽰对应了第⼆种合并⽅式,⽽顺序表⽰对应了第⼀种合并⽅式。
⼆、数据结构——线性表1、链式表⽰:链式表⽰的特点是⽤⼀组任意的存储单元存储线性表的数据元素,每个元素包括两个域——数据域和指针域。
其中数据域是存储数据信息的域,本实验中默认所处理的数据元素都是在整型(int)范围内的数据;指针域中存储⼀个指针,指向当前元素的下⼀个元素的地址。
n个结点按照如上关系连接起来,形成⼀个链表,就是线性表的链式表⽰。
由于链式表⽰对于数据的插⼊、删除操作⽐较⽅便,⽽查找⼀个元素的效率⽐较低下,于是选择⽤第⼆种合并⽅式,即以LA为母表,将LB 中的元素⼀个⼀个插⼊LA中。
⾸先,每个结点的是⼀个node型的变量,包含⼀个int型变量Num和⼀个node*型的指针变量next。
正如上⽂所描述,Num保存该结点的数值,next保存逻辑上下⼀个结点的地址。
然后定义了⼀个名叫MyList的类,其中有private型的变量包含线性表⾃⾝的基本变量,⽐如元素个数、⾸地址等等;还包括public型的线性表的基本操作函数,⽐如初始化(InitList)、清除(ClearList)、打印(PrintList)等等。
线性表的存储结构定义及基本操作
一、实验目的:. 掌握线性表的逻辑特征. 掌握线性表顺序存储结构的特点,熟练掌握顺序表的基本运算. 熟练掌握线性表的链式存储结构定义及基本操作. 理解循环链表和双链表的特点和基本运算. 加深对顺序存储数据结构的理解和链式存储数据结构的理解,逐步培养解决实际问题的编程能力二、实验内容:(一)基本实验内容(顺序表):建立顺序表,完成顺序表的基本操作:初始化、插入、删除、逆转、输出、销毁, 置空表、求表长、查找元素、判线性表是否为空;1.问题描述:利用顺序表,设计一组输入数据(假定为一组整数),能够对顺序表进行如下操作:. 创建一个新的顺序表,实现动态空间分配的初始化;. 根据顺序表结点的位置插入一个新结点(位置插入),也可以根据给定的值进行插入(值插入),形成有序顺序表;. 根据顺序表结点的位置删除一个结点(位置删除),也可以根据给定的值删除对应的第一个结点,或者删除指定值的所有结点(值删除);. 利用最少的空间实现顺序表元素的逆转;. 实现顺序表的各个元素的输出;. 彻底销毁顺序线性表,回收所分配的空间;. 对顺序线性表的所有元素删除,置为空表;. 返回其数据元素个数;. 按序号查找,根据顺序表的特点,可以随机存取,直接可以定位于第i 个结点,查找该元素的值,对查找结果进行返回;. 按值查找,根据给定数据元素的值,只能顺序比较,查找该元素的位置,对查找结果进行返回;. 判断顺序表中是否有元素存在,对判断结果进行返回;. 编写主程序,实现对各不同的算法调用。
2.实现要求:对顺序表的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价;. “初始化算法”的操作结果:构造一个空的顺序线性表。
对顺序表的空间进行动态管理,实现动态分配、回收和增加存储空间;. “位置插入算法”的初始条件:顺序线性表L 已存在,给定的元素位置为i,且1≤i≤ListLength(L)+1 ;操作结果:在L 中第i 个位置之前插入新的数据元素e,L 的长度加1;. “位置删除算法”的初始条件:顺序线性表L 已存在,1≤i≤ListLength(L) ;操作结果:删除L 的第i 个数据元素,并用e 返回其值,L 的长度减1 ;. “逆转算法”的初始条件:顺序线性表L 已存在;操作结果:依次对L 的每个数据元素进行交换,为了使用最少的额外空间,对顺序表的元素进行交换;. “输出算法”的初始条件:顺序线性表L 已存在;操作结果:依次对L 的每个数据元素进行输出;. “销毁算法”初始条件:顺序线性表L 已存在;操作结果:销毁顺序线性表L;. “置空表算法”初始条件:顺序线性表L 已存在;操作结果:将L 重置为空表;. “求表长算法”初始条件:顺序线性表L 已存在;操作结果:返回L 中数据元素个数;. “按序号查找算法”初始条件:顺序线性表L 已存在,元素位置为i,且1≤i≤ListLength(L)操作结果:返回L 中第i 个数据元素的值. “按值查找算法”初始条件:顺序线性表L 已存在,元素值为e;操作结果:返回L 中数据元素值为e 的元素位置;. “判表空算法”初始条件:顺序线性表L 已存在;操作结果:若L 为空表,则返回TRUE,否则返回FALSE;分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。
(01)两个线性表的归并及其应用-PPT课件
引例:
pc->next=pa; pc=pa;
La=(3,5,8,11)
pa=pa->next; } else { pc->next=pb; pc=pb;
Lb=(2,6,8,9,11,15,20) pb=pb->next; }
则:求La与Lb的归并},得结果线性表Lc如下:
Lc Lc=(2,3,5,6,8,8,9,1if1(,p11b,)1p5c,2-0>)next=pb;
Lb=(2,6,8,9,11,15,20) pb=pb->next; }
则:求La与Lb的归并},得结果线性表Lc如下:
Lc Lc=(2,3,5,6,8,8,9,1if1(,p11b,)1p5c,2-0>)next=pb;
单链表的物理实现过el程se :pc->next=pa;
La
pa
^
pc
Lb
3
5
单链表的物理实现过程:
La pa
Lb
3
5
8
11 ^
2
6
8
9
11
15
20 ^
pb
一、两个w线hifil(ep性a(p->a表d&at&a的<p=bp归)b{ ->并data){
引例:
pc->next=pa; pc=pa;
La=(3,5,8,11)
pa=pa->next; } else { pc->next=pb; pc=pb;
单链表的物理实现过程:
La pa
Lb
3
5
8
11 ^
2
6
8
9
11
《数据结构》吕云翔编著第2章线性表习题解答
《数据结构》吕云翔编著第2章线性表习题解答数据结构第2章线性表习题解答一、习题解答1. 假设有一个线性表L={a1, a2, ..., an},设计一种算法,将线性表的所有元素逆置。
解答:可以使用两个指针i和j,分别指向线性表的第一个元素和最后一个元素,然后交换这两个指针所指向的元素,接着i向后移动一个单位,j向前移动一个单位,再次交换他们所指向的元素。
依次类推,直到i和j指针相遇为止。
这样就完成了线性表的逆置。
2. 设线性表L={a1, a2, ..., an},设计一个算法,删除其中所有值为x 的元素。
解答:可以使用一个指针i遍历线性表,当遇到一个元素值等于x 时,将该元素删除,同时将后面的元素依次前移一位。
直到整个线性表遍历完毕。
3. 设有两个线性表LA={a1, a2, ..., am}和LB={b1, b2, ..., bn},其中元素递增有序排列。
设计一个算法,将LA和LB合并成一个新的线性表LC,且元素递增有序排列。
解答:可以使用两个指针i和j分别指向LA和LB的第一个元素,并且使用一个指针k指向LC的最后一个元素。
比较LA[i]和LB[j]的大小,将较小的元素插入到LC的末尾,然后相应指针后移一位,直到其中一个指针到达对应线性表的末尾。
最后,将剩余的元素插入到LC的末尾,即可得到合并后的线性表LC。
4. 设线性表L={a1, a2, ..., an},设计一个算法,找出其中最大的元素以及最大元素的位置。
解答:可以使用一个变量max记录当前遍历到的最大元素,初始化为L[0],同时使用变量position记录最大元素的位置,初始值也为0。
然后遍历整个线性表,若遇到L[i]大于max,则更新max为L[i],同时更新position为i。
遍历完毕后,max就是最大元素,position就是最大元素的位置。
5. 在线性表L={a1, a2, ..., an}中,设计一个算法,找出倒数第k个位置上的元素。
数据结构与算法期中考试卷(含答案)
数据结构与算法期中考试卷(含答案)⽟林师范学院期中课程考试试卷(2010——2011学年度第⼀学期)命题教师:刘恒命题教师所在系:数计系课程名称:数据结构与算法考试专业:信计考试年级:09级⼀、单项选择题(每题2分,共30分,把正确答案填⼊表格中) 1、在数据结构中,从逻辑上可以把数据结构分成( C )。
A 、动态结构和静态结构B 、紧凑结构和⾮紧凑结构C 、线性结构和⾮线性结构D 、逻辑结构和存储结构 2、结构中的数据元素之间存在⼀个对多个的关系,称为(B )结构。
A 、线性 B 、树形 C 、图状 D 、⽹状 3、以下关于线性表的说法不正确的是(C )。
A 、线性表中的数据元素可以是数字、字符、记录等不同类型。
B 、线性表中包含的数据元素个数不是任意的。
C 、线性表中的每个结点都有且只有⼀个直接前驱和直接后继。
D 、存在这样的线性表:表中各结点都没有直接前驱和直接后继。
4、关于单链表的说法,请选出不正确的⼀项( C)。
A 、逻辑相邻、物理不⼀定相邻B 、不能随机存取C 、插⼊与删除需移动⼤量元素D 、表容量易于扩充 5、关于顺序表的说法,请选出不正确的⼀项(D )。
A 、逻辑相邻、物理相邻 B 、可实现随机存取 C 、存储空间使⽤紧凑 D 、表容量易于扩充6、设N 为正整数,试确定下列程序段中前置以记号@语句的频度为(A )。
x=91;y=100;while(y>0){@if(x>100){x-=10;y--;} else x++; } A 、1100 B 、 9100 C 、110 D 、 9107、在顺序表中删除⼀个元素,平均需要移动( C)元素,设表长为n 。
A、n/2-1 B 、n/2+1C 、n/2D 、(n+1)/28、对单链表执⾏下列程序段,请选出正确的⼀项( A)。
T=P;While(T->next!=NULL ){T —>data=T —>data*2;T=T —>next;} A 、R->data=4 B 、R->data=8C 、H->data=4D 、Q->data=79、若⼀个栈的输⼊序列是1,2,3,┅,n ,输出序列的第⼀个元素是n,则第k 个输出元素是( C)。
数据结构C语言版 线性表的单链表存储结构表示和实现
#include 〈stdio.h>#include <malloc。
h>#include 〈stdlib.h>/*数据结构C语言版线性表的单链表存储结构表示和实现P28—31编译环境:Dev-C++ 4。
9。
9。
2日期:2011年2月10日*/typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data; //数据域struct LNode *next;//指针域}LNode, *LinkList;// typedef struct LNode *LinkList;// 另一种定义LinkList的方法// 构造一个空的线性表Lint InitList(LinkList *L){/*产生头结点L,并使L指向此头结点,头节点的数据域为空,不放数据的。
void *malloc(size_t)这里对返回值进行强制类型转换了,返回值是指向空类型的指针类型.*/(*L)= (LinkList)malloc(sizeof(struct LNode) );if( !(*L))exit(0);// 存储分配失败(*L)-〉next = NULL;// 指针域为空return 1;}// 销毁线性表L,将包括头结点在内的所有元素释放其存储空间。
int DestroyList(LinkList *L){LinkList q;// 由于单链表的每一个元素是单独分配的,所以要一个一个的进行释放while(*L ){q = (*L)—〉next;free(*L );//释放*L = q;}return 1;}/*将L重置为空表,即将链表中除头结点外的所有元素释放其存储空间,但是将头结点指针域置空,这和销毁有区别哦。
不改变L,所以不需要用指针。
*/int ClearList( LinkList L ){LinkList p,q;p = L—〉next;// p指向第一个结点while( p ) // 没到表尾则继续循环{q = p—>next;free( p );//释放空间p = q;}L—>next = NULL; // 头结点指针域为空,链表成了一个空表return 1;}// 若L为空表(根据头结点L—〉next来判断,为空则是空表),则返回1,// 否则返回0.int ListEmpty(LinkList L){if(L—>next ) // 非空return 0;elsereturn 1;}// 返回L中数据元素个数。
实习01_线性表的顺序存储和操作(有序表的合并)
实验一线性表的顺序存储和操作(有序表的合并)1.目的用顺序表(SqList)类型实现书上算法2.1和2.2,了解线性表及在计算机中的两类不同的存储结构;熟练掌握线性表的查找、插入和删除等算法并灵活运用这些算法。
2.要求用C语言编写程序,其中Lb={2,4,6,8,10} La={1,2,3,4,5},①算法2.1执行后,得到的new La = 1,2,3,4,5,6,8,10②修改Lb=2,6,8,9,11,15,20,并利用新生成的La,得到合并后的Lc,Lc= 1,2,2,3,4,5,6,6,8,8,9,10,11,15,203、预习要求:1、复习书上第20页的例2-1和例2-2;2、复习算法2.3,理解如何构造线性表;3、复习算法2.7,理解算法的执行步骤和含义;4、项目介绍:前面的课程已经学习了如何用C语言描述顺序表、如何初始化顺序表、以及如何在顺序表中插入和删除数据元素。
现在通过两个顺序表的合并的实验,加深对顺序表的理解,熟悉如何将逻辑上的数学模型转化为计算机能够理解的指令代码。
该实验是数据结构课程的第一个实验,实验的目标除了加深理解课堂内容外,还对学生的动手能力提出了更高的要求,锻炼学生动手的能力。
5、算法设计#include <stdio.h>#include <stdlib.h>#include <malloc.h># define TRUE 1# define ERROR 0# define OK 1# define OVERFLOW -2# define FALSE 0# define LIST_INIT_SIZE 10# define LISTINCREMENT 5void main(){List La,Lb,Lc;int j,b[7]={2,6,8,9,11,15,20};InitList(La); // 创建空表La。
如不成功,则会退出程序的运行for(j=1;j<=5;j++) // 在表La中插入5个元素,依次为1、2、3、4、5 ListInsert(La,j,j);printf("La= ");ListTraverse(La,printer); // 输出表La的内容InitList(Lb); // 创建空表Lbfor(j=1;j<=5;j++) // 在表Lb中插入5个元素,依次为2、4、6、8、10 ListInsert(Lb,j,2*j);printf("Lb= ");ListTraverse(Lb,printer); // 输出表Lb的内容Union(La,Lb); // 调用算法2.1,将Lb中满足条件的元素插入La(不改变Lb) printf("new La= ");ListTraverse(La,printer); // 输出新表La的内容ClearList(Lb); // 清空表Lbfor(j=1;j<=7;j++) // 在表Lb中重新依次插入数组b[]的7个元素ListInsert(Lb,j,b[j-1]);printf("Lb= ");ListTraverse(Lb,printer); // 输出表Lb的内容MergeList(La,Lb,Lc); // 调用算法2.2,生成新表Lc(不改变表La和表Lb)printf("Lc= ");ListTraverse(Lc,printer); // 输出表Lc的内容}6.小结线性表是软件设计中最基础的数据结构。
实验报告
2.将实验材料(附件)中的c1.h和linklist.cpp文件复制到同一个文件夹中。
其中,c1.h中包含程序中常用的头文件及宏定义,以后每次都要记得将该文件包括到你的源程序中。
linklist.cpp中包含线性表顺序存储结构的定义和部分基本操作的实现。
实验报告
课程名称
数据结构
实验名称
线性表的链式存储结构
实验间
11月4日星期二下午
实验地点
数学院楼504
班级
信息1班
学号
姓名
一、实验目的与要求
实验目的:了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法。
实验要求:1,根据实验内容编程,上机调试,得出正确的运行程序。
2,编译运行程序,观察运行情况和输出结果。
3,写出实验报告。
二、实验内容与步骤
一.实验内容
1.利用基本操作实现两个有序表合并(教材算法2.2)
2.补充未完成的基本操作:InitList,DestroyList,ListLength,ListTraverse,GetElem,ListInsert
3.记录实验过程并总结实验经验,完成实验报告。
二.实验步骤
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?pa:pb;
free(Lb);
}
2,调用基本操作的好处:调用基本操作的过程中没有破坏链表的原始结构。更容易理解程序每一步操作的含义,结构条理清楚,增加程序的可读性。
指导老师
评分情况
void MergeList(LinkList La,LinkList Lb,LinkList &Lc) //算法2.2
实验1线性表的基本操作
实验一线性表的基本操作一、线性结构的顺序表基本操作实验目的1.学会定义单链表的结点类型、线性表的顺序存储类型,实现C程序的基本结构,对线性表的一些基本操作和具体的函数定义。
2.掌握顺序表的基本操作,实现顺序表的插入、删除、查找以及求并集等运算。
3.掌握对多函数程序的输入、编辑、调试和运行过程。
实验要求1.预习C语言中结构体的定义与基本操作方法。
2.对顺序表的每个基本操作用单独的函数实现。
3.编写完整程序完成下面的实验内容并上机运行。
实验内容1.编写程序实现顺序表的下列基本操作:(1)初始化顺序表La。
(2)将La置为空表。
(3)销毁La。
(4)在La中插入一个新的元素。
(5)删除La中的某一元素。
(6)在La中查找某元素,若找到,则返回它在La中第一次出现的位置,否则返回0。
(7)打印输出La中的元素值。
2.(选做)编写程序完成下面的操作:(1)构造两个顺序线性表La和Lb,其元素都按值非递减顺序排列。
(2)实现归并La和Lb得到新的顺序表Lc,Lc的元素也按值非递减顺序排列。
(3)假设两个顺序线性表La和Lb分别表示两个集合A和B,利用union_Sq操作实现A=A∪B。
二、单链表基本操作(选做)实验目的1. 学会定义单链表的结点类型、线性表的链式存储类型,实现对单链表的一些基本操作和具体的函数定义,了解并掌握单链表的类定义以及成员函数的定义与调用。
2. 掌握单链表基本操作及两个有序表归并、单链表逆置等操作的实现。
实验要求1.预习C语言中结构体的定义与基本操作方法。
2.对单链表的每个基本操作用单独的函数实现。
3.编写完整程序完成下面的实验内容并上机运行。
实验内容1.编写程序完成单链表的下列基本操作:(1)初始化单链表La。
(2)在La中插入一个新结点。
(3)删除La中的某一个结点。
(4)在La中查找某结点并返回其位置。
(5)打印输出La中的结点元素值。
2.构造一个单链表L,其头结点指针为head,编写程序实现将L逆置。
实验线性表操作
实验一线性表基本操作一、实验目的1、理解线性表的数据结构及其应用2、掌握线性表的顺序存储方式及其基本操作(建表、插入、删除)3、掌握线性表的链式存储方式以及基本操作(建表、插入、删除)4、理解链式存储的概念和具体语言环境下的表示方法二、实验内容1、顺序表的操作具体要求:(1)顺序表的存储结构typedef struct {int *data;//整型数据元素,可以是其它类型int length;//顺序表的当前长度(元素个数)int listsize;//当前分配的存储容量(已经分配的内存空间大小)}SqList;或者#define N 10;int data[N];//用数组来模拟实现顺序表(2)构造一个空表L函数: void InitList_Sq(SqList *L)(3)分别建立有n个数据元素的顺序表函数 void CreatList_Sq(SqList *L,int n)(4)在第i个元素之前插入一个数据元素函数void InsertList_Sq(SqList *L ,int e)(5)删除一个数据元素e函数 int ListDelete_Sq(SqList *L, int i)(6)结果显示:输出顺序表中的数据元素函数 void ShowList_Sq(SqList *L)(7)顺序表元素排序:对顺序表中元素按非递减排序(选做)函数 void SortList_Sq(SqList *L)(8)归并两个有序的(非递减排列)顺序表Sq_LA和 Sq_LB,新表Sq_Lnew中数据元素非递减排列(选做)函数void MergeList_Sq(SqList *La, SqList *Lb, SqList *Lc)实验步骤:源程序主函数如下:运行结果:图1.1顺序表进行归并操作前、后的各个表中数据元素2、建立一个线性链表(单链表),实现单链表上数据元素的插入、删除操作。
具体要求:(1)单链表的存储结构typedef struct LNode{char data; //数据元素为字符类型,可以为其它类型,例如整型struct LNode *next;// 指向后继结点的指针}LNode, *LinkList;(2)构造一个空的单链表函数 LinkList InitList_L(void)(3)建立一个带头节点的具有n个结点的单链表L函数尾插法LinkList CreatList_L_T(int n) 或头插法LinkList CreatList_L(int n)(4)在单链表LA上插入一个数据元素i_e,插入位置为i(1<i<n)函数LinkList ListInsert_L(LinkList L,int i,char i_e)(5)在单链表LA上删除第i个数据元素,并用r_e来返回删除的数据元素值函数LinkList ListDelete_L(LinkList L,int i)(6)结果显示:输出单链表进行插入(删除)操作前、后的数据元素函数 void ShowList(LinkList L)实验步骤:源程序主函数如下:运行结果:图1.2 单链表进行插入(删除)操作前、后的数据元素三、问题讨论四、实验心得附:程序源代码一(不包含在实验报告里边)/*顺序表操作*/#include <stdio.h>#include <string.h>#include <stdlib.h>#define LIST_INIT_SIZE 50#define LISTINCREMENT 20#define M 6 //LA中元素个数#define N 4//LB中元素个数typedef int ElemType;/*顺序表的当前长度(元素个数)length,当前分配的存储容量(已经分配的内存空间大小)listsize*/ typedef struct{int *data;int length;int listsize;}SqList;/*书上算法2.3,初始化线性表,分配存储空间*/void InitList_Sq(SqList *L){L->data = (int *)malloc(LIST_INIT_SIZE*sizeof(int));//分配100个数据元素大小的空间if (!L->data)printf("存储空间分配失败");L->length = 0; // 空表长度为0L->listsize = LIST_INIT_SIZE; // 初始存储容量return;} // InitList_Sq/*书上算法2.4,线性表插入元素*/void ListInsert_Sq(SqList *L, int i, int e) {// 在顺序线性表L的第i个元素之前插入新的元素e// i的合法值为1≤i≤L->length+1int *p,*q;if (i < 1 || i > L->length+1)printf("i值不合法");if (L->length >= L->listsize) { // 当前存储空间已满,增加容量int *newbase = (int *)realloc(L->data,(L->listsize+LISTINCREMENT)*sizeof (int));if (!newbase)printf("存储分配失败");// 存储分配失败L->data = newbase; // 新基址L->listsize += LISTINCREMENT; // 增加存储容量q = &(L->data[i-1]); // q为插入位置for (p = &(L->data[L->length-1]); p>=q; --p)*(p+1) = *p; // 插入位置及之后的元素右移*q = e; // 插入e++L->length; // 表长增1} // ListInsert_Sqint ListDelete_Sq(SqList *L, int i) { // 算法2.5// 在顺序线性表L中删除第i个元素,并用e返回其值。
数据结构--两个线性表的归并及其应用
两个线性表的归并
pa
3 Lb 2 pb
5
8
11
^
11 15 20
6
8
9
^
pc Lc La
while (pa && pb){ if (pa->data<=pb->data){ pc->next=pa; pc=pa; 引例: 引例: pa=pa->next; } La=(3,5,8,11) else { pc->next=pb; pc=pb; Lb=(2,6,8,9,11,15,20) pb=pb->next; } 的归并,得结果线性表 如下: 则:求La与Lb的归并 得结果线性表 如下 求 与 的归并 得结果线性表Lc如下 } Lc=(2,3,5,6,8,8,9,11,11,15,20) 线性链表的物理实现过程: 线性链表的物理实现过程
两个线性表的归并
pa
^
11
pc
3 Lb 2
5
8
^
11 15 20
6 pb
8
9
^
Lc La
while (pa && pb){ if (pa->data<=pb->data){ pc->next=pa; pc=pa; 引例: 引例: pa=pa->next; } La=(3,5,8,11) else { pc->next=pb; pc=pb; Lb=(2,6,8,9,11,15,20) pb=pb->next; } 的归并,得结果线性表 如下: 则:求La与Lb的归并 得结果线性表 如下 求 与 的归并 得结果线性表Lc如下 } if (pb) pc->next=pb; Lc=(2,3,5,6,8,8,9,11,11,15,20) else pc->next=pa; 线性链表的物理实现过程: 线性链表的物理实现过程
数据结构论文--关于线性表的链式结构
数据结构课程小论文题目:线性表的链式表示学号:090510126姓名:叶妍莉班级:090510学院:经济管理学院2011年12月8日一.引言: --------------------------------------------------------------------- 2 - 二.链表的概述 --------------------------------------------------------------- 2 -1.线性链表里的一些概念: ------------------------------------------ 3 -2.链表的有关概述: --------------------------------------------------- 3 -3.链表的存储方法: --------------------------------------------------- 4 -4.链表的分类: --------------------------------------------------------- 4 - 三.线性表的链式实现 ------------------------------------------------------ 4 -1.“插入”和“删除”操作的实现: ------------------------------ 5 -2.“合并链表”操作的实现: --------------------------------------- 6 - 四.链表的优点与缺点 ------------------------------------------------------ 6 - 五.总结 ------------------------------------------------------------------------ 7 -线性表的链式表示姓名:叶妍莉班级:090510 学号:090510126摘要:线性表对于学过数据结构的人来说都是再熟悉不过了,它是数据结构的一个基本内容,是最常用且最简单的一种数据结构。
数据结构算法(第二章)
∥算法2.1: 将所有在线性表Lb中但不在La中的数据元素插入到La中void union(List &La, List Lb){La_len=ListLength(La);Lb_len=ListLength(Lb);for(i=1;i<=Lb_len;i++){GetElem(Lb,i,e);if(!LocateElem(La,e,equal)) ListInsert(La,++La_len,e);}}∥union∥算法2.2: 已知线性表La和Lb中的数据元素按值非递减排列。
∥归并La和Lb得到新的线性表Lc ,Lc的数据元素也接值非递减排列。
void MergeList(ListLa,List Lb, List &Lc){InitList(Lc);i=j=1; k=0;La_len=ListLength(La); Lb_len=ListLengtb(Lb);while((i<=La_len)&&(j<=Lb_len)){∥La和Lb均非空GetElem(La,i,ai);GetElem(Lb,j,bj);if (ai<=bj) { ListInsert(Lc, ++k, ai); ++i; }else{ListInsert(Lc, ++k, bj); ++j;}}while(i<=La_len){GetElem(La, i++, ai); ListInsert(Lc,++k,ai);}while(j<=Lb_len){GetElem(Lb,j++,bj); ListInsert(Lc,++k,bj);}}∥MergeList∥算法 2.3:构造一个空的线性表L。
Status InitList_Sq(SqList &L){L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!L.elem) exit(OVERFLOW);L.length=0;L.listsize=LIST_INIT_SIZE;return oK;}∥InitList_Sq∥算法2.4:在顺序线性表L中第i个位置之前插入新的元素e,∥i的合法值为1≤i≤ListLength_ Sq(L)+1Status ListInsert_ Sq(SqList &L, int i, ElemType e){if(i<1|| i>L.length+1) return ERROR;if (L.length>=L.listsize){newbase= (ElemType *)realloc(L.elem, (L.listsize+ LISTINCREMENT)* sizeof(ElemType));if(!newbase)exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}q=& (L.elem[i-l]);for(p=&(L.elem[L.length-l]);p>=q;--p)*(p+1)=*p;*q=e;++L.length;return OK;}∥Listlnsert_ Sq∥算法2.5:在顺序线性表L中删除第i个元素,并用e返回其值∥i的合法值为1≤i≤ListLength_ Sq(L)Status ListDelete_ Sq(SqList &L, int i,ElemType &e){if((i<1)|(1> L.length)) return ERROR;p=&(L.elem[i-l]);e=*p;q=L.elem+L.length -1;for(++p;p<=q;++p) *(p一1)=*p;--L.length;Return OK;}//ListDelete_Sq算法2.6:在顺序线性表L中查找第1个值与e满足compare()的元素的位序,//若找到,则返回其在L中的位序,否则返回0LocateElem_Sq(SqList_L, ElemType e, Status(*compare)(ElemType,ElemType)){;L.elem;while(i<=L.length&&!(*compare)(*p++,e)) ++i;if(i<=L.length) return i;else return0;}∥LocateElem_Sq∥算法2.7:已知顺序线性表La和Lb的元素按值非递减排列∥归并La和Lb得到新的顺序线性表Lc ,Lc的元素也按值非递减排列void MergeList_ Sq(SqList La, SqList Lb, SqList &Lc){pa=La.elem; pb=Lb.elem;Lc.listsize=Lc.length=La.length+Lb.length;pc=Lc.elem=(ElemType* )malloc(Lc.listsize* sizeof(ElemType));if(!Lc.elem) exit(OVERFLOW);pa_last=La.elem+La.length-l;pb_last=Lb.elem+Lb.length-l;while (pa<=pa_last&&pb<=pb_last){*pc++=*pa++;while (pa<=pa_ last) *pc++=*pa++;while (pb<=pb_ last) *pc++=*pb++;}∥MergeList_Sq∥算法2.8:L为带头绪点的单链表的头指针。
顺序表的基本操作
L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if (!L.elem) exit(OVERFLOW); /*初始化失败,返回0*/
L.length = 0; /*置空表长度为0*/
#define INCREM 10 /*溢出时,顺序表长度的增量*/
enum Status {
OK,
ERROR
};
typedef int ElemType; /*定义表元素的类型*/
typedef struct LNode{
ElemType data; /*结点的数据域*/
struct LNode *next; /*结点的指针域*/
int LocateElem_L(LinkList L,ElemType e); //查找出第1个与e相等的数据元素位置
void ListConvert_L(LinkList &L); //单链表翻转
void FreeList_L(LinkList L); //销毁单链表
/*linkListOp.cpp文件*/
if(L.length > 0)
return 1;
else
return 0;
}
/* main.cpp文件*/
#include <stdio.h>
#include <malloc.h>
#include "sqlistOp.h"
void main(){
SqList L;
printf("准备创建顺序表\n");
数据结构经典考题
14、己知两个存放整数的有序单链表(己按整数从小至大的顺序排序),指针L1和L2分别指向这两个单链表的头结点。设计一个算法,将L1和L2合并成一个单链表,且新的链表仍按整数由小到大的顺序排列,新的单链表的结点由L1和L2的结点构成。要求合并后的单链表利用原来单链表的存储空间。
(1)Q=P->NEXT;
(2)P->DATA=P->NEXT->DATA;
(3)P->NEXT=Q->NEXT或P->NEXT->NEXT;
(4)FREE(Q);
11、在一个双链表中,删除*P结点之后的一个结点的操作是_ C 。
A: P->NEXT=P->NEXT->NEXT;
对链表设置头结点的作用是什么?(至少说出两条好处)答:
(1) 对带头结点的链表,在表的任何结点之前插入结点或删除表中任何结点,所要做的都是修改前一结点的指针域,因为任何元素结点都有前驱结点。若链表没有头结点,则首元素结点没有前驱结点,在其前插入结点或删除该结点时操作会复杂些。
(2) 对带头结点的链表,表头指针是指向头结点的非空指针,因此空表与非空表的处理是一样的。
WHILE(P!=NULL&&P->DATA<MINK) //*R为*P的前驱结点
{
R=P;
P=P->NEXT;
}
Q=P; //求值域刚好>MIN
WHILE(Q!=NULL&&Q->DATA>MAXK) //求值域刚好<MAX
18、用不带头结点的单链表存储链栈,设计进栈和出栈相应的算法。
将非递减有序排列(LL1)归并为一个新的线性表L2线性表L2中的元素仍按值非递减
将⾮递减有序排列(LL1)归并为⼀个新的线性表L2线性表L2中的元素仍按值⾮递减#include "stdio.h"#include "stdlib.h"#include "function.h"void main(){Sqlist L,L1,L2;InitList(&L);InitList(&L1);InitList(&L2);ListInsert(&L, 1, 3);//f(n)ListInsert(&L, 2, 5);ListInsert(&L, 1, 8);ListInsert(&L, 1, 11);ListInsert(&L1,1,2);ListInsert(&L1,2,6);ListInsert(&L1,3,8);ListInsert(&L1,3,9);ListInsert(&L1,3,11);ListInsert(&L1,3,15);ListInsert(&L1,3,20);//对顺序表L进⾏排序int tmp = 0;for (int i = 0; i <L.length-1; i++){for (int j = i + 1; j < L.length; j++) {if (L.elem[i] > L.elem[j]) {tmp = L.elem[i];L.elem[i] = L.elem[j];L.elem[j] = tmp;}}}tmp = 0;for (int i = 0; i <L1.length - 1; i++){for (int j = i + 1; j < L1.length; j++) {if (L1.elem[i] > L1.elem[j]) {tmp = L1.elem[i];L1.elem[i] = L1.elem[j];L1.elem[j] = tmp;}}}int k = 0;int j = 0;while ((k<L.length)&&(j<L1.length)){if (L.elem[k] <= L1.elem[j]){ListInsert(&L2, L2.length + 1, L.elem[k]);k++;}else{ListInsert(&L2, L2.length + 1, L1.elem[j]);j++;}}if (k >= L.length) {for (int i = j; i < L1.length; i++){ListInsert(&L2, L2.length + 1, L1.elem[i]);}}if (j>=L1.length) {for (int i = k; i < L.length; i++){ListInsert(&L2, L2.length + 1, L.elem[i]);}}//输出顺序链表中的所有值for (int i = 0; i < L2.length; i++){printf("元素的第%d个值为%d\n", i + 1, L2.elem[i]); }}该算法的时间复杂度为O(f(L1)+f(L))。
数据结构0212线性表的合并2.12 线性表的合并
4
6
8
10
11
算法执行后
La
1
78
链式有序表合并
2
4
6
8
10
11
和有序顺序表的合并类似,有序链表的合并 的时间复杂度也为O(m+n),但在归并有序链表的 时候,并不需要另建新表的结点空间,所以空间 复杂度为O(1)。
线性表的合并
线性表的合并
线性表的合并是很常见的一个问题,比如我 们通讯录管理中,可能会涉及到将两个通讯录合 并的问题,学生成绩管理系统中,也可能将两个 班排好序的成绩合并在一起,并依然保持有序。 前面的例子就是一般线性表的合并问题,后面的 例子就是有序表的合并问题。
问题描述
假设利用两个线性表A=AB。
pc
7<8
0123456789 La 1 7 8
pa 0123456789 Lb 2 4 6 8 10 11
pb 0123456789 Lc 1 2 4 6 7
pc
8=8
0123456789 La 1 7 8
pa 0123456789 Lb 2 4 6 8 10 11
pb 0123456789 Lc 1 2 4 6 7 8 8
1<2
0123456789 La 1 7 8
pa 0123456789 Lb 2 4 6 8 10 11
pb 0123456789 Lc 1
pc
2<7
0123456789 La 1 7 8
pa 0123456789 Lb 2 4 6 8 10 11
pb 0123456789 Lc 1 2
pc
4<7
Lc指向La其算 法描述
void MergeList_L(LinkList &La, LinkList
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<stdio.h>#include<malloc.h>#define LIST_INIT_SIZE 100 // 初始化大小#define LISTINCREMENT 15#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1 // 不可实行的#define OVERFLOW -2 // 溢出#include<process.h> // exit()typedef int ElemType; // 基本(元素)类型typedef struct{ElemType * elem;int length;int listsize;}SqList;int InitList(SqList *L)// 操作结果:构造一个空的顺序线性表{(*L).elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!(*L).elem) // 存储分配失败exit(OVERFLOW);(*L).length=0; // 空表长度为0(*L).listsize=LIST_INIT_SIZE; // 初始存储容量return OK;}int DestroyList(SqList *L)// 初始条件:顺序线性表L已存在。
操作结果:销毁顺序线性表L{free((*L).elem);(*L).elem=NULL;(*L).length=0;(*L).listsize=0;return OK;}int ClearList(SqList *L)// 初始条件:顺序线性表L已存在。
操作结果:将L重置为空表{(*L).length=0;return OK;}int ListEmpty(SqList L)// 初始条件:顺序线性表L已存在。
操作结果:若L为空表,则返回TRUE,否则返回FALSE{if(L.length==0)return TRUE;elsereturn FALSE;}int ListLength(SqList L)// 初始条件:顺序线性表L已存在。
操作结果:返回L中数据元素个数{return L.length;}int GetElem(SqList L,int i,ElemType *e)// 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) 。
操作结果:用e返回L中第i个数据元素的值{if(i<1||i>L.length)exit(ERROR);*e=*(L.elem+i-1);return OK;}int LocateElem(SqList L,ElemType e)// 初始条件:顺序线性表L已存在。
操作结果:返回L中第1个与e相等的数据元素的位序。
若这样的数据元素不存在,则返回值为0。
{ElemType *p;int i=1; // i的初值为第1个元素的位序p=L.elem; // p的初值为第1个元素的存储位置while(i<=L.length&&(*p++!=e))++i;if(i<=L.length)return i;elsereturn 0;}int PriorElem(SqList L,ElemType cur_e,ElemType *pre_e)// 初始条件:顺序线性表L已存在。
操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
{int i=2;ElemType *p=L.elem+1;while(i<=L.length&&*p!=cur_e){p++;i++;}if(i>L.length)return INFEASIBLE;else{*pre_e=*--p;return OK;}}int NextElem(SqList L,ElemType cur_e,ElemType *next_e)// 初始条件:顺序线性表L已存在。
操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义{int i=1;ElemType *p=L.elem;while(i<L.length&&*p!=cur_e){i++;p++;}if(i==L.length)return INFEASIBLE;else{*next_e=*++p;return OK;}}int ListInsert(SqList *L,int i,ElemType e)// 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1 。
操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1{ElemType *newbase,*q,*p;if(i<1||i>(*L).length+1) // i值不合法return ERROR;if((*L).length>=(*L).listsize) // 当前存储空间已满,增加分配{newbase=(ElemType*)realloc((*L).elem,((*L).listsize+LISTINCREMENT)*sizeof(ElemType));if(!newbase) // 存储分配失败exit(OVERFLOW);(*L).elem=newbase; // 新基址(*L).listsize+=LISTINCREMENT; // 增加存储容量}q=(*L).elem+i-1; // q为插入位置for(p=(*L).elem+(*L).length-1;p>=q;--p) // 插入位置及之后的元素右移*(p+1)=*p;*q=e; // 插入e++(*L).length; // 表长增1return OK;}int ListDelete(SqList *L,int i,ElemType *e)// 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) 。
操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1{ElemType *p,*q;if(i<1||i>(*L).length) // i值不合法return ERROR;if((*L).length==0) // i值不合法return ERROR;p=(*L).elem+i-1; // p为被删除元素的位置*e=*p; // 被删除元素的值赋给eq=(*L).elem+(*L).length-1; // 表尾元素的位置for(++p;p<=q;++p) // 被删除元素之后的元素左移*(p-1)=*p;(*L).length--; // 表长减1return OK;}void MergeList(SqList La,SqList Lb,SqList *Lc)// 算法2.2// 已知线性表La和Lb中的数据元素按值非递减排列// 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减有序排列{ElemType ai,bj;int La_len,Lb_len;int i=1,j=1,k=0;La_len=ListLength(La); // 求线性表的长度Lb_len=ListLength(Lb);while((i<=La_len)&&(j<=Lb_len)) // La和Lb均非空{GetElem(La,i,&ai); // 取La中第i个数据元素赋给aiGetElem(Lb,j,&bj); // 取Lb中第j个数据元素赋给bjif(ai<=bj) // 将La和Lb中较小的数赋值给Lc{ListInsert(Lc,++k,ai);++i;}else{ListInsert(Lc,++k,bj);++j;}}while(i<=La_len) // 若La中数据元素没有全部赋给Lc,则将剩下的元素都赋给Lc{GetElem(La,i++,&ai);ListInsert(Lc,++k,ai);}while(j<=Lb_len) // 若Lb中数据元素没有全部赋给Lc,则将剩下的元素都赋给Lc{GetElem(Lb,j++,&bj);ListInsert(Lc,++k,bj);}}void print(ElemType *c){printf("%d ",*c);}void main(){SqList La,Lb,Lc;int i,j,k;InitList(&La); // 创建空表La成功printf("请输入La的4个数据元素Please enter the La four data elements:");for(j=1;j<=4;j++) // 在表La中插入4个元素{scanf("%d",&k);i=ListInsert(&La,j,k);}printf("La="); // 输出表La的内容for(i=0;i<La.length;i++)print(&La.elem[i]);printf("\n");InitList(&Lb); // 也可不判断是否创建成功printf("请输入Lb的7个数据元素Please input Lb seven data elements:");for(j=1;j<=7;j++) // 在表Lb中插入7个元素{scanf("%d",&k);i=ListInsert(&Lb,j,k);}printf("Lb="); // 输出表Lb的内容for(i=0;i<Lb.length;i++)print(&Lb.elem[i]);printf("\n");i=InitList(&Lc); // 创建空表La成功MergeList(La,Lb,&Lc);printf("Lc="); // 输出表Lc的内容for(i=0;i<Lc.length;i++)print(&Lc.elem[i]);printf("\n");}。