线性表算法c语言描述
第一章 线性表
11.线性表是A.一个有限序列,可以为空B.一个有限序列,不能为空C.一个无限序列,可以为空D.一个无限序列,可以为空正确答案是:【A】解析:线性表的定义如下:线性表是具有n(n≥0)个元素的一个有限序列,当n=0时称为空表。
2在n个结点的顺序表,算法的时间复杂度是O(1)的操作是A.访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)B.在第i个结点后插入一个新结点(1≤i≤n)C.删除第i个结点(1≤i≤n)D.顺序查找与给定值x相等的元素正确答案是:【A】解析:顺序表可以按元素下标直接存和直接取,其时间复杂度为O(1)。
在第i个元素后面插入新元素和删除第i个元素的时间复杂度都是O(n),顺序查找的时间复杂度也是O(n)。
3若长度为n的线性表采用顺序存储结构,在表的第i个位置插入一个数据元素,需要移动表中数据元素的数目为A.iB.n+iC.n-i+1D.n-i-1正确答案是:【C】解析:在线性表的第i个位置插入一个新的数据元素之前,需要先将线性表的第i个数据元素至第n个数据元素依次后移1个位置,一共需要移动n-i+1个数据元素。
4将两个各有n1和n2个元素的有序表(递增)归并成一个有序表,仍保持其递增顺序,则最少的比较次数是A.B.C.D.正确答案是:【C】解析:由于将长度为n的单链表链接在长度为m的单链表之后的操作,需要把长度为m的单链表遍历一遍,找到最后的一个结点,所以时间复杂度为O (m)。
5已知L是带头结点的单链表,结点p既不是第一个结点,也不是最后一个结点,删除p结点的直接后继结点的语句序列是A.p=p→nextB.p→next=pC.p→next=p→next→nextD.p=p→next→next正确答案是:【C】解析:选项A是删除了当前p结点;选项B是把p结点之后的所有结点都丢失了,同时在p结点本身形成了一个环;选项C正确;选项D是把p和p的后继结点都删除了。
6设双向循环链表中结点的结构为(prior,data,next),且不带表头结点。
《数据结构-c语言描述》教学大纲
教与学|数据结构一C语言描述(教学大纲)一、课程基本信息二、课程描述和目标1•课程描述本课程是高等院校计算机类相关专业一门重要的学科基础课,也是本校计算机科学与技术、软件工程、网络工程、大数据与科学技术等专业的计算机大类平台必修课。
本课程主要讨论各种数据的抽象表示、实现方法、处理数据的算法设计以及对算法性能的分析。
它的先修课程是:高级语言程序设计,后继课程是:数据库原理、操作系统等。
本课程的教学依赖于其先修课程,又能为其后续课程及进一步的软件开发奠定良好的理论与实践基础。
2.课程目标结合专业人才培养方案,并基于新工科专业OBE理念,力求通过本课程的系统学习促进学生在知识、能力和素质三方面得到一定程度的提升。
课程目标1:能够清楚表述数据结构和算法的基本概念,并能判断计算机处理不同数据时所采用的组织方法、操作原理和实现方法。
课程目标2:能够针对具体问题,运用数据结构课程相关知识和批判思维,分析计算机处理对象的结构特征,选择合适的数据存储结构,设计高效的操作算法。
课程目标3:能够综合运用数据结构的基本原理和设计方法,研究复杂问题的特征,自主设计可行的求解方案,并能运用高级语言编写实现问题求解的应用程序,再验证其正确性。
三、课程目标对毕业要求的支撑关系四、教学内容、基本要求及学时分配本课程教学内容主要包括线性表、栈和队列、串与数组、树和图等主要数据结构的特点、在计算机内部的表示和实现原理与方法分析,以及查找和排序两种主要操作的各种实线性表的应用奋斗一我自己励志的故事栈的应用奉献-开源技术背后的故事10分钟矩阵的压缩存储节约-提升资源复用水平、降低资源消耗的相关故事10分钟哈夫曼树与哈夫曼编码(压创新-工匠精神,余立平冒着巨大的危险雕刻火药的10分钟缩技术)航天人的故事拓扑排序、关键路径分布式-跨地域信息沟通水平,是升社会安全的故事10分钟二叉排序树上的查找快速排序效率-有关提升计算资源利用率以及社会生产效率10分钟的故事协作一有关专业分工、各司其职的螺丝钉精神的故10分钟五、课程重难点六、课程要求及成绩评定1.教学环节及其组织形式本课程采用线上线下相结合的混合式教学模式实施教学,整个教学分课前、课中、课后三个环节进行组织教学活动。
数据结构(C语言版)
比较
Prim算法适用于稠密图, Kruskal算法适用于稀疏图;
两者时间复杂度相近,但 Kruskal算法需额外处理并查
集数据结构。
最短路径算法设计思想及实现方法比较
1 2
Dijkstra算法
从源点出发,每次找到距离源点最近的顶点并更 新距离值,直至所有顶点距离确定。适用于不含 负权边的图。
Floyd算法
特殊二叉树
满二叉树、完全二叉树等。
二叉树的遍历与线索化
二叉树的遍历
前序遍历、中序遍历、后序遍历和层 次遍历是二叉树的四种基本遍历方法 。
线索化二叉树
为了方便查找二叉树节点的前驱和后 继,可以对二叉树进行线索化处理, 即在节点的空指针域中存放指向前驱 或后继的指针。
树和森林的遍历与转换
树的遍历
01
串的顺序存储结构
01
02
03
串的顺序存储结构是用 一组地址连续的存储单 元来存储串中的字符序
列的。
按照预定义的大小,为 每个定义的串变量分配 一个固定长度的存储区 ,一般是用定长数组来
定义。
串值的存储:将实际串 长度值保存在数组的0下 标位置,串的字符序列 依次存放在从1开始的数
组元素中。
串的链式存储结构
03
比较
DFS空间复杂度较低,适用于递 归实现;BFS可找到最短路径, 适用于非递归实现。
最小生成树算法设计思想及实现方法比较
Prim算法
从某一顶点开始,每次选择当 前生成树与外界最近的边加入 生成树中,直至所有顶点加入
。
Kruskal算法
按边权值从小到大排序,依次 选择边加入生成树中,保证不
形成环路。
数据结构(C语言版)
线性表练习题答案
第2章线性表练习题答案一、填空1. 向一个长度为n的向量的第i个元素(1≤i≤n+1)之前插入一个元素时,需向后移动n-i+1 个元素。
2. 向一个长度为n的向量中删除第i个元素(1≤i≤n)时,需向前移动n-i 个元素。
3. 在顺序表中访问任意一结点的时间复杂度均为O(1),因此,顺序表也称为随机存取的数据结构。
4. 在单链表中,除了首元结点外,任一结点的存储位置由其直接前驱结点的链域的值指示。
5.在n个结点的单链表中要删除已知结点*p,需找到它的前驱结点的地址,其时间复杂度为O(n)。
二、判断正误(×)1. 链表的每个结点中都恰好包含一个指针。
答:错误。
链表中的结点可含多个指针域,分别存放多个指针。
例如,双向链表中的结点可以含有两个指针域,分别存放指向其直接前趋和直接后继结点的指针。
(×)2. 链表的物理存储结构具有同链表一样的顺序。
错,链表的存储结构特点是无序,而链表的示意图有序。
(×)3. 链表的删除算法很简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动。
错,链表的结点不会移动,只是指针内容改变。
(×)4. 线性表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。
错,混淆了逻辑结构与物理结构,链表也是线性表!且即使是顺序表,也能存放记录型数据。
(×)5. 顺序表结构适宜于进行顺序存取,而链表适宜于进行随机存取。
错,正好说反了。
顺序表才适合随机存取,链表恰恰适于“顺藤摸瓜”(×)6. 顺序存储方式的优点是存储密度大,且插入、删除运算效率高。
错,前一半正确,但后一半说法错误,那是链式存储的优点。
顺序存储方式插入、删除运算效率较低,在表长为n的顺序表中,插入和删除一个数据元素,平均需移动表长一半个数的数据元素。
(×)7. 线性表在物理存储空间中也一定是连续的。
错,线性表有两种存储方式,顺序存储和链式存储。
数据结构作业答案
数据结构作业答案单选题1、下列关于算法的基本特征,说法不正确的是()。
能行性是算法中的每一个步骤必须能够实现且能达到预期的目的。
算法的确定性是指算法中的每一个步骤必须是有明确的定义,不允许模棱两可。
算法的有穷性是指算法必须能在有限的时间内做完。
算法与提供情报无关。
[D] 教师批改:D2、算法的时间复杂度取决于()。
问题的规模待处理的数据的初态问题的难度 A 和 B[D] 教师批改:D3、下列选项中,不是算法基本特征的是()。
可行性有穷性确定性高效率[D] 教师批改:D4、通常一个好的算法应达到的目标中,不包括()。
正确性可读性技巧性健壮性[C] 教师批改:C5、在一般的计算机系统中,基本的运算和操作不包括()。
语法处理算术运算关系运算数据传输[A] 教师批改:A6、工程上常用的分治法是()。
列举法归纳法减半递推技术回溯法[C] 教师批改:C多选题7、算法设计的要求包括()。
正确性可读性健壮性唯一性[ABC] 教师批改:A,B,C8、算法的时间复杂度应该与()无关。
所使用的计算机程序设计语言基本运算的执行次数程序编制者[ABD] 教师批改:A,B,D9、下列关于算法的描述中,不正确的有()。
算法即是计算机程序算法是解决问题的计算方法算法是排序方法算法是解决问题的有限运算序列[ABC] 教师批改:A,B,C填空题16、所谓算法是指()。
教师批改:解题方案的准确而完整的描述17、算法的基本特征有()、()、()和()教师批改:能行性、确定性、有穷性和拥有足够的情报。
18、一个算法通常由两种基本要素组成,它们是()和()。
教师批改:算法中对数据的运算和操作。
算法的控制结构。
19、工程上常用的几种算法设计方法有列举法、()、()、()、()和回溯法。
教师批改:归纳法、递推、递归、减半递推技术。
20、算法的复杂度主要包括()复杂度和()复杂度。
教师批改:时间、空间综合题21、设给定3个整数a,b,c,试写出寻找这3个整数的中数的算法;并分析在平均情况与最坏情况下,该算法分别要做多少次比较?寻找这3个整数的中数的算法用C语言描述如下(中数m由函数值返回):int mid ( int a, int b, int c){ int m ; m=a ;if ( m>=b ) { if (m>=c) { if ( b>=c ) m=b ; else m=c ; } }else { if ( m<=c) { if (b>=c) m=c; else m=b ; } }return ( m ) ;}假设a,b,c中的每一个数为中数的概率相等(均为1/3)。
C语言:2.2 线性表及其顺序存储结构
线性表中数据元素的个数n称为线性表的长度
2.线性表的顺序存储结构
2.2.1 线性表及其运算
… a1 a2 … ai-1 ai … an …
第1个元素的存储地址,即线性表的起始地 址,称作线性表的基地址
每个数据元素所占的
线性表的顺序存储结构具有的特点: 存储空间(子节数) (1)所有元素所占的存储空间是连续的 (2)各元素在存储空间中是按逻辑顺序
v[i-1]=b;
//插入新元素
n=n+1;
//线性表长度增加1
return;
}
4.线性表在顺序存储结构下的删除运算 2.2.1 线性表及其运算
例2 删除线性表(21,18,30,75,66,42,56,87) 的第5个元素。
V(1:10) 21 18 30 75 4626 4526 5867 87
2. 线性表:允许在任意位置进行插入、删除运算 栈:只允许在一端进行插入、删除运算的线性表, 具有先进后出、后进先出的特点 队列:只允许在队尾插入,在排头进行删除 运算的线性表,具有先进先出的特点
3.由线性表在顺序存储结构下的插入与删除运算效 率比较低,这种存储方式对于大线性表或元素经常 需要变动的线性表不太合适.
S(1:10)
1.什么是队列
2.2.3 队列栈及其应用
队列(Queue)是指允许在一端进行插入,而在 另一端进行删除的线性表。
出队
ABCDE F
入队
排头指针 front
队尾指针 rear
2.队列的应用
输入输出缓冲区的结构
计
缓
打
算
冲
印
机
区
机
数据结构(C语言版) 线性表 详细举例介绍
}
} // union
O(ListLength2(Lb))
算法2.1’’
试改变结构, 选用有序表表示集合。
有序表: 其数据元素依值从小 到大(非递减)有序排列的 线性表。
例如: (2,3,3,5,6,6,6,8,12)
void purge(List &La, List Lb) {
(求数据元素的后继)
初始条件: 线性表L已存在。
若cur_e是L的元素,但不是 操作结果:
最后一个,则用next_e返回它 的后继,否则操作失败, next_e无定义。
GetElem( L, i, &e ) (求线性表中某个数据元素)
线性表L已存在, 初始条件: 且 1≤i≤LengthList(L)
算法2.1’’
InitList(LA); La_len = ListLength(La); Lb_len =ListLength(Lb); // 求线性表的长度
for (i = 1; i <= Lb_len; i++) { GetElem(Lb, i, e);
// 取Lb中第i个数据元素赋给e
if (ListEmpty(La) || !equal (en, e)) { ListInsert(La, ++La_len, e); 算法2.1’ en = e;
} // La中不存在和 e 相同的数据元素,则插入之
}
}
O(ListLength(Lb))
例2-2 (教材P.20)
归并两个“其数据元素按值非递减有 序排列”的线性表 LA 和 LB,求得线性 表 LC 也具有同样特性。
【数据结构】线性表顺序表详解和代码实例
【数据结构】线性表顺序表详解和代码实例线性表(List)是零个或者多个数据元素的有限序列.⾸先它是⼀个序列.⾥⾯的元素是有顺序的,如果有多个元素,除开头和结尾以外的元素都有⼀个前驱和⼀个后继.⽽开头元素只有后继,结尾元素只有前驱.其次线性表是有限的,也就是⾥⾯的元素个数是有限的。
1ADT 线性表(List)2Data3线性表的数据对象集合为{a1, a2, a3, ......, an},每个元素类型为DataType。
4Operation5InitList(L); //初始化线性表6 IsEmptyList(L); //判断线性表是否为空7 ClearList(L); //清空线性表8 GetElemList(L, i, *e); //获取第i个位置的数据9 SearchList(L, e); //查找与数据e相等的元素10 InsertNodeList(L, i, e);//在第i个位置插⼊元素11 DeleteNodeList(L, i, *e);//删除第i个位置的元素,e获取删除元素12 GetLengthList(L); //获取线性表的长度13endADT关于线性表的基本操作就上⾯⼏种,还有⼏个例如线性表的排序,合并,逆序等等操作。
为了⽂章篇幅,就下次再介绍了。
线性表的顺序存储结构,就是指 ⽤⼀段地址连续的存储单元⼀次存储线性表的数据元素。
学过⾼级语⾔的朋友,相信对数组这玩意⼉都不会陌⽣吧。
数组就是⼀种顺序存储结构。
链式存储结构就是可以⽤⼀组任意的内存单元存储线性表中的元素。
与顺序存储不同的是,这组内存单元可以是连续的,也可以是不连续的。
这就意味着,元素可以存储在内存的任意位置。
正因为如此,在链式结构中,每个元素不仅要存它的信息,还需要存储它后继元素的存储地址。
我们把存储元素信息的域称为数据域,⽽把存储后继元素地址的域称为指针域。
由这两部分共同组成的数据元素ai,则可以称之为节点(Node)。
数据结构C语言描述(耿国华)第3章
0
M-1
top [0]
top [1]
图3.3 共享栈
第 3 章 限定性线性表——栈和队列
(1) 初始化操作。
void InitStack(DqStack *S)
{
S->top[0]=-1;
S->top[1]=M; }
第 3 章 限定性线性表——栈和队列 (2) 进栈操作算法。 int Push(DqStack *S, StackElementType x, int i)
(4) IsFull(S)
操作前提: 栈S已经存在。
操作结果: 判栈满函数,若S栈已满,则函数值为TRUE,
否则为FALSE。
第 3 章 限定性线性表——栈和队列 (5) Push(S,x) 操作前提:栈S已经存在。 操作结果:在S的顶部插入(亦称压入)元素x;若S栈未满,将x 插入栈顶位置,若栈已满,则返回FALSE,表示操作失败,否则 返回TRUE。 (6) Pop(S, x)
int IsEmpty(SeqStack *S)
{
/*判栈S为空栈时返回值为真, 反之为假*/
return(S->top==-1?TRUE:FALSE); }
第 3 章 限定性线性表——栈和队列
(3) 判栈满。 int IsFull(SeqStack *S) {
return(S->top == Stack-Size?TRUE:FALSE);
第 3 章 限定性线性表——栈和队列
2. 链栈
图3.4 链栈示意图
第 3 章 限定性线性表——栈和队列 链栈的结构可用C语言定义如下:
typedef struct node
{
StackElementType data;
数据结构---C语言描述-(耿国华)-课后习题答案
第一章习题答案2、××√3、(1)包含改变量定义的最小范围(2)数据抽象、信息隐蔽(3)数据对象、对象间的关系、一组处理数据的操作(4)指针类型(5)集合结构、线性结构、树形结构、图状结构(6)顺序存储、非顺序存储(7)一对一、一对多、多对多(8)一系列的操作(9)有限性、输入、可行性4、(1)A(2)C(3)C5、语句频度为1+(1+2)+(1+2+3)+…+(1+2+3+…+n)第二章习题答案1、(1)一半,插入、删除的位置(2)顺序和链式,显示,隐式(3)一定,不一定(4)头指针,头结点的指针域,其前驱的指针域2、(1)A(2)A:E、AB:H、L、I、E、AC:F、MD:L、J、A、G或J、A、G(3)D(4)D(5)C(6)A、C3、头指针:指向整个链表首地址的指针,标示着整个单链表的开始。
头结点:为了操作方便,可以在单链表的第一个结点之前附设一个结点,该结点的数据域可以存储一些关于线性表长度的附加信息,也可以什么都不存。
首元素结点:线性表中的第一个结点成为首元素结点。
4、算法如下:int Linser(SeqList *L,int X){ int i=0,k;if(L->last>=MAXSIZE-1){ printf(“表已满无法插入”);return(0);}while(i<=L->last&&L->elem[i]<X)i++;for(k=L->last;k>=I;k--)L->elem[k+1]=L->elem[k];L->elem[i]=X;L->last++;return(1);}5、算法如下:#define OK 1#define ERROR 0Int LDel(Seqlist *L,int i,int k){ int j;if(i<1||(i+k)>(L->last+2)){ printf(“输入的i,k值不合法”);return ERROR;}if((i+k)==(L->last+2)){ L->last=i-2;ruturn OK;}else{for(j=i+k-1;j<=L->last;j++)elem[j-k]=elem[j];L->last=L->last-k;return OK;}}6、算法如下:#define OK 1#define ERROR 0Int Delet(LInkList L,int mink,int maxk){ Node *p,*q;p=L;while(p->next!=NULL)p=p->next;if(mink<maxk||(L->next->data>=mink)||(p->data<=maxk)) { printf(“参数不合法”);return ERROR;}else{ p=L;while(p->next-data<=mink)p=p->next;while(q->data<maxk){ p->next=q->next;free(q);q=p->next;}return OK;}}9、算法如下:int Dele(Node *S){ Node *p;P=s->next;If(p= =s){printf(“只有一个结点,不删除”);return 0;}else{if((p->next= =s){s->next=s;free(p);return 1;}Else{ while(p->next->next!=s)P=p->next;P->next=s;Free(p);return 1;}}}第三章习题答案2、(1)3、栈有顺序栈和链栈两种存储结构。
基于C语言的线性表链式存储算法
③ 将新节点链接 到链表 的尾部 ; ④ 重复步骤②~ ,继续插入新节点直到结束 。 ③ 用 C语 言描述如下 :
# e i e NULL 0 df n
③ 将新 节点插入 到头结点 和第一个结点之 间;
④ 重复 步骤② ,继续插入新节点直到结束。 ③
用 C语 言描述 如下 :
i tx: n
s u t n d ce t0 t c o e ra r {
i tx; n
su tn d h p q /h指 向建立 的链表 ( t c o e书 , , ;* r 头结点) /
p (t c o e )ma o L N);/p指 向待插 入 的 = s ut n d r l c( E l *
线性表 的顺序存储 也 叫顺 序表 ,是用 内存 中一组地址 连 续的存储 单元依 次存储线性 表 中的数 据元 素 ,数 据元素 之间 的逻 辑关 系通 过 内存 中数 据元 素间 的物理 位置 关 系来体 现 ,
如 图 2所 示 。
n 一
曰] 佃
…一日 … 母
图 3
田
线 性链表 的优点是 :对存储 空 间没有连续 性要求 ,容 易
{
it dt; , 设数据元素 的类型为整型 / n a a 木
s u t o e n x; t c n d e t r
{
i dt; m aa
};
设数据元素 的类型为整型 ,
su t o e nx; t c n d e t r
}; s u t n d ce t0 t c o e ra r {
p > e tNu L; - nx= L ( 转到 3 下 2页 )
鸟
数据结构之线性表详细解答
二章线性表线性表是最简单、最基本、也是最常用的一种线性结构。
它有两种存储方法:顺序存储和链式存储,它的主要基本操作是插入、删除和检索等。
2.1 线性表的逻辑结构2.1.1 线性表的定义线性表是一种线性结构。
线性结构的特点是数据元素之间是一种线性关系,数据元素“一个接一个的排列”。
在一个线性表中数据元素的类型是相同的,或者说线性表是由同一类型的数据元素构成的线性结构。
在实际问题中线性表的例子是很多的,如学生情况信息表是一个线性表:表中数据元素的类型为学生类型; 一个字符串也是一个线性表:表中数据元素的类型为字符型,等等。
综上所述,线性表定义如下:线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列,通常记为:(a1,a2,… a i-1,a i,a i+1,…a n)其中n为表长,n=0 时称为空表。
表中相邻元素之间存在着顺序关系。
将a i-1 称为a i 的直接前趋,a i+1 称为a i 的直接后继。
就是说:对于a i,当i=2,...,n 时,有且仅有一个直接前趋a i-1.,当i=1,2,...,n-1 时,有且仅有一个直接后继a i+1,而a1 是表中第一个元素,它没有前趋,a n 是最后一个元素无后继。
需要说明的是:a i为序号为i 的数据元素(i=1,2,…,n),通常我们将它的数据类型抽象为datatype,datatype根据具体问题而定,如在学生情况信息表中,它是用户自定义的学生类型; 在字符串中,它是字符型; 等等。
2.1.2 线性表的基本操作在第一章中提到,数据结构的运算是定义在逻辑结构层次上的,而运算的具体实现是建立在存储结构上的,因此下面定义的线性表的基本运算作为逻辑结构的一部分,每一个操作的具体实现只有在确定了线性表的存储结构之后才能完成。
线性表上的基本操作有:⑴线性表初始化:Init_List(L)初始条件:表L不存在操作结果:构造一个空的线性表⑵求线性表的长度:Length_List(L)初始条件:表L存在操作结果:返回线性表中的所含元素的个数⑶取表元:Get_List(L,i)初始条件:表L存在且1<=i<=Length_List(L)操作结果:返回线性表L中的第i个元素的值或地址⑷按值查找:Locate_List(L,x),x是给定的一个数据元素。
数据结构与算法分析c语言描述中文答案
数据结构与算法分析c语言描述中文答案【篇一:数据结构(c语言版)课后习题答案完整版】选择题:ccbdca6.试分析下面各程序段的时间复杂度。
(1)o(1)(2)o(m*n)(3)o(n2)(4)o(log3n)(5)因为x++共执行了n-1+n-2+??+1= n(n-1)/2,所以执行时间为o(n2)(6)o(n)第2章线性表1.选择题babadbcabdcddac 2.算法设计题(6)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。
elemtype max (linklist l ){if(l-next==null) return null;pmax=l-next; //假定第一个结点中数据具有最大值 p=l-next-next; while(p != null ){//如果下一个结点存在if(p-data pmax-data) pmax=p;p=p-next; }return pmax-data;(7)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。
void inverse(linklist l) { // 逆置带头结点的单链表 l p=l-next; l-next=null; while ( p) {q=p-next; // q指向*p的后继p-next=l-next;l-next=p; // *p插入在头结点之后p = q; }}(10)已知长度为n的线性表a采用顺序存储结构,请写一时间复杂度为o(n)、空间复杂度为o(1)的算法,该算法删除线性表中所有值为item的数据元素。
[题目分析] 在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。
本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。
因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。
数据结构实验 C语言版 线性表__C版
2. 求表长
L.length
3. 取第i个元素
L.elem[i-1]
(0<i<L.length+1)
18
4. 元素定位操作
分析:依次取出每个元素和给定值进行比较 int LocateElem_Sq (SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
6. 删除操作
线性表的删除运算是指将表的第i(1≦i≦n)个元 素删除,使长度为n的线性表: (a1,…a i-1,ai,a i+1…,an) 变成长度为n-1的线性表 (a1,…a i-1,a i+1,…,an)
操作步骤: ① 判断线性表是否为空 ② 判断i值是否合法:1≦i≦n ③ 元素前移 ④ 表长减1
2
线性结构:数据元素之间存在1对1的关系。 四个特征: ① 存在惟一的一个“第一元素” ② 存在惟一的一个“最后元素” ③ 除最后元素外,其它元素均有惟一的“后继” ④ 除第一元素外,其它元素均有惟一的“前驱”
3
2.1 线性表的类型定义
一.定义
线性表(Linear List) :由n(n≧0)个数据元素组成的 有限序列。记作: (a1,a2,…an) 其中数据元素的个数n定义为表的长度。当n=0时称 为空表 这里的数据元素ai(1≦i≦n)只是一个抽象的符号, 其具体含义在不同的情况下可以不同。 例1、26个英文字母组成的字母表 (A,B,C、…、Z) 例2、某校从1978年到1983年各种型号的计算机拥 有量的变化情况。 4 (6,17,28,50,92,188)
思考:若要直接查相等的呢?
19
5. 插入操作
线性表的插入运算是指在表的第i(1≦i≦n+1)个位置上,插 入一个新元素e,使长度为n的线性表(a1,…a i-1,ai,…,an) 变成长度为n+1的线性表 (a1,…a i-1,e,ai,…,an) 操作步骤: ① 判断i是否符合要求:1≦i≦n+1 ② 判断表长是否溢出 ③ 元素右移 ④ 插入 ⑤ 表长增1
数据结构教程(C语言描述)
数据结构教程
简单赋值: 变量名=表达式;
串联赋值: 变量名1=变量名2=...=变量名k=表达式;
交换赋值: 变量名<-->变量名; 条件赋值: 变量名=条件表达式?表达式?表达式T:表达式F
1、if(表达式) 语句;
4、赋值语句
2、if(表达式) 语句; else 语句;
3、switch(表达式){
for(赋初值表达式;条件;修改表达式序列)语句; 6、循环语句 while(条件)语句;
do{ 语句序列}while(条件);
return [/函数结束语句 break; //case结束语句
exit(异常代码); //异常结束语句
8、输入和输 scanf([格式串],变量1,...,变量n); 出语句
file:///C|/Documents%20and%20Settings/Krison%20Liang/Desktop/datasf29.htm(第 7/115 页)2010-4-26 14:38:21
成组赋值:
(变量名1,...,变量名k)=(表达式1,...,表达式k); 结构名=结构名; 结构名=(值1,...,值k); 变量名[]=表达式; 变量名[起始下标..终止下标]=变量名[起始下标..终止下 标];
任意数据元素的集合
除第一个和最后一个
数据关系 R1={<ai-1,ai>| ai-1,ai(- D,i=2,...,n}
外,每个元素有唯一的 直接前趋和唯一的直接
后继
ListInsert(&L,i,e) 基本操作 ListDelete(&L,i,e)
...
L为线性表,i为位置,e 为数据元素。
二、类C语言语法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*用单链表表示集合,设计一个算法求两个集合的交。*/ void interset(linklist *A,linklist *B,linklist *&C) { linklist *pa=A->next,*pb,*s,*r; C=(linklist*)malloc(sizeof(linklist)); r=C; while(pa!=NULL) { pb=B->next; while(pb!=NULL&&pb->data!=pa->data) pb=pb->next; if(pb!=NULL) { s=(linklist*)malloc(sizeof(linklist)); s->data=pa->data; r->next=s; r=s;
{ temp=R[k]; R[k]=R[j]; R[j]=temp; k++;j--; } } void leftshift(int R[],int n,int p) { if(p>0&&p<n) { reverse(R,0,n-1); reverse(R,0,n-1-p); reverse(R,n-p,n-1); } } /*一个长度为 L 的升序序列 S,处在第(L+1)/2 个位置的数称为 S 的中位数。两个序列的中 位数是含它们所有元素的升序序列的中位数。现有两个等长的升序序列 A 和 B,试设计一个 在时间和空间两方面都尽可能高效的算法,找出两个序列 A 和 B 的中位数。*/ int m_search(int A[],int B[],int n) { int start1,end1,mid1,start2,end2,mid2; start1=0;end1=n-1; start2=0;end2=n-1; while(start1!=end1 || start2!=end2) { mid1=(start1+end1)/2; mid2=(start2+end2)/2; if(A[mid1]==B[mid2]) return A[mid1]; if(A[mid1]<B[mid2]) { if((start1+end1)%2==0) //奇数个 { start1=mid1; end2=mid2; } else { start1=mid1+1; end2=mid2; } } else
/*将两个有序表合并成一个有序表称为有序表合并,也称为归并。假设有序表采用顺序表存 放,并且元素是递增有序的,合并 A、B 两个有序表产生有序表 C 的算法如下:*/
void merge (sqlist A,sqlist B,sqlist &C) { int i=0,j=0,k=0; while (i<A.length && j<B.length) { if(A.data[i]<B.data[j]) { C.data[k]=A.data[i]; k++;i++; } else { C.data[k]=B.data[j]; k++;j++; } } while (i<A.length) { C.data[k]=A.data[i]; k++;i++; } while (j<B.length) { C.data[k]=B.data[j]; k++;j++; } C.length=k; }
/*假设带头节点的单链表给出头指针 list。在不改变链表的前提下,请设计一个尽可能高效 的算法,查找链表中倒数第 k 个位置上的节点。若查找成功,算法输出该节点的 data 域的 值,并返回 1;否则,只返回 0。*/ 方法一: typedef struct LNode { int data; struct LNode *link; } *LinkList; int Searchk(LinkList list,int k) { LinkList p,q; int count=0; p=q=list->link; while(p!=NULL) { if (count<k)
} pa=pa->next; } r->next=NULL; }
/*设计一个算法,在带头节点的单链表 L 中删除一个最小值,假设这样的节点是唯一的。*/ void delminnode(linklist *&L) { linklist *pre=L,*p=pre->next,*minp=p,*minpre=pre; while(p!=NULL) { if(p->data<minp->data) { minp=p; minpre=pre; } pre=p; p=p->next; } minpre->next=minp->next; free(minp); }
/*设计一个算法,在带头节点的单链表 L 中删除所有值为 x 的节点并释放其空间,假设这样 的节点不是唯一的。*/ 解法一: void delxnode(linklist *&L,ElemType x) { linklist *p=L->next,*pre=L,*q; while(p!=NULL) { if(p->data==x) { q=p;p=p->next;pre->next=p;free(q); } else {
/*设计一个算法用于判断带头结点的循环双链表 L 是否对称。*/ int symetry(DLinkList *L) { DLinkList *p=L->next,*q=L-prior; while(p!=q && p->next!=q) if(p-data==q->data) { p=p->next; q=q->prior;
} ra->next=rb->next=NULL; }
/*设 C={a1,b1,a2,b2,...,an,bn}为一线性表,采用带头节点的 hc 单链表存放,设计一个就地算 法,将其拆分成两个线性表,使得:A={a1,a2,...,an},B={bn,bn-1,...,b1}.*/ void split(linklist *hc,linklist *&ha,linklist *&hb) { linklist *p=hc->next,*ra,*q; ha=hc; ra=ha; hb=(linklist*)malloc(sizeof(linklist)); hb->next=NULL; while(p!=NULL) { ra->next=p; ra=p; p=p->next; q=p->next; p->next=hb->next; hb->next=p; p=q; } ra->next=NULL; }
count++; else q=q->link; p=p->link; } if (count<k) return(0); else { printf("%d",q->data); return(1); } } 方法二: int Searchk(LinkList list,int k) { LinkList p,q; int count=0; p=q=list->link; while(p!=NULL && count<k) { count++; p=p->link; } if (p==NULL) return(0); else { while (p!=NULL) { q=q->link; p=p->link; } printf("%d",q->data); return(1); } }
/*已知长度为 n 的线性表 L 采用顺序表存储结构,编写一个时间复杂度为 O(n)、空间复杂度 为 O(1)的算法,该算法将删除线性表中所有值为 x 的数据元素。*/
解法一: void delnode1(sqlist &L,ElemType x) { int k=0,i; for(i=0;i<L.length;i++) if(L.data[i]!=x) { L.data[k]=L.data[i]; k++; } L.length=k; } 解法二: void delnode2(sqlist &L,ElemType x) { int k=0,i=0; while(i<L.length) { if(L.data[i]==x) k++; else L.data[i-k]=L.data[i]; i++; } L.length-=k; }
/*设 C={a1,b1,a2,b2,...,an,bn}采用带头节点的 hc 单链表存放,设计一个就地算法,将其拆分 成两个线性表,使得:A={a1,a2,...,an},B={b1,b2,...,bn}。*/ void split(linklist *hc,linklist *&ha,linklist *&hb) { linklist *p=hc->next,*ra,*rb; ha=hc; ra=ha; hb=(linklist*)malloc(sizeof(linklist)); rb=hb; while(p!=NULL) { ra->nest=p; ra=p; p=p->nest; rb->nest=p; rb=p; p=p->nest;
{ if((start1+end1)%2==0) //奇数个 { start2=mid2; end1=mid1; } else { start2=mid2+1; end1=mid1; } } } return A[start1]<B[start2]?A[start1]:B[start2]; }