数据结构C语言版 线性表的动态分配顺序存储结构表示和实现文库

合集下载

C语言中都有哪些常见的数据结构你都知道几个?

C语言中都有哪些常见的数据结构你都知道几个?

C语⾔中都有哪些常见的数据结构你都知道⼏个?上次在⾯试时被⾯试官问到学了哪些数据结构,那时简单答了栈、队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了⼀下⼏种常见的数据结构,原来我们学过的数据结构有这么多~⾸先,先来回顾下C语⾔中常见的基本数据类型吧O(∩_∩)OC语⾔的基本数据类型有:整型int,浮点型float,字符型char等等添加描述那么,究竟什么是数据结构呢?数据结构是计算机存储、组织数据的⽅式。

数据结构是指相互之间存在⼀种或多种特定关系的数据元素的集合⼤部分数据结构的实现都需要借助C语⾔中的指针和结构体类型下⾯,进⼊今天的重点啦O(∩_∩)O⼏种常见的数据结构(1)线性数据结构:元素之间⼀般存在元素之间存在⼀对⼀关系,是最常⽤的⼀类数据结构,典型的有:数组、栈、队列和线性表(2)树形结构:结点间具有层次关系,每⼀层的⼀个结点能且只能和上⼀层的⼀个结点相关,但同时可以和下⼀层的多个结点相关,称为“⼀对多”关系,常见类型有:树、堆(3)图形结构:在图形结构中,允许多个结点之间相关,称为“多对多”关系下⾯分别对这⼏种数据结构做⼀个简单介绍:1、线性数据结构:典型的有:数组、栈、队列和线性表(1)数组和链表a、数组:存放着⼀组相同类型的数据,需要预先指定数组的长度,有⼀维数组、⼆维数组、多维数组等b、链表:链表是C语⾔中⼀种应⽤⼴泛的结构,它采⽤动态分配内存的形式实现,⽤⼀组任意的存储单元存放数据元素链表的,⼀般为每个元素增设指针域,⽤来指向后继元素c、数组和链表的区别:从逻辑结构来看:数组必须事先定义固定的长度,不能适应数据动态地增减的情况;链表动态地进⾏存储分配,可以适应数据动态地增减的情况,且可以⽅便地插⼊、删除数据项(数组中插⼊、删除数据项时,需要移动其它数据项)从内存存储来看:(静态)数组从栈中分配空间(⽤NEW创建的在堆中), 对于程序员⽅便快速,但是⾃由度⼩;链表从堆中分配空间, ⾃由度⼤但是申请管理⽐较⿇烦从访问⽅式来看:数组在内存中是连续存储的,因此,可以利⽤下标索引进⾏随机访问;链表是链式存储结构,在访问元素的时候只能通过线性的⽅式由前到后顺序访问,所以访问效率⽐数组要低(2)栈、队列和线性表:可采⽤顺序存储和链式存储的⽅法进⾏存储顺序存储:借助数据元素在存储空间中的相对位置来表⽰元素之间的逻辑关系链式存储:借助表⽰数据元素存储地址的指针表⽰元素之间的逻辑关系a、栈:只允许在序列末端进⾏操作,栈的操作只能在栈顶进⾏,⼀般栈⼜被称为后进先出或先进后出的线性结构顺序栈:采⽤顺序存储结构的栈称为顺序栈,即需要⽤⼀⽚地址连续的空间来存储栈的元素,顺序栈的类型定义如下:添加描述链栈:采⽤链式存储结构的栈称为链栈:添加描述b、队列:只允许在序列两端进⾏操作,⼀般队列也被称为先进先出的线性结构循环队列:采⽤顺序存储结构的队列,需要按队列可能的最⼤长度分配存储空空,其类型定义如下:添加描述 链队列:采⽤链式存储结构的队列称为链队列,⼀般需要设置头尾指针只是链表的头尾结点:添加描述c、线性表:允许在序列任意位置进⾏操作,线性表的操作位置不受限制,线性表的操作⼗分灵活,常⽤操作包括在任意位置插⼊和删除,以及查询和修改任意位置的元素顺序表:采⽤顺序存储结构表⽰的线性表称为顺序表,⽤⼀组地址连续的存储单元⼀次存放线性表的数据元素,即以存储位置相邻表⽰位序相继的两个元素之间的前驱和后继关系,为了避免移动元素,⼀般在顺序表的接⼝定义中只考虑在表尾插⼊和删除元素,如此实现的顺序表也可称为栈表:添加描述线性表:⼀般包括单链表、双向链表、循环链表和双向循环链表单链表:添加描述 双向链表:添加描述线性表两种存储结构的⽐较:顺序表: 优点:在顺序表中,逻辑中相邻的两个元素在物理位置上也相邻,查找⽐较⽅便,存取任⼀元素的时间复杂度都为O(1) 缺点:不适合在任意位置插⼊、删除元素,因为需要移动元素,平均时间复杂度为O(n)链表: 优点:在链接的任意位置插⼊或删除元素只需修改相应指针,不需要移动元素;按需动态分配,不需要按最⼤需求预先分配⼀块连续空空 缺点:查找不⽅便,查找某⼀元素需要从头指针出发沿指针域查找,因此平均时间复杂度为O(n)2、树形结构:结点间具有层次关系,每⼀层的⼀个结点能且只能和上⼀层的⼀个结点相关,但同时可以和下⼀层的多个结点相关,称为“⼀对多”关系,常见类型有:树、堆(1)⼆叉树:⼆叉树是⼀种递归数据结构,是含有n(n>=0)个结点的有限集合,⼆叉树具有以下特点:⼆叉树可以是空树;⼆叉树的每个结点都恰好有两棵⼦树,其中⼀个或两个可能为空;⼆叉树中每个结点的左、右⼦树的位置不能颠倒,若改变两者的位置,就成为另⼀棵⼆叉树(2)完全⼆叉树:从根起,⾃上⽽下,⾃左⽽右,给满⼆叉树的每个结点从1到n连续编号,如果每个结点都与深度为k的满⼆叉树中编号从1⾄n的结点⼀⼀对应,则称为完全⼆叉树a、采⽤顺序存储结构:⽤⼀维数组存储完全⼆叉树,结点的编号对于与结点的下标(如根为1,则根的左孩⼦为2*i=2*1=2,右孩⼦为2*i+1=2*1+1=2)添加描述b、采⽤链式存储结构:⼆叉链表:添加描述三叉链表:它的结点⽐⼆叉链表多⼀个指针域parent,⽤于执⾏结点的双亲,便于查找双亲结点添加描述两种存储结构⽐较:对于完全⼆叉树,采⽤顺序存储结构既能节省空间,⼜可利⽤数组元素的下标值确定结点在⼆叉树中的位置及结点之间的关系,但采⽤顺序存储结构存储⼀般⼆叉树容易造成空间浪费,链式结构可以克服这个缺点(3)⼆叉查找树:⼆叉查找树⼜称⼆叉排序树,或者是⼀课空⼆叉树,或者是具有如下特征的⼆叉树:a、若它的左⼦树不空,则左⼦树上所有结点的值均⼩于根结点的值b、若它的右⼦树不空,则右⼦树上所有结点的值均⼤于根结点的值c、它的左、右⼦树也分别是⼆叉查找树(4)平衡⼆叉树:平衡⼆叉查找树简称平衡⼆叉树,平衡⼆叉树或者是棵空树,或者是具有下列性质的⼆叉查找树:它的左⼦树和右⼦树都是平衡⼆叉树,且左⼦树和右⼦树的⾼度之差的绝对值不超过1添加描述平衡⼆叉树的失衡及调整主要可归纳为下列四种情况:LL型、RR型、LR型、RL型(5)树:树是含有n(n>=0)个结点的有限集合,在任意⼀棵⾮空树种: a、有且仅有⼀个特定的称为根的结点b、当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每⼀个集合本⾝⼜是⼀棵树,并且T1,T2,...,Tm称为根的⼦树(6)堆:堆是具有以下特性的完全⼆叉树,其所有⾮叶⼦结点均不⼤于(或不⼩于)其左右孩⼦结点。

数据结构(C语言版)

数据结构(C语言版)

比较
Prim算法适用于稠密图, Kruskal算法适用于稀疏图;
两者时间复杂度相近,但 Kruskal算法需额外处理并查
集数据结构。
最短路径算法设计思想及实现方法比较
1 2
Dijkstra算法
从源点出发,每次找到距离源点最近的顶点并更 新距离值,直至所有顶点距离确定。适用于不含 负权边的图。
Floyd算法
特殊二叉树
满二叉树、完全二叉树等。
二叉树的遍历与线索化
二叉树的遍历
前序遍历、中序遍历、后序遍历和层 次遍历是二叉树的四种基本遍历方法 。
线索化二叉树
为了方便查找二叉树节点的前驱和后 继,可以对二叉树进行线索化处理, 即在节点的空指针域中存放指向前驱 或后继的指针。
树和森林的遍历与转换
树的遍历
01
串的顺序存储结构
01
02
03
串的顺序存储结构是用 一组地址连续的存储单 元来存储串中的字符序
列的。
按照预定义的大小,为 每个定义的串变量分配 一个固定长度的存储区 ,一般是用定长数组来
定义。
串值的存储:将实际串 长度值保存在数组的0下 标位置,串的字符序列 依次存放在从1开始的数
组元素中。
串的链式存储结构
03
比较
DFS空间复杂度较低,适用于递 归实现;BFS可找到最短路径, 适用于非递归实现。
最小生成树算法设计思想及实现方法比较
Prim算法
从某一顶点开始,每次选择当 前生成树与外界最近的边加入 生成树中,直至所有顶点加入

Kruskal算法
按边权值从小到大排序,依次 选择边加入生成树中,保证不
形成环路。
数据结构(C语言版)

数据结构(C语言)

数据结构(C语言)
2、transpose算法:考虑到b.data中的行就是a.data中的列,要想得到b.data中行号为0的三元组元素,可对a.data扫描一遍,找出a.data中列号为0的元素,为后再找列号为其它的元素。
广义表
由一个大的表像数组中一样存储元素,但内部的元素可以使结构不一样的,或者是所谓的子广义表。(树和有向图也可以用广义表来表示)

树的存储结构:
1、双亲表示法(用一组连续的存储空间(一维数组)存储树中的各个结点,数组中的一个元素表示树中的一个结点,数组元素为结构体类型,其中包括结点本身的信息以及结点的双亲结点在数组中的序号,但是这样并不能反映出孩子结点之间的兄弟关系来,所以,得利用一些手法来区别兄弟,可在结点结构中增设存放第一个孩子的域和存放第一个右兄弟的域,就能较方便地实现上述操作了,在实际存储的时候,第一列是序号,第二列是数据的具体内容,第三列则是通过固定的数字关系来反映这是第几代父母,第一代也就是根结点,其为-1,一下慢慢变大。这种存储方法比较适应存储数据和查找父结点。)
队列也是一种特殊的线性表。它所有的插入操作均限定在表的一端进行,而所有的删除操作则限定在表的另一端进行。允许删除元素的一端称为队头,允许插入元素的一端称为队尾,删除元素称为出队,插入元素称为进队。(假如是一个循环队列是会出现队满和队空的情况)
队列的顺序存储结构:利用连续的存储单元存储队列。
队列的链式存储结构:利用地址对队列中的数据进行连接,但存储的数据不一定连续。
数据组织(数据、数据元素、数据项)的三个层次:数据可由若干个数据元素构成,而数据元素又可以由一个或若干个数据项组成。
四种基本的数据结构:集合、线性结构、树形结构、图状结构。
顺序存储的特点是在内存中开辟一组连续的空间来存放数据,数据元素之间的逻辑关系通过元素在内存中存放的相对位置来确定。

数据结构 (C语言版) (第二版)(目录)

数据结构 (C语言版) (第二版)(目录)

数据结构(C语言版)(第二版)(目录)第1章导论
1 算法和数据结构
2 什么是数据结构
3 符号,引理,定理与证明
4 说明文篇
5 C语言和程序设计
6 总结
第2章算法分析
1 算法的衡量标准
2 时间和空间复杂度分析
3 运行时复杂度分析
4 递归分析
第3章线性表
1 一维数组
2 线性表
3 顺序表
4 链表
5 循环链表
6 树表
7 双向链表
第4章栈
1 栈的定义
2 栈的抽象数据类型
3 栈的基本操作
4 栈的应用——后缀表达式的求算
第7章树
1 树的定义
2 树的抽象数据类型
3 树的存储
4 树的遍历
5 二叉树
6 二叉排序树(搜索树)
7 平衡二叉树
8 哈夫曼树
9 图的存储
第8章查找
1 静态查找
2 哈希表
3 动态单值查找
第10章数据结构综合应用
1 树的遍历
2 贪心法
3 回溯法
4 分析与评价
附录 A C语言库
1 算法入口及时区函数
2 内存处理函数
3 字符串处理函数
4 文件处理函数
附录 B 内存分配方式。

线性表的存储方式及其操作(C语言版)

线性表的存储方式及其操作(C语言版)

线性表的存储⽅式及其操作(C语⾔版)该篇也是复习数据结构总结的,虽然很简单但⽅便以后使⽤。

线性表的顺序存储1.定义⼀个结构体,因为在⾼级语⾔中数组具有随机存储的特性,所以通常⽤数组来表⽰顺序存储。

typedef struct LNode *List;struct LNode{ElementType Data[maxsize];int last; //线性表的长度为 last+1};struct LNode L; //定义了⼀个结构体List PtrL; //定义了⼀个结构体指针访问下标 i的元素为 L.Data[i] 或者为 Ptr-> Data[i]2.初始化操作List MakeEmpty(){List PtrL;PtrL = (List)malloc(sizeof(struct LNode));PtrL->last = -1;return PtrL;}3.查找操作int Find(ElementType X,List PtrL){int i = 0;while(i<=PtrL->last && PtrL ->Data[i] != X)i++;if(i>PtrL->last) return -1;else return i;}4.插⼊操作时间复杂度为 O(N)void Insert(ElementType X,int i,List PtrL){int j;if(PtrL->last == maxsize-1){printf("表满");return;}if(i<1 || i>PtrL->last+2) /*因为插⼊的是第 i个位置的元素 (1<=i<=1+n)*/{printf("位置不合法");return;}for(j=PtrL->last;j>=i-1;j--)PtrL->Data[j+1]=PtrL->Data[j]; /* 将 ai ~an 倒序向后移动*/PtrL->Data[i-1] = X;PtrL->last++;return;}5.删除操作第i个元素 1<=i<=nvoid Delete(int i,List PtrL){int j;if(i<1 || i>PtrL->last){printf("不存在第%d个元素",i);return;}for(j=i;j<=PtrL->last;j++)PtrL->Data[j-1] = PtrL->Data[j];PtrL->last--;return;}线性表的链式存储结构1.结构体typedef struct LNode *List;struct LNode{ElementType Data;List Next; //线性表的长度为 last+1};struct LNode L; //定义了⼀个结构体List PtrL; //定义了⼀个结构体指针访问下标 i的元素为 L.Data[i] 或者为 Ptr-> Data[i]2.因为链表不像顺序表那样数组直接有表长,所以我们加上⼀个求表长的操作。

线性表的动态分配顺序存储结构

线性表的动态分配顺序存储结构

util.h//通用头文件:存放公共函数或变量#include "stdio.h"#include "stdlib.h"//函数结果状态代码#define TRUE 1#define FALSE 0#define OK 2#define ERROR -1#define INFEASIBLE -2 //不可行#define OVERFLOW -3//声明函数返回值的数据类型typedef int Status;//声明线性表中元素的数据类型typedef int ElemType;//声明相关辅助函数Status Compare(ElemType,ElemType);void Vist(ElemType);//声明函数指针typedef Status (*pCompare)(ElemType,ElemType);typedef void (*pVisit)(ElemType);u.til.cpp//通用函数的定义#include "util.h"Status Compare(ElemType e1,ElemType e2){//操作结果:比较e1和e2是否相等。

若相等,则返回TRUE;否则返回FALSE if(e1==e2)return TRUE;elsereturn FALSE;}//Comparevoid Visit(ElemType e){//操作结果:在屏幕上输出eprintf("%d ",e);}//VisitSqList.h//顺序表头文件#include "util.h"//线性表的动态分配顺序存储结构#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define LISTINCREMENT 10 //线性表存储空间的分配增量typedef struct{ElemType *elem; //存储空间基址int length; //当前长度int listsize; //当前分配的存储容量}SqList;//顺序表的基本操作Status InitList_Sq(SqList&);Status DestroyList_Sq(SqList&);//声明顺序表的引用型操作Status ListEmpty_Sq(SqList);int ListLength_Sq(SqList);ElemType PriorElem_Sq(SqList,ElemType,ElemType&); ElemType NextElem_Sq(SqList,ElemType,ElemType&); ElemType GetElem_Sq(SqList,int,ElemType&);int LocateElem_Sq(SqList,ElemType,pCompare);void ListTraverse_Sq(SqList,pVisit);//声明顺序加工型操作Status ClearList_Sq(SqList&);Status PutElem(SqList&,int,ElemType);Status ListInsert_Sq(SqList&,int,ElemType);Status ListDelete_Sq(SqList&,int,ElemType&);void Union(SqList&,SqList);void Purge(SqList&,SqList);void MergeList_Sq(SqList,SqList,SqList&);SqList.cpp//顺序表的操作#include "SqList.h"//顺序表的基本操作Status InitList_Sq(SqList &L){ //操作结果:构造一个空线性表LL.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));//申请分配存储空间if(!L.elem) exit(OVERFLOW); //存储分配失败L.length=0; //顺序表长度初始化为0L.listsize=LISTINCREMENT; //当前存储容量大小为INCREMENT return OK;}//InitList_SqStatus DestroyList_Sq(SqList &L){//初始条件:顺序表L存在//操作结果:销毁顺序表Lif(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败free(L.elem); //释放存储空间L.length=0;L.listsize=0;L.elem=NULL;return OK;}//DestroyList_Sq//顺序表的引用型操作Status ListEmpty_Sq(SqList L){//初始条件:顺序表L存在//操作结果:查看顺序表L是否为空表,是则返回TRUE;反之返回FALSEif(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(L.length==0)return TRUE;elsereturn FALSE;}//ListEmpty_Sqint ListLength_Sq(SqList L){//初始条件:顺序表L存在//操作结果:返回顺序表长度if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败return L.length;}//ListLength_SqElemType PriorElem_Sq(SqList L,ElemType cur_e,ElemType &pre_e){//初始条件:顺序表L存在//操作结果:若cur_e在顺序表中,且不是第一个元素,则用pre_e返回其前驱// 否则操作不可行int pos=2; //cur_e当前位置pos≥2if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败ElemType *p=L.elem+1; //从顺序表第2个位置查找cur_ewhile(pos++<=L.length&&(*p++)!=cur_e); //pos范围2≤pos≤L.Lengthif(pos>L.length) return INFEASIBLE; //到表结束未找到cur_e,操作不可行else{pre_e=(*--p); //pre_e为当前值cur_e的前驱return pre_e; //返回前驱pre_e}}//PriorElem_SqElemType NextElem_Sq(SqList L,ElemType cur_e,ElemType &next_e){//初始条件:顺序表L存在//操作结果:若cur_e在顺序表中,且不是最后一个元素,则用next_e返回其后继// 否则操作不可行int pos=1; //cur_e当前位置pos≥2if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败ElemType *p=L.elem; //从顺序表第1个位置查找cur_ewhile(pos++<L.length&&(*p++)!=cur_e); //pos范围1≤pos<L.Lengthif(pos==L.length) return INFEASIBLE; //到表尾未找到cur_e,操作不可行else{next_e=(*++p); //pre_e为当前值cur_e的前驱return next_e; //返回前驱pre_e}}//NextElem_SqElemType GetElem_Sq(SqList L,int pos,ElemType &e){//初始条件:顺序表L存在,且1≤pos≤L.Length//操作结果:用e返回pos位置的值if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(pos<1||pos>L.length) return ERROR; //pos取值范围1≤pos≤L.Lengthelse{e=*(L.elem+pos-1);return e; //用e返回pos位置的值}}//GetElemint LocateElem_Sq(SqList L,ElemType e,pCompare equal){//初始条件:顺序表L存在//操作结果:若元素e在顺序表中存在,则返回其在顺序表中第一次出现的位置// 否则,操作不可行int pos=1; //pos≥1if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败ElemType *p=L.elem; //从顺序表第1个位置查找cur_e while(pos++<=L.length&&!equal(*p++,e));//遍历顺序表查找第一个cur_eif(pos>L.length)return 0; //到表结束时未找到元素e elsereturn pos; //返回顺序表中出现e的第一个位置}//LocateElem_Sqvoid ListTraverse_Sq(SqList L,pVisit visit){//初始条件:顺序表L存在//操作结果:遍历顺序表,在屏幕上显示顺序表元素int pos;if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败for(pos=1;pos<=L.length;pos++) visit(L.elem[pos-1]);printf("\n");}//ListTraverse_Sq//加工型操作Status ClearList_Sq(SqList &L){//初始条件:线性表L已存在//操作结果:将L重置为空表L.length=0; //空表长度为0return OK;}//ClearList_SqStatus PutElem_Sq(SqList &L,int pos,ElemType e){//初始条件:顺序表L存在,且pos范围为1≤pos≤L.length//操作结果:顺序表第pos个位置赋值为eif(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败L.elem[pos-1]=e;return OK;}//PutElem_SqStatus ListInsert_Sq(SqList &L,int pos,ElemType e){//初始条件:顺序表L存在,且pos范围为1≤pos≤L.length+1//操作结果:将e插入到顺序表第pos个位置,顺序表长度加1ElemType *newbase;ElemType *p,*q;if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(pos<1||pos>L.length+1) return INFEASIBLE; //pos值不合法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; //表长加1}q=&L.elem[pos-1]; //q指向需要右移的元素位置for(p=&L.elem[L.length-1];p>=q;p--) *(p+1)=*p;//右移元素*q=e;L.length++;return OK;}//ListInsert_SqStatus ListDelete_Sq(SqList &L,int pos,ElemType &e){//初始条件:顺序表L存在,且pos范围为1≤pos≤L.length//操作结果:将顺序表中第pos个位置的元素e删除,并用e返回ElemType *p,*q;if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(pos<1||pos>L.length) return INFEASIBLE; //pos值不合法q=L.elem+pos-1; //p指向被删除元素的位置) e=*q; //被删除元素赋值给efor(p=&L.elem[L.length-1];p>=++q;p--) *(p-1)=*p;//左移元素L.length--;return e;}//ListDelete_Sqvoid Union(SqList &La,SqList Lb) //A∪B{int i;int La_Len,Lb_Len;ElemType e;pCompare equal;La_Len=ListLength_Sq(La); //即La_Len=La.lengthLb_Len=ListLength_Sq(Lb); //即Lb_Len=Lb.lengthfor(i=1;i<=Lb_Len;i++){GetElem_Sq(Lb,i,e); //e=Lb.elem[i-1]if(!LocateElem_Sq(La,e,equal))ListInsert_Sq(La,++La_Len,e); //插入La之后}}//unionvoid Purge(SqList &La,SqList Lb) //提取A集合(纯化){int i;int La_Len,Lb_Len;ElemType e,en;pCompare equal; //Compare函数指针InitList_Sq(La); //构造一个空顺序表La_Len=ListLength_Sq(La); //取La当前长度Lb_Len=ListLength_Sq(Lb); //取Lb当前长度for(i=1;i<=Lb_Len;i++){ //遍历顺序表LbGetElem_Sq(Lb,i,e); //e=Lb.elem[i-1];if(!equal(en,e)) ListInsert_Sq(La,++La_Len,e);en=e; //en=Lb.elem[i-1] }}//Purgevoid MergeList_Sq(SqList La,SqList Lb,SqList &Lc)//合并升序序列{InitList_Sq(Lc); //构造一个空顺序表Lcint i=1; //i指示La位置int j=1; //j指示Lb位置int La_Len,Lb_Len,Lc_Len;ElemType ai,bj; //暂存La、Lb中的元素//取La、Lb、Lc当前长度La_Len=ListLength_Sq(La);Lb_Len=ListLength_Sq(Lb);Lc_Len=ListLength_Sq(Lc);//将短顺序表取出与长顺序表进行排序,并插入Lc中while(i<=La_Len&&j<=Lb_Len){GetElem_Sq(La,i,ai); //ai=La.elem[i-1];GetElem_Sq(Lb,j,bj); //bj=Lb.elem[j-1];//将小的值插入Lcif(ai<=bj){ListInsert_Sq(Lc,++Lc_Len,ai);i++;}else{ListInsert_Sq(Lc,++Lc_Len,bj);j++;}}while(i<=La_Len){ //如果La尚有元素未插入Lc,则全部插入GetElem_Sq(La,i++,ai);ListInsert_Sq(Lc,++Lc_Len,ai);}while(i<=Lb_Len){ //如果Lb尚有元素未插入Lc,则全部插入GetElem_Sq(Lb,i++,bj);ListInsert_Sq(Lc,++Lc_Len,bj);}}//MergeList_Sqmain.cpp//main (检验基本操作的主程序)#include "SqList.h"void main(){//定义试验变量SqList L;ElemType e;int i;//初始化顺序表InitList_Sq(L);printf("初始化L后:L.elem=%d L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);//在顺序表首部插入:1,2,3,4,5for(i=1;i<=5;i++){ListInsert_Sq(L,1,i);e=L.elem[0];printf("第%d个元素为%d,此时L.elem=%d L.length=%d L.listsize=%d\n",i,e,L.elem,L.length,L.listsize);}//判空操作printf("顺序表L是否为空:%d(1是0否)\n",ListEmpty_Sq(L));//清空顺序表并判空ClearList_Sq(L);printf("顺序表L是否为空:%d(1是0否)\n",ListEmpty_Sq(L));//在顺序表尾端插入:1,2,3,4,5,6,7,8for(i=1;i<9;i++){ListInsert_Sq(L,i,i);e=L.elem[i-1];printf("第%d个元素为%d,此时L.elem=%d L.length=%d L.listsize=%d\n",i,e,L.elem,L.length,L.listsize);}//求表长操作printf("顺序表L长为%d\n",ListLength_Sq(L));//删除操作printf("删除的第2个元素为%d\n",ListDelete_Sq(L,2,e));//销毁顺序表DestroyList_Sq(L);printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); }。

C语言:2.2 线性表及其顺序存储结构

C语言:2.2 线性表及其顺序存储结构
(a1, a2,...,ai ,...,an )
线性表中数据元素的个数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语言版)

数据结构(c语言版)

目录第1章绪论第2章线性表第3章栈和队列第4章串第5章数组第6章树第7章图第8章查找第9章排序第10章文件第1章绪论1.1数据结构的基本概念和术语1.2算法描述与分析1.3实习:常用算法实现及分析习题11.1数据结构的基本概念和术语1.1.1引例首先分析学籍档案类问题。

设一个班级有50个学生,这个班级的学籍表如表1.1所示。

表1.1学籍表序号学号姓名性别英语数学物理0120030301李明男8691800220030302马琳男7683855020030350刘薇薇女889390个记录又由750我们可以把表中每个学生的信息看成一个记录,表中的每个数据项组成。

该学籍表由个记录组成,记录之间是一种顺序关系。

这种表通常称为线性表,数据之间的逻辑结构称为线性结构,其主要操作有检索、查找、插入或删除等。

又如,对于学院的行政机构,可以把该学院的名称看成树根,把下设的若干个系看成它的树枝中间结点,把每个系分出的若干专业方向看成树叶,这样就形成一个树型结构,如图1.1所示。

树中的每个结点可以包含较多的信息,结点之间的关系不再是顺序的,而是分层、分叉的结构。

树型结构的主要操作有遍历、查找、插入或删除等。

最后分析交通问题。

如果把若干个城镇看成若干个顶点,再把城镇之间的道路看成边,它们可以构成一个网状的图(如图1.2所示),这种关系称为图型结构或网状结构。

在实际应用中,假设某地区有5个城镇,有一调查小组要对该地区每个城镇进行调查研究,并且每个城镇仅能调查一次,试问调查路线怎样设计才能以最高的效率完成此项工作?这是一个图论方面的问题。

交通图的存储和管理确实不属于单纯的数值计算问题,而是一种非数值的信息处理问题。

图1.2交通示意图1.1.2数据结构有关概念及术语一般来说,数据结构研究的是一类普通数据的表示及其相1968 D.E.Knuth 教授开创了数据结“数据结构”是计算机专业的一门专业基础课。

它为操作关的运算操作。

数据结构是一门主要研究怎样合理地组织数据,建立合适的数据结构,提高计算机执行程序所用的时间效率和空间效率的学科。

精品课件-数据结构实用教程(C语言版)-第二章 线性表

精品课件-数据结构实用教程(C语言版)-第二章 线性表
线性表是一种最简单的线性结构 线性结构是一个数据元素的有序(次序)集
线性结构的基本特征:
1.集合中必存在唯一的一个“第一元素”; 2.集合中必存在唯一的一个 “最后元素” 3.除最后元素之外,均有 唯一的后继; 4.除第一元素之外,均有 唯一的前驱。
例如:alphabet=(a,b,c,…,z) 和 prime=(2,3,5,7,11,…,97)alphabet是字母表,其结点是一个英 文字母,prime是100以内的素数表,结点是整型数。且只有一个 域的线性表,
void * malloc(unsigned int size); 在内存的动态存储区中分配一个长度size的连续空间.此函数
的返回值是一个指向分配域起始地址的指针(类型为void). 2. calloc函数
void * calloc(unsigned n,unsigned size); 其作用是在内存的动态分配区中分配n个长度为size的连续空
(n
n 1 i1
i
1)
n 2
在线性表中任何一个位置上删除一个元素所移动元素的平均次
数为:
Edl
1
n
(n
n i1
i)
n 1 2
利用上述定义的线性表类型 可以实现其它更复杂的操作
例 2-1 例 2-2
例 2-1
假设:有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即:线性表中的数据元素即为集合中的成员。
(a1, …, ai-1, ai, …, an) 改变为 (a1, …, ai-1, e, ai, …, an)
<ai-1, ai>
<ai-1, e>, <e, ai>
a1 a2

用C语言定义线性表的顺序存储结构

用C语言定义线性表的顺序存储结构

用C语言定义线性表的顺序存储结构线性表顺序存储的表示:线性表的顺序存储结构可以借助于高级程序设计语言中的一维数组来表示,一维数组的下标与元素在线性表中的序号相对应。

线性表的顺序存储结构可用C语言定义如下:#define MAXSIZE /*线性表可能达到的最大长度;*/ typedef struct{ElemType elem[MAXSIZE];/* 线性表占用的数组空间。

*/ int last;/*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/} SeqList;说明:(1)结点类型定义中ElemType数据类型是为了描述的统一而自定的,在实际应用中,用户可以根据自己实际需要来具体定义顺序表中元素的数据类型,如int、char、float或是一种struct结构类型。

(2)从数组中起始下标为0处开始存放线性表中第一个元素。

因此需要注意区分元素的序号和该元素在数组中的下标之间的对应关系,即数据元素a1在线性表中的序号为1,其对应的elem数组的下标为0;ai在线性表中的序号为i,其对应的elem数组的下标为i-1。

利用定义的顺序表的数据类型SeqList就可以定义变量了。

变量L的定义与使用方法有两种:(1)通过变量定义语句:SeqList L将L定义为SeqList类型的变量,可通过L.elem[i-1]来访问顺序表中序号为i的元素a i;通过st 可得到顺序表中最后一个元素的下标,而st+1就是顺序表的长度。

(2)通过指针变量定义语句:SeqList *L将L定义为指向SeqList类型的指针变量,使用时,可通过L->elem[i-1]来访问顺序表中序号为i的元素a i,通过L->last+1可得到顺序表的长度。

typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。

这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。

数据结构(C语言版) 线性表 详细举例介绍

数据结构(C语言版) 线性表 详细举例介绍
// La中不存在和 e 相同的数据元素,则插入之
}
} // 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 也具有同样特性。

《数据结构C语言版》----第02章

《数据结构C语言版》----第02章
int ListLength(SLNode *head) { SLNode *p = head; int size = 0; while(p->next != NULL) { p = p->next; size ++; } return size; }
p size=0
head
a0
a1
(a)
...
a n 1 ∧
3.顺序表操作的效率分析
时间效率分析: 算法时间主要耗费在移动元素的操作上,因此计算时间复 杂度的基本操作(最深层语句频度) T(n)= O(移动元素次数) 而移动元素的个数取决于插入或删除元素的位置i. 若i=size,则根本无需移动(特别快); 若i=0,则表中元素全部要后移(特别慢); 应当考虑在各种位置插入(共n+1种可能)的平均移动次 数才合理。
(3)带头结点单链表和不带头结点单链表的比较
1).在带头结点单链表第一个数据元素前插入结点
p head s p head data next a0 x

a1

an-1

(a) 插入前
data next a0

a1

an-1

s
x
(b) 插入后
2).删除带头结点单链表第一个数据元素结点
p data next head
(5)取数据元素ListGet(L,
i, x)
int ListGet(SeqList L, int i, DataType *x) { if(i < 0 || i > L.size-1) { printf("参数i不合法! \n"); return 0; } else { *x = L.list[i]; return 1; } }

线性表的顺序存储结构(C语言实现)

线性表的顺序存储结构(C语言实现)

线性表的顺序存储结构(C语⾔实现)1 #include <stdio.h>2 #include <stdlib.h>34#define OK 15#define ERR 26#define TRUE 17#define FALSE 08#define MAXSIZE 20 //定义线性表的最⼤长度910 typedef int status; //定义函数返回的状态,OK & ERR11 typedef char datatype; //定义线性表中每个结点的数据类型,这⾥暂定为字符型1213 typedef struct {14 datatype data[MAXSIZE]; //存储着线性表中的每个结点15int length; //线性表当前的长度16 } SequenceList;1718/* 函数原型,线性表的基本操作 */19 SequenceList *createSequenceList(void);20 status isEmpty(SequenceList *L);21void clear(SequenceList *L);22int getLength(SequenceList *L);23int locateNode(SequenceList *L,datatype node_to_locate);24 datatype getNode(SequenceList *L, int index);25 status insert(SequenceList *L, int index, datatype node_to_insert);26 status delete(SequenceList *L, int index);27void showList(SequenceList *L);2829int main(){30/* 测试 */31 SequenceList *root; //指向线性表32 root=createSequenceList(); //创建⼀个线性表33 printf("Length = %d\n",getLength(root)); //打印线性表的当前长度34 printf("isEmpty = %d\n",isEmpty(root)); //打印线性表是否为空35 insert(root,0,'A'); //分别插⼊4个结点36 insert(root,0,'B');37 insert(root,1,'C');38 insert(root,1,'D');39 printf("Length = %d\n",getLength(root));40 printf("isEmpty = %d\n",isEmpty(root));41 showList(root); //打印线性表42 putchar('\n');43 delete(root,1); //删除index=1(数组下标为1)的结点44 showList(root);45 putchar('\n');46 printf("Locate = %d\n",locateNode(root,'A')); //打印查找到的结点的位置47 printf("getNode = %c\n",getNode(root,1)); //打印下标是1的结点的值48 clear(root); //清空线性表49 printf("isEmpty = %d",isEmpty(root));5051return0;52 }5354 SequenceList *createSequenceList(void){55 SequenceList *tmp;56 tmp=malloc(sizeof(SequenceList));//void*类型指针能⾃动转为其他类型的指针57 tmp->length=0; //初始化线性表长度58return tmp;59 }60 status isEmpty(SequenceList *L){61if (L->length==0)62return TRUE;63else64return FALSE;65 }66void clear(SequenceList *L){67 L->length=0;68 }69int getLength(SequenceList *L){70return L->length;71 }72int locateNode(SequenceList *L, datatype node_to_locate){73//返回找到的结点的index74//node_to_locate应当是能唯⼀标识⼀个结点的数据,否则只返回匹配的第⼀个结点75int i;76for (i=0; i<L->length; i++){77if (L->data[i]==node_to_locate)78return i;79 }80return -1; //未找到任何匹配81 }82 datatype getNode(SequenceList *L, int index){83//index表⽰线性表中第N个结点,头结点的index是084if (L->length==0 || index<0 || index>L->length-1) return (datatype)ERR; 85return L->data[index];86 }87 status insert(SequenceList *L, int index, datatype node_to_insert){88//node_to_insert表⽰想要插⼊的结点89//当列表为空时,只有index=0才能插⼊90int k;91if (L->length == MAXSIZE) return ERR; //线性表已满92if (index<0 || index>L->length) return ERR; //index不在有效范围93if (index<L->length){94//插⼊的位置不是最后⼀个结点的下⼀个结点95for (k=L->length-1; k>=index; k--){96 L->data[k+1]=L->data[k]; //将要插⼊结点后⾯的所有结点都往后移97 }98 }99 L->data[index]=node_to_insert; //将新结点插⼊100 L->length++;101return OK;102 }103 status delete(SequenceList *L, int index){104int k;105if (L->length == 0) return ERR; //线性表为空106if (index<0 || index>L->length-1) return ERR; //index不在有效范围107if (index<L->length-1){108//删除的位置不是最后⼀个结点109for (k=index; k<L->length-1; k++){110 L->data[k]=L->data[k+1]; //将删除位置后⾯的结点都往前移111 }112 }113 L->length--;114return OK;115 }116void showList(SequenceList *L){117int i;118for (i=0; i<L->length; i++){119 printf("%c\t",L->data[i]);120 }121 }122123/*124顺序存储结构的线性表的优缺点:125优点:126 1.不必为每个结点之间的逻辑关系增加额外的存储空间127 2.可以快速地读和写表中任意⼀个结点128缺点:129 1.插⼊和删除需要移动⼤量结点130 2.线性表动态变化较⼤,难以确定所需的存储空间131 3.数组预设过长会造成空间浪费(存储碎⽚)132*/133/* 环境: Code::Blocks with GCC 5.1 */运⾏截图:。

数据结构实验 C语言版 线性表__C版

数据结构实验 C语言版 线性表__C版
17
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语言版)(浦江学院)

《数据结构》实验指导书(C语言版)(浦江学院)

实验1: 顺序表的操作实验一、实验名称和性质二、实验目的1.掌握线性表的顺序存储结构的表示和实现方法。

2.掌握顺序表基本操作的算法实现。

3.了解顺序表的应用。

三、实验内容1.建立顺序表。

2.在顺序表上实现插入、删除和查找操作(验证性内容)。

3.删除有序顺序表中的重复元素(设计性内容)。

四、实验的软硬件环境要求硬件环境要求:PC机(单机)使用的软件名称、版本号:Windows环境下的VC++6.0五、知识准备前期要求熟练掌握了C语言的编程规则、方法和顺序表的基本操作算法。

六、验证性实验1.实验要求编程实现如下功能:(1)根据输入顺序表的长度n和各个数据元素值建立一个顺序表,并输出顺序表中各元素值,观察输入的内容与输出的内容是否一致。

(2)在顺序表的第i个元素之前插入一个值为x的元素,并输出插入后的顺序表中各元素值。

(3)删除顺序表中第i个元素,并输出删除后的顺序表中各元素值。

(4)在顺序表中查找值为e的数据元素,如果查找成功,则显示“查找成功”和该元素在顺序表中的位置,否则显示“查找失败”。

2. 实验相关原理线性表的顺序存储结构称为顺序表,顺序表的存储结构描述为:#define MAXLEN 30 /*线性表的最大长度*/typedef struct{Elemtype elem[MAXLEN]; /*顺序表中存放元素的数组,其中elemtype为抽象数据类型,在程序具体实现时可以用任意类型代替*/int length; /*顺序表的长度,即元素个数*/}Sqlist; /*顺序表的类型*/【核心算法提示】(1)顺序表插入操作的基本步骤:要在顺序表中的第i个数据元素之前插入一个数据元素x,首先要判断插入位置i是否合法,假设线性表的表长为n,则i的合法值范围:1≤i ≤n+1,若是合法位置,就再判断顺序表是否满,如果满,则增加空间或结束操作,如果不满,则将第i个数据元素及其之后的所有数据元素都后移一个位置,此时第i个位置已经腾空,再将待插入的数据元素x插入到该位置上,最后将线性表的表长增加1。

数据结构c语言顺序表

数据结构c语言顺序表

数据结构c语言顺序表
数据结构c语言顺序表是一种线性存储结构,它采用一组连续的内存空间存储相同类型的数据。

顺序表的元素在内存中的存储顺序与逻辑上的顺序相同,可以通过下标随机访问元素。

顺序表的操作包括:初始化顺序表、插入元素、删除元素、查找元素、修改元素、遍历顺序表等。

在c语言中,顺序表可以使用数组来实现。

数组的大小可以在初始化时指定,也可以使用动态内存分配函数malloc来动态分配数组大小。

动态分配可以避免浪费内存空间,但需要注意及时释放内存。

顺序表的优点是随机访问速度快,操作简单方便。

缺点是插入、删除元素时需要移动大量元素,效率较低。

对于频繁插入、删除元素的情况,可考虑使用链表等其他数据结构。

总之,顺序表是数据结构中常用的一种线性结构,掌握其基本操作和实现方式对于提高程序效率和性能具有重要意义。

- 1 -。

线性表的顺序存储表示_数据结构(C语言版)(第2版)_[共2页]

线性表的顺序存储表示_数据结构(C语言版)(第2版)_[共2页]

23 于一元多项式的运算可以看作是线性表的合并,合并过程需要不断地进行元素的插入操作。

其他如求线性表的拆分、复制等操作也都可以利用上述基本操作的组合来实现。

(3)对于不同的应用,基本操作的接口可能不同。

例如,案例2.2的删除操作,如果要求删除图书表中ISBN 为x 的图书,首先需要根据x 确定该图书在线性表中的位置,然后再利用ListDelete(&L,i)基本操作将该种图书记录从表中删除。

(4)由抽象数据类型定义的线性表,可以根据实际所采用的存储结构形式,进行具体的表示和实现。

2.4 线性表的顺序表示和实现2.4.1 线性表的顺序存储表示线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。

通常,称这种存储结构的线性表为顺序表(Sequential List )。

其特点是,逻辑上相邻的数据元素,其物理次序也是相邻的。

假设线性表的每个元素需占用l 个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储起始位置。

则线性表中第i + 1个数据元素的存储位置LOC(a i + 1)和第i 个数据元素的存储位置LOC(a i )之间满足下列关系:LOC(a i + 1) = LOC(a i ) + l一般来说,线性表的第i 个数据元素a i 的存储位置为:LOC(a i ) = LOC(a 1) + (i − 1) × l式中,LOC(a 1)是线性表的第一个数据元素a 1的存储位置,通常称作线性表的起始位置或基地址,表中相邻的元素a i 和a i + 1的存储位置LOC(a i )和LOC(a i + 1)是相邻的。

每一个数据元素的存储位置都和线性表的起始位置相差一个常数,这个常数和数据元素在线性表中的位序成正比(见图2.2)。

由此,只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。

数据结构线性表的顺序存储结构C语言实现

数据结构线性表的顺序存储结构C语言实现

完成时间
typedef int ElemType; typedef struct{
ElemType *elem; int length; int listsize; }SqList;
void color(const unsigned short color1)//颜色函数 {
/*仅限改变 0-15 的颜色;如果在 0-15 那么实现他的颜色 因为如果超过 15 后面的改 变的是文本背景色*/
int *p; //在线性表 L 中查找第一个值与 e 满足 compare()的元素的位序 //若找到,则返回其在 L 中的位序,否则返回 0 int i=1; p=L->elem; while((i<=L->length) && (!(*compare)(*p++,5))) ++i; if(i<=L->length) return i; else return 0; } */ void search_L(SqList *L,ElemType e)//查找操作 { int j,flag=0; color(13); printf("\n 顺序表当前数据:"); printsq_L(L); color(10); printf("\n 请输入要查找的元素:");
学号:2015201018
数学与信息技术学院 2016~2017(下)学年
计科专业 2015 级《数据结构》实验报告 1
实验名称 线性表的顺序存储结构
实验目的
实验内容
姓名:汪继超
1. 掌握线性表的概念,掌握顺序表的概念及其各种运算 的原理。
2. 通过对线性表的查找、插入和删除算法的实现以加深 对线性表的顺序存储结构的理解,为加强线性表在实 际中的应用打下基础。

动态分配的顺序线性表的十五种操作—C语言实现

动态分配的顺序线性表的十五种操作—C语言实现

动态分配的顺序线性表的⼗五种操作—C语⾔实现线性表定义:是最常⽤的,也是最简单的数据结构,是长度为n个数据元素的有序的序列。

含有⼤量记录的线性表叫⽂件记录:稍微复杂的线性表⾥,数据元素为若⼲个数据项组成,这时把⼀个数据元素叫记录结构特点:在⾮空有限的条件下,存在唯⼀的⼀个表头结点,唯⼀的⼀个表尾结点,除去第⼀个元素之外,每个数据元素都只有⼀个前驱,除去最后⼀个元素之外,每⼀个数据元素都只有⼀个后继。

注意:线性表中的数据元素可以是各种各样的,但同⼀线性表中的元素必定具有相同特性(属于同⼀数据对象,类似数组)。

线性表的数据元素间有序偶关系。

线性表的顺序表⽰和实现有⼀组地址连续的内存单元,在这些连续的内存单元⾥,顺次地存储线性表⾥的数据元素特点:逻辑地址和物理地址都是连续的,适合随机存取。

假设&a1为线性表的基址,每个数据元素占据L个存储单位。

那么表⾥第i个元素的存储地址:&a(i) = &a(1) + (i - 1)x L线性表的顺序表⽰结构(顺序映象)也叫顺序表,顺序表中元素的逻辑关系和物理位置⼀致,是⼀种随机存取的存储结构。

(类似⾼级语⾔⾥的数组,通常⽤数组描述数据结构的顺序存储结构)。

如果⽤数组表⽰顺序表,那很简单,也不实⽤,不能改变存储容量,下⾯是动态分配的顺序表的表⽰和操作ADT.h头⽂件1/************************************************************************/2/* 功能:声明常量和函数原型的头⽂件,线性表的动态分配顺序存储结构3/* 作者:dashuai4/************************************************************************/5 #include <stdio.h>6 #include <stdlib.h>7#define LIST_INIT_SIZE 100//线性表初始化存储空间分配8#define LISTINCREMENT 10//线性表存储空间的分配增量910 typedef struct{//此时可以省去结构标记11int *elem;//线性表基址12int length;//当前表长13int listsize;//当前为线性表分配的存储容量14 } SqList;//为结构起的别名SqList1516//线性表常⽤的有13个操作,归为4类1718/************************************************************************/19/*第⼀类:初始化操作,记住各种数据结构开始使⽤都要初始化 */20/************************************************************************/2122//1、线性表的初始化,构造⼀个空的线性表23int InitList(SqList *L);//因为要改变线性表,必须⽤指针做参数2425/************************************************************************/26/*第⼆类:销毁操作,记住各种数据结构使⽤了都要有销毁的步骤 */27/************************************************************************/2829//2、销毁,释放内存操作30void Destory(SqList *L);//直接把内存释放的操作!类似与free()3132/************************************************************************/33/* 第三类:引⽤型操作,操作不改变线性表⾥的数据元素,也不改变他们之间的关系*/34/************************************************************************/3536//3、判空操作,若线性表已经存在,为空⽩则返回true,否则返回false37void ListEmpty(SqList L);3839//4、求长度操作,若线性表已经存在,则返回表L中元素个数40int ListLength(SqList L);4142//5、定位操作:线性表 L 已存在,返回 L 中第 1 个与 e 满⾜相等关系的元素的位序。

线性表的动态分配顺序存储结构

线性表的动态分配顺序存储结构

util.h//通用头文件:存放公共函数或变量#include "stdio.h"#include "stdlib.h"//函数结果状态代码#define TRUE 1#define FALSE 0#define OK 2#define ERROR -1#define INFEASIBLE -2 //不可行#define OVERFLOW -3//声明函数返回值的数据类型typedef int Status;//声明线性表中元素的数据类型typedef int ElemType;//声明相关辅助函数Status Compare(ElemType,ElemType);void Vist(ElemType);//声明函数指针typedef Status (*pCompare)(ElemType,ElemType);typedef void (*pVisit)(ElemType);u.til.cpp//通用函数的定义#include "util.h"Status Compare(ElemType e1,ElemType e2){//操作结果:比较e1和e2是否相等。

若相等,则返回TRUE;否则返回FALSE if(e1==e2)return TRUE;elsereturn FALSE;}//Comparevoid Visit(ElemType e){//操作结果:在屏幕上输出eprintf("%d ",e);}//VisitSqList.h//顺序表头文件#include "util.h"//线性表的动态分配顺序存储结构#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define LISTINCREMENT 10 //线性表存储空间的分配增量typedef struct{ElemType *elem; //存储空间基址int length; //当前长度int listsize; //当前分配的存储容量}SqList;//顺序表的基本操作Status InitList_Sq(SqList&);Status DestroyList_Sq(SqList&);//声明顺序表的引用型操作Status ListEmpty_Sq(SqList);int ListLength_Sq(SqList);ElemType PriorElem_Sq(SqList,ElemType,ElemType&); ElemType NextElem_Sq(SqList,ElemType,ElemType&); ElemType GetElem_Sq(SqList,int,ElemType&);int LocateElem_Sq(SqList,ElemType,pCompare);void ListTraverse_Sq(SqList,pVisit);//声明顺序加工型操作Status ClearList_Sq(SqList&);Status PutElem(SqList&,int,ElemType);Status ListInsert_Sq(SqList&,int,ElemType);Status ListDelete_Sq(SqList&,int,ElemType&);void Union(SqList&,SqList);void Purge(SqList&,SqList);void MergeList_Sq(SqList,SqList,SqList&);SqList.cpp//顺序表的操作#include "SqList.h"//顺序表的基本操作Status InitList_Sq(SqList &L){ //操作结果:构造一个空线性表LL.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));//申请分配存储空间if(!L.elem) exit(OVERFLOW); //存储分配失败L.length=0; //顺序表长度初始化为0L.listsize=LISTINCREMENT; //当前存储容量大小为INCREMENT return OK;}//InitList_SqStatus DestroyList_Sq(SqList &L){//初始条件:顺序表L存在//操作结果:销毁顺序表Lif(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败free(L.elem); //释放存储空间L.length=0;L.listsize=0;L.elem=NULL;return OK;}//DestroyList_Sq//顺序表的引用型操作Status ListEmpty_Sq(SqList L){//初始条件:顺序表L存在//操作结果:查看顺序表L是否为空表,是则返回TRUE;反之返回FALSEif(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(L.length==0)return TRUE;elsereturn FALSE;}//ListEmpty_Sqint ListLength_Sq(SqList L){//初始条件:顺序表L存在//操作结果:返回顺序表长度if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败return L.length;}//ListLength_SqElemType PriorElem_Sq(SqList L,ElemType cur_e,ElemType &pre_e){//初始条件:顺序表L存在//操作结果:若cur_e在顺序表中,且不是第一个元素,则用pre_e返回其前驱// 否则操作不可行int pos=2; //cur_e当前位置pos≥2if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败ElemType *p=L.elem+1; //从顺序表第2个位置查找cur_ewhile(pos++<=L.length&&(*p++)!=cur_e); //pos范围2≤pos≤L.Lengthif(pos>L.length) return INFEASIBLE; //到表结束未找到cur_e,操作不可行else{pre_e=(*--p); //pre_e为当前值cur_e的前驱return pre_e; //返回前驱pre_e}}//PriorElem_SqElemType NextElem_Sq(SqList L,ElemType cur_e,ElemType &next_e){//初始条件:顺序表L存在//操作结果:若cur_e在顺序表中,且不是最后一个元素,则用next_e返回其后继// 否则操作不可行int pos=1; //cur_e当前位置pos≥2if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败ElemType *p=L.elem; //从顺序表第1个位置查找cur_ewhile(pos++<L.length&&(*p++)!=cur_e); //pos范围1≤pos<L.Lengthif(pos==L.length) return INFEASIBLE; //到表尾未找到cur_e,操作不可行else{next_e=(*++p); //pre_e为当前值cur_e的前驱return next_e; //返回前驱pre_e}}//NextElem_SqElemType GetElem_Sq(SqList L,int pos,ElemType &e){//初始条件:顺序表L存在,且1≤pos≤L.Length//操作结果:用e返回pos位置的值if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(pos<1||pos>L.length) return ERROR; //pos取值范围1≤pos≤L.Lengthelse{e=*(L.elem+pos-1);return e; //用e返回pos位置的值}}//GetElemint LocateElem_Sq(SqList L,ElemType e,pCompare equal){//初始条件:顺序表L存在//操作结果:若元素e在顺序表中存在,则返回其在顺序表中第一次出现的位置// 否则,操作不可行int pos=1; //pos≥1if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败ElemType *p=L.elem; //从顺序表第1个位置查找cur_e while(pos++<=L.length&&!equal(*p++,e));//遍历顺序表查找第一个cur_eif(pos>L.length)return 0; //到表结束时未找到元素e elsereturn pos; //返回顺序表中出现e的第一个位置}//LocateElem_Sqvoid ListTraverse_Sq(SqList L,pVisit visit){//初始条件:顺序表L存在//操作结果:遍历顺序表,在屏幕上显示顺序表元素int pos;if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败for(pos=1;pos<=L.length;pos++) visit(L.elem[pos-1]);printf("\n");}//ListTraverse_Sq//加工型操作Status ClearList_Sq(SqList &L){//初始条件:线性表L已存在//操作结果:将L重置为空表L.length=0; //空表长度为0return OK;}//ClearList_SqStatus PutElem_Sq(SqList &L,int pos,ElemType e){//初始条件:顺序表L存在,且pos范围为1≤pos≤L.length//操作结果:顺序表第pos个位置赋值为eif(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败L.elem[pos-1]=e;return OK;}//PutElem_SqStatus ListInsert_Sq(SqList &L,int pos,ElemType e){//初始条件:顺序表L存在,且pos范围为1≤pos≤L.length+1//操作结果:将e插入到顺序表第pos个位置,顺序表长度加1ElemType *newbase;ElemType *p,*q;if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(pos<1||pos>L.length+1) return INFEASIBLE; //pos值不合法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; //表长加1}q=&L.elem[pos-1]; //q指向需要右移的元素位置for(p=&L.elem[L.length-1];p>=q;p--) *(p+1)=*p;//右移元素*q=e;L.length++;return OK;}//ListInsert_SqStatus ListDelete_Sq(SqList &L,int pos,ElemType &e){//初始条件:顺序表L存在,且pos范围为1≤pos≤L.length//操作结果:将顺序表中第pos个位置的元素e删除,并用e返回ElemType *p,*q;if(!L.elem) exit(ERROR); //顺序表不存在,函数调用失败if(pos<1||pos>L.length) return INFEASIBLE; //pos值不合法q=L.elem+pos-1; //p指向被删除元素的位置) e=*q; //被删除元素赋值给efor(p=&L.elem[L.length-1];p>=++q;p--) *(p-1)=*p;//左移元素L.length--;return e;}//ListDelete_Sqvoid Union(SqList &La,SqList Lb) //A∪B{int i;int La_Len,Lb_Len;ElemType e;pCompare equal;La_Len=ListLength_Sq(La); //即La_Len=La.lengthLb_Len=ListLength_Sq(Lb); //即Lb_Len=Lb.lengthfor(i=1;i<=Lb_Len;i++){GetElem_Sq(Lb,i,e); //e=Lb.elem[i-1]if(!LocateElem_Sq(La,e,equal))ListInsert_Sq(La,++La_Len,e); //插入La之后}}//unionvoid Purge(SqList &La,SqList Lb) //提取A集合(纯化){int i;int La_Len,Lb_Len;ElemType e,en;pCompare equal; //Compare函数指针InitList_Sq(La); //构造一个空顺序表La_Len=ListLength_Sq(La); //取La当前长度Lb_Len=ListLength_Sq(Lb); //取Lb当前长度for(i=1;i<=Lb_Len;i++){ //遍历顺序表LbGetElem_Sq(Lb,i,e); //e=Lb.elem[i-1];if(!equal(en,e)) ListInsert_Sq(La,++La_Len,e);en=e; //en=Lb.elem[i-1] }}//Purgevoid MergeList_Sq(SqList La,SqList Lb,SqList &Lc)//合并升序序列{InitList_Sq(Lc); //构造一个空顺序表Lcint i=1; //i指示La位置int j=1; //j指示Lb位置int La_Len,Lb_Len,Lc_Len;ElemType ai,bj; //暂存La、Lb中的元素//取La、Lb、Lc当前长度La_Len=ListLength_Sq(La);Lb_Len=ListLength_Sq(Lb);Lc_Len=ListLength_Sq(Lc);//将短顺序表取出与长顺序表进行排序,并插入Lc中while(i<=La_Len&&j<=Lb_Len){GetElem_Sq(La,i,ai); //ai=La.elem[i-1];GetElem_Sq(Lb,j,bj); //bj=Lb.elem[j-1];//将小的值插入Lcif(ai<=bj){ListInsert_Sq(Lc,++Lc_Len,ai);i++;}else{ListInsert_Sq(Lc,++Lc_Len,bj);j++;}}while(i<=La_Len){ //如果La尚有元素未插入Lc,则全部插入GetElem_Sq(La,i++,ai);ListInsert_Sq(Lc,++Lc_Len,ai);}while(i<=Lb_Len){ //如果Lb尚有元素未插入Lc,则全部插入GetElem_Sq(Lb,i++,bj);ListInsert_Sq(Lc,++Lc_Len,bj);}}//MergeList_Sqmain.cpp//main (检验基本操作的主程序)#include "SqList.h"void main(){//定义试验变量SqList L;ElemType e;int i;//初始化顺序表InitList_Sq(L);printf("初始化L后:L.elem=%d L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);//在顺序表首部插入:1,2,3,4,5for(i=1;i<=5;i++){ListInsert_Sq(L,1,i);e=L.elem[0];printf("第%d个元素为%d,此时L.elem=%d L.length=%d L.listsize=%d\n",i,e,L.elem,L.length,L.listsize);}//判空操作printf("顺序表L是否为空:%d(1是0否)\n",ListEmpty_Sq(L));//清空顺序表并判空ClearList_Sq(L);printf("顺序表L是否为空:%d(1是0否)\n",ListEmpty_Sq(L));//在顺序表尾端插入:1,2,3,4,5,6,7,8for(i=1;i<9;i++){ListInsert_Sq(L,i,i);e=L.elem[i-1];printf("第%d个元素为%d,此时L.elem=%d L.length=%d L.listsize=%d\n",i,e,L.elem,L.length,L.listsize);}//求表长操作printf("顺序表L长为%d\n",ListLength_Sq(L));//删除操作printf("删除的第2个元素为%d\n",ListDelete_Sq(L,2,e));//销毁顺序表DestroyList_Sq(L);printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构C语言版线性表的动态分配顺序存储结构表示和实现P22-26编译环境:Dev-C++ 4.9.9.2日期:2011年2月9日*/#include <stdio.h>#include <malloc.h>#include <stdlib.h>typedef int ElemType; // 定义数据结构元素的数据类型#define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量#define LISTINCREMENT 5 // 线性表存储空间的分配增量// 线性表的动态分配顺序存储结构typedef struct{ElemType *elem; // 存储空间基址int length; // 当前长度int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位) }SqList;// 算法2.3,P23// 构造一个空的顺序线性表即对顺序表结构体中的所有元素// 进行初始化。

int InitList(SqList *L){// 分配指定大小的存储空间给顺序表(*L).elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));if( !(*L).elem ) // 存储分配失败exit(0);(*L).length = 0; // 当前长度初始化为0// 指定分配的存储容量(*L).listsize = LIST_INIT_SIZE;return 1;}// 销毁顺序线性表L即将顺序表结构体中的所有成员销毁(空间释放,// 数值置0)。

int DestroyList(SqList *L)// 先释放空间,然后置空free( (*L).elem );(*L).elem = NULL;(*L).length = 0;(*L).listsize = 0;return 1;}// 将L重置为空表(当前长度为0即是空表)。

int ClearList(SqList *L){(*L).length = 0;return 1;}/*若L为空表,则返回1,否则返回0。

如何判断是否为空表呢?结构体中已经包含一个可以说明的元素,那就是length,表示当前顺序表的长度,根据当前的长度就可以判断了,为0就是空表,不为0就不是空表了。

*/int ListEmpty(SqList L){if(0 == L.length)return 1;elsereturn 0;}// 返回L中数据元素个数。

int ListLength(SqList L){// L.length刚好记录了当前顺序表的长度,直接返回return L.length;}// 用e返回L中第i个数据元素的值,第i个数据元素就是L.elem[i-1]。

int GetElem(SqList L,int i,ElemType *e){// 首先进行异常处理if(i < 1 || i > L.length)exit(0);/*注意顺序表基址L.elem[0] 表示第一个数,而第i个数则是用基址L.elem + i - 1来表示,也可以用L.elem[i-1]表示。

为什么可以那样表示呢?因为l.elem是基地址,相当于数组头一样,指示了一个首地址,然后对地址进行加减,形成不同元素的地址。

*是取地址所指的内容,所以*(L.elem+i-1)就是第i个数据的值了。

*/*e = *(L.elem + i - 1);// *e = L.elem[i-1];return 1;}/* 算法2.6,P26返回L中第1个与e满足关系compare()的数据元素的位序。

若这样的数据元素不存在,则返回值为0。

*/int LocateElem(SqList L,ElemType e,int(* compare)( ElemType, ElemType)){ElemType *p;int i = 1; // i的初值为第1个元素的位序p = L.elem; // p的初值为第1个元素的存储位置即地址// 循环比较,直到找到符合关系的元素while(i <= L.length && !compare(*p++, e) )++i;if(i <= L.length)return i;elsereturn 0;}#if 0/* 算法2.7 与算法2.2区别已知顺序线性表La和Lb的元素按值非递减排列。

归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列。

算法的时间复杂度为O(La.length + Lb.length).*/void MergeList(SqList La, SqList Lb, SqList *Lc){ElemType *pa, *pa_last, *pb, *pb_last, *pc;pa = La.elem; //pa指向线性表La的头结点pb = Lb.elem; //pb指向线性表Lb的头结点/* 不用InitList()创建空表Lc */(*Lc).listsize = (*Lc).length = La.length + Lb.length;// pc指向线性表Lc的头结点pc = (*Lc).elem =(ElemType *)malloc((*Lc).listsize*sizeof(ElemType));if( !(*Lc).elem ) /* 存储分配失败 */exit(0);pa_last = La.elem + La.length - 1; //pa_last指向线性表La的尾结点pb_last = Lb.elem + Lb.length - 1; //pb_last指向线性表Lb的尾结点while(pa <= pa_last && pb <= pb_last) /* 表La和表Lb均非空 */{ /* 归并 */if(*pa <= *pb) //*pa更小接到pc后*pc++ = *pa++;else //*pb更小接到pc后*pc++ = *pb++;}while(pa <= pa_last) /* 表La非空且表Lb空 */*pc++ = *pa++; /* 插入La的剩余元素 */while(pb <= pb_last) /* 表Lb非空且表La空 */*pc++ = *pb++; /* 插入Lb的剩余元素 */}#endif// 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否// 则返回0。

int PriorElem(SqList L, ElemType cur_e, ElemType *pre_e){int i = 2;// 因为第一个数据元素无前继,从第二个数据元素开始ElemType *p = L.elem + 1;// 找到该cur_e对应的元素并赋给pwhile(i <= L.length && *p != cur_e){p++;i++;}if(i > L.length)return 0;else{/*将该cur_e的前驱赋给*pre_e.对等式说明下:* 和 --是同优先级的,且它们的结合性是自右向左的,所以先p自减1,p指向其前驱,然后将p所指向的地址的内容赋给*pre_e。

从这里要明白为什么用指针进行传值,我给你一个地址,你把内容放进去,然后我就知道其中的值了。

这就是使用指针的用处。

*/*pre_e = *--p;return 1;}}/*若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则返回0*/int NextElem(SqList L,ElemType cur_e,ElemType *next_e){int i = 1;ElemType *p = L.elem;while(i < L.length && *p != cur_e){i++;p++;}if(i == L.length)return 0;else{/*对这个等式说明下:* 和 --是同优先级的,且它们的结合性是自右向左的,所以先p自加1,然后将p所指向的地址的内容赋给*next_e*/*next_e = *++p;return 1;}}// 算法2.4 P24// 在L中第i个位置之前插入新的数据元素e,L的长度加1.int ListInsert(SqList *L,int i,ElemType e){ElemType *newbase, *q, *p;// 输入的i不合法if(i < 1 || i > (*L).length + 1)return 0;// 当前存储空间已满,增加分配if( (*L).length >= (*L).listsize){// realloc改变(*L).elem所指内存的大小,原始所指内存中的// 数据不变。

newbase = (ElemType *)realloc((*L).elem,((*L).listsize + LISTINCREMENT) * sizeof(ElemType));if( !newbase )exit(0);(*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 1;}/* 算法2.5 P25删除L的第i个数据元素,并用e返回其值,L的长度减1.*/int ListDelete(SqList *L,int i,ElemType *e){ElemType *p,*q;// i值不合法if( i < 1 || i > (*L).length)return 0;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 1;}// 依次对L的每个数据元素调用函数vi()。

相关文档
最新文档