线性表顺序存储结构上的基本运算
线性表的类型定义、顺序表示和实现
i=n 只删 an即可 1≤i≤n -1 将ai+1 ~an前移
23
bool deleteElem(SqList& L,int pos)
typedef int ElemType;
typedef char ElemType;
等;
②同一线性表中的数据元素必须具有相同的特性,属同一类 型;
③a2,关…系, ra是i-1,一a个i, a有i+1序, …偶,对an的)集,合a,i-1即领对先于于非ai,空表的示线了性数表据(元a1,素 之间的相邻关系,称ai-1是ai的直接前驱,ai是ai-1的直接后继 ;
6
2.1.3 操作举例
例:假设利用两个线性表La和Lb分别表示两 个集合A和B,求一个新的集合A=A∪B。
算法:
– ①取得Lb中的1个元素; – ②在La中查找这个元素; – ③若不存在:插入La中;若存在,取Lb中下一个
元素,重复 ①、②、③,直到取完Lb的每个元素 。
7
void unionList(SqList &la,SqList lb)
10
线性表的顺序存储结构示意图
存储地址
loc(a1) loc(a1)+ k
内存空间状态 逻辑地址
a1
1
a2
2
…
…
…
loc(a1)+ (i- 1)k
ai
i
…
…
…
loc(a1)+ (n- 1)k
an
n 空闲
顺序存储结构可以借助于高级程序设计语言中的一维数组来表示。
11
用C++语言描述的顺序表类型如下所示: sqlist.h
数据结构习题及答案与实验指导(线性表)2
第2章线性表线性表是一种最基本、最常用的数据结构,它有两种存储结构——顺序表和链表。
本章主要介绍线性表的定义、表示和基本运算的实现。
重点讨论了线性表的存储结构,以及在顺序、链式两种存储结构上基本运算的实现。
重点提示:●线性表的逻辑结构特征●线性表的顺序存储和链式存储两种存储结构的特点●在两种存储结构下基本操作的实现2-1 重点难点指导2-1-1 相关术语1.线性表线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,通常记为:(a1,a2,…,a n),其中n为表长,n=0时称为空表。
要点:一种逻辑结构,其数据元素属于相同数据类型,之间的关系是线性关系。
2.顺序表顺序存储的线性表。
要点:按线性表中的元素的逻辑顺序依次存放在地址连续的存储单元里,其存储特点:用物理上的相邻实现逻辑上的相邻。
3.链表用链表存储的线性表。
要点:链表是通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,对每个结点的地址是否连续没有要求。
4.单链表每个结点除了数据域外还有一个指向其后继的指针域。
要点:通常将每个元素的值和其直接后继的地址作为一个结点,通过每个结点中指向后继结点的指针表示线性表的逻辑结构。
5.头指针要点:头指针是一个指针变量,里面存放的是链表中首结点的地址,并以此来标识一个链表。
如链表H,链表L等,表示链表中第一个结点的地址存放在指针变量H、L中。
通常用头指针来惟一标识一个链表。
6.头结点要点:附加在第一个元素结点之前的一个结点,头指针指向头结点。
当该链表表示一个非空的线性表时,头结点的指针域指向第一个元素结点;为空表时,该指针域为空。
7.头结点的作用要点:其作用有两个,一是使对空表和非空表的处理得到统一;二是在链表的第一个位置上的操作和在其他位置上的操作一致,无需特殊处理。
2-1-2 线性表的顺序存储1.顺序表顺序存储的线性表称为顺序表。
其特点是:用一组地址连续的存储单元来依次存放线性表的数据元素,因此数据元素的逻辑顺序和物理次序一致(这是顺序存储的核心所在)。
《数据结构》线性结构实验报告
《数据结构》线性结构实验报告2、源程序:#include <stdio.h>#include<stdlib.h>#define MAXSIZE 1024typedef int elemtype;typedef struct SequenStack{elemtype data[MAXSIZE];int top;}SequenStack;SequenStack * Init_SequenStack(){SequenStack * S;S = (SequenStack *)malloc(sizeof(SequenStack));if (S == NULL)return S;S->top = -1;return S;}int SequenStack_Empty(SequenStack * S)//判栈空{if (S->top == -1){return 1;}{int a;printf("请以十进制输入一个数:\n");scanf_s("%d", &a);printf("转化为二进制为:");Conversion(a);printf("\n");}运行结果:3、源程序:#include<stdio.h>#include<stdlib.h>#include<string.h>typedef struct node{char data;struct node* next;}LinkStack;//初始化LinkStack* Init_LinkStack(){LinkStack* top;top = (LinkStack*)malloc(sizeof(LinkStack));top->next = NULL;return top;}//入栈void Push_LinkStack(LinkStack* top, char x){LinkStack* node;node = (LinkStack*)malloc(sizeof(LinkStack));node->data = x;node->next = top->next;top->next = node;}运行结果:4、源程序:#include <stdio.h>#include<stdlib.h>#include<string.h>#define MAXSIZE 20typedef int elemtype;typedef struct QueueNode{elemtype data;struct QueueNode* next;}LinkedQueueNode;typedef struct LQueue{LinkedQueueNode* front;LinkedQueueNode* rear;}LQueue, *LinkedQueue;typedef struct Person{char name[MAXSIZE];char sex;}Person;typedef char* ElemType;//链队初始化LinkedQueue Init_LinkedQueue(){LinkedQueue Q = (LinkedQueue)malloc(sizeof(LQueue));LinkedQueueNode * head = (LinkedQueueNode *)malloc(sizeof(LinkedQueueNode));if (head != NULL && Q != NULL){head->next = NULL;Q->front = head;Q->rear = head;printf("输入参与者的姓名,性别\n");for (i = 0; i < num; i++){printf("输入第%d个舞者的名字:\n", i + 1);scanf_s("%s", &dancer[i].name, 10);printf("输入第%d个人的性别(F/M):\n", i + 1);scanf_s("%s", &dancer[i].sex, 10);while (dancer[i].sex != 'F' && dancer[i].sex != 'M'){printf("输入错误,请重新输入第%d个人的性别(F/M):\n", i + 1);scanf_s("%s", &dancer[i].sex, 10);}}DancePartner(dancer, num);break;case 0:printf("感谢你的使用!\n");break;default:printf("无此选项!\n");break;}} while (n != 0);return 0;}运行结果:。
算法与数据结构第2章 线性表
利用已有基本运算求解问题 例2.1 假设有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即线性表中的数据元素即为集合中的成员。编写一 个算法求一个新的集合C=A∪B,即将两个集合的并集放在线 性表LC中。 解题思路: LC LA LC LB中不在LA中的元素
void unionList(List LA,List LB,List &LC)
该运算返回L中第 i(1≤i≤ListLength(L))个元素的值,存放在e中。
e=L->data[i-1];
return 1; } 本算法的时间复杂度为O(1)。
(7) 按元素值查找LocateElem(L,e) 该运算顺序查找第1个值域与e相等的元素的位序。若这样的元 素不存在,则返回值为0。 int LocateElem(SqList *L, ElemType e) { int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) else } return i+1; return 0;
{ int lena,lenb,lenc,i; ElemType e; InitList(LC); lena=ListLength(LA); for (i=1;i<=lena;i++) //求线性表的长度
//将LA的所有元素插入到Lc中
{ GetElem(LA,i,e); ListInsert(LC,i,e);
0
返回到 sq Main:
???
main:
引用的作用 main() { SqList *sq; InitList(sq); op(sq);
线性表的存储结构定义及基本操作
一、实验目的:. 掌握线性表的逻辑特征. 掌握线性表顺序存储结构的特点,熟练掌握顺序表的基本运算. 熟练掌握线性表的链式存储结构定义及基本操作. 理解循环链表和双链表的特点和基本运算. 加深对顺序存储数据结构的理解和链式存储数据结构的理解,逐步培养解决实际问题的编程能力二、实验内容:(一)基本实验内容(顺序表):建立顺序表,完成顺序表的基本操作:初始化、插入、删除、逆转、输出、销毁, 置空表、求表长、查找元素、判线性表是否为空;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;分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。
线性表的顺序存储结构
∑
n +1 i =1
p i ( n i + 1)
1 不失一般性,若在线性表的任何位置插入元素都是等概率的,即 p i = 不失一般性,若在线性表的任何位置插入元素都是等概率的, , n + 1 上式可化简为: 上式可化简为: 1 n+1 n
Eis =
∑(n i +1) = 2 n +1
第二章 线性表
2.1 线性表的类型定义 2.2 线性表的顺序表示和实现
2.3 线性表的链式表示和实现
2.4 一元多项式的表示及相加
2.2 线性表的顺序表示和实现 线性表的顺序表示指的 是用一组地址连续的存储单 元依次存储线性表的数据元 素.
£2.2 线性表的顺序存储结构
(1)线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性 ) 表的数据元素.如下图2.1所示 所示: 表的数据元素.如下图 所示: 存储地址 b b+l … b+(i-1)l … b+(n-1)l b+nl … b+(maxlen-1)l 内存状态 a1 a2 … ai … an 空闲 数据元素在线性表中的位序 1 2 … i … n
// 为顺序表分配大小为 maxsize 的数组空间
if (!L.elem) exit(OVERFLOW); L.length = 0; L.listsize = maxsize; return OK; 算法时间复杂度 O(1) 时间复杂度: 时间复杂度 } // InitList_Sq
(4)线性表的插入和删除运算 ) 序号 数据元素 1 2 3 4 5 6 7 8 12 13 21 24 28 30 42 77 (a) 序号 数据元素 1 2 3 4 5 6 7 8 9 12 13 21 24 25 28 30 42 77 (b) 序号 数据元素 1 2 3 4 5 6 7 8 12 13 21 24 28 30 42 77 (a) 序号 数据元素 1 2 3 4 5 6 7 12 13 21 28 30 42 77
第二章基本数据结构及其运算
用这种方法查找,每次比较都可抛弃子表一半的 元素,查找效率较高 从该例可看出,数据元素在表中的排列顺序对查 找效率有很大的影响
例2、学生情况登记表信息查询 成绩在90分及以上的学生情况登记表
学 号 970156 970157 970158 970159 970160 970161 970162 970163 970164 … 姓 名 性 别 年龄 20 张小明 男 19 李小青 女 19 赵 凯 男 21 李启明 男 18 刘 华 女 19 曾小波 女 18 张 军 男 20 王 伟 男 19 胡 涛 男 … … … 成绩 86 83 70 91 78 90 80 65 95 … 学 号 姓 名 性别 男 女 男 女 年龄 21 19 19 17 成绩 91 90 95 93 970159 李启明 970161 曾小波 970164 胡 970168 梅 涛 玲
数据结构主要研究和讨论三方面问题:
1、数据元素之间的固有逻辑关系,称为数据的逻辑结构 2、数据元素及其关系在计算机中的存储方式,称为数据的 物理结构或存储结构
3、施加在数据结构上的操作,称为数据结构的运算。数据处 理的本质就是对数据结构施加各种运算,常见的运算有:查找、 排序、插入、删除等。
主要目的是提高数据处理的效率:
§2.1.3 数据结构的图形表示
D中的数据元素用中间标有元素值的方框表示, 称为数据结点(结点);R中的关系用一条有向线段 从前件结点指向后件结点。
例:设数据元素的集合为D = {di |1≤ i≤ 7的整数},画 出对应于下列关系所构成的数据结构的图形
①、R1={(d1,d3),(d1,d7),(d4,d5),(d3,d6),(d2,d4)} ②、R2={(di,dj)|i+j=5} ③、R3={(d2,d3)(d3,d1),(d1,d4),(d4,d6),d6,d5),(d5,d7)}
大学数据结构复习要点
第一章复习要点是:数据、数据元素、数据结构(包括逻辑结构、存储结构)以及数据类型的概念、数据的逻辑结构分为哪两大类,及其逻辑特征、数据的存储结构可用的四种基本存储方法。
时间复杂度与渐近时间复杂度的概念,如何求算法的时间复杂度。
可能出的题目有选择题、填空题或简答题。
第二章复习要点是:线性表的逻辑结构特征、常见的线性表的基本运算,并可以根据这些基本运算组合得到更复杂的运算。
顺序表的特征、顺序表中结点地址的计算。
顺序表上实现的基本运算(算法):主要是插入和删除的算法。
顺序表的算法应该掌握。
算法时间复杂度要记住。
单链表的特征、图形表示法。
单链表的各种算法实现,并能运用这些算法解决一些简单问题;循环链表的特征、双链表的特征以及它们的主要算法实现。
可能出的题型有:填空题、简答题、应用题和算法题。
第三章复习要点是:栈的定义、其逻辑结构特征、栈的基本运算、栈的上溢、下溢的概念。
队列的逻辑结构,队列的基本运算;循环队列的边界条件处理;以上各种基本运算算法的实现。
算法的简单应用。
可能出的题型有填空、选择、简答、算法等。
第四章复习要点是:串是一种特殊的线性表,它的结点仅由一个字符组成。
空串与空白串的区别:空串是长度为零的串,空白串是指由一个或多个空格组成的串。
串运算的实现中子串定位运算又称串的模式匹配或串匹配。
串匹配中,一般将主串称为目标(串),子串称为模式(串)。
本章可能出的题型多半为选择、填空等。
第五章复习要点是:多维数组和广义表的逻辑结构特征:它们是复杂的非线性结构。
一个数据元素可能有多个直接前趋和多个直接后继。
多维数组的两种顺序存储方式:行优先顺序和列优先顺序。
这两种存储方式下的地址计算方法。
几种特殊矩阵的特征及其压缩存储地址对应关系。
稀疏矩阵的三元组表示(画图形表示)。
广义表是线性表的推广,也是树的推广。
能画出广义表的图形表示法。
广义表的取表头运算与取表尾运算要注意,表头是广义表的第一个元素,它不一定是原子,表尾则必是子表。
数据结构--实验报告 线性表的基本操作
一、实验目的二、实验内容和要求三、源代码1)顺序表的代码2)单链表的代码四、测试结果1)顺序表的测试结果2)单链表的测试结果五、心得体会实验一线性表的基本操作及其应用一、实验目的1、帮助读者复习C++语言程序设计中的知识。
2、熟悉线性表的逻辑结构。
3、熟悉线性表的基本运算在两种存储结构上的实现。
4、掌握顺序表的存储结构形式及其描述和基本运算的实现。
5、熟练掌握动态链表结构及有关算法的设计二、实验内容题目一:顺序表的基本操作[问题描述]实现顺序表的建立、求长度,取元素、修改元素、插入、删除等顺序表的基本操作。
[基本要求](1)依次从键盘读入数据,建立带头结点的顺序表;(2)输出顺序表中的数据元素(3)求顺序表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。
(6)根据算法,将两个有序的顺序表合并成一个有序顺序表。
[测试数据] 由学生任意指定。
题目二:单链表的基本操作[问题描述]实现带头结点的单链表的建立、求长度,取元素、修改元素、插入、删除等单链表的基本操作。
[基本要求](1)依次从键盘读入数据,建立带头结点的单链表;(2)输出单链表中的数据元素(3)求单链表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。
(6)根据算法,将两个有序的单链表合并成一个有序单链表。
[测试数据]由学生任意指定。
三、源代码(一)顺序表的基本操作#include<iostream>using namespace std;#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;typedef int ElemType;#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct { //结构体ElemType *elem;int length;int listsize;}SqList;SqList Lx;Status InitList_Sq(SqList &L) //分配空间{ L.elem=new ElemType[LIST_INIT_SIZE];if(!L.elem)exit(OVERFLOW);L.length =0;L.listsize=LIST_INIT_SIZE;return OK;}Status ListInsert(SqList &L,int i,ElemType e) //插入新元素{ int *q,*p;ElemType *newbase;if(i<1 || i>L.length+1) return ERROR;if(L.length>=L.listsize){ newbase=new ElemType[L.listsize+LISTINCREMENT];if(!newbase) exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}q=&(L.elem[i-1]);for (p=&(L.elem[L.length-1]);p>=q;--p)*(p+1)=*p;*q=e;++L.length;return OK;}Status Listlength(SqList L) //长度{ int *p=L.elem; //判断线形表是否存在while(p){ return (L.length); }}Status GetElem(SqList L, int i,ElemType &e) //取元素{ if(i<1 || i>L.length)return ERROR;else{ e=L.elem[i-1];return e;}}void MergeList(SqList La,SqList Lb,SqList &Lc) //合并{ ElemType ai,bj;InitList_Sq(Lc);int i=1,j=1,k=0;int La_len,Lb_len;La_len=Listlength(La);Lb_len=Listlength(Lb);while((i<=La_len)&&(j<=Lb_len)){ 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);}}void show(SqList L,int i) //显示{ int j;ElemType k;cout<<"顺序表显示如下:"<<endl;for(j=0;j<i-1;j++){ k=L.elem[j];cout<<k<<"->"; }if(j==i-1 && i>0){ k=L.elem[j]; cout<<k; }cout<<endl;}void create(SqList &L,int n) //输入元素{ int e;for(int i=0;i<n;i++)L.elem[i]=e;L.length=i+1; }}Status ListDelete_Sq(SqList &L,int i,ElemType &e) //删除{ ElemType *p, *q;if(i<1 || i>L.length) return ERROR;p=&(L.elem[i-1]);e=*p;q=L.elem+L.length-1;for(++p;p<=q;++p) *(p-1)=*p;--L.length;return OK;}Status Listxiugei(SqList &L,int i,ElemType &e) //修改{ if(i<1 || i>L.length)return ERROR;else{ L.elem[i-1]=e;return OK; }}void shuru(SqList &L1) //顺序表的创建{ int a;InitList_Sq(L1);cout<<"请输入顺序表的长度:";cin>>a;cout<<"请输入顺序表的元素(共"<<a<<"个)"<<endl;create(L1,a);show(L1,a);}void chaxun(SqList &L1) //取第i个位置的元素{ int j;ElemType e1;cout<<"请选择所要取出元素的位置:";while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>j; }GetElem(L1,j,e1);cout<<"取出的元素为:"<<e1<<endl; }void xiugai(SqList &L1) //修改第i个位置的元素{ int a;int j; ElemType e1;a=L1.length;cout<<"请选择所要修改元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要修改元素的位置:";cin>>j; }cout<<"要修改成的元素:";cin>>e1;Listxiugei(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a);}void shanchu(SqList &L1) //删除顺序表里的元素{ int a;int j; ElemType e1;a=L1.length;cout<<"请选择所要删除元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>j; }ListDelete_Sq(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a-1);}void charu(SqList &L1) //插入元素到顺序表里{ int a; int j; ElemType e1;a=L1.length;cout<<"请选择所要插入元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>j; }cout<<"要插入的元素:";cin>>e1;ListInsert(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a+1);}void hebing(SqList &L3) //合并两个顺序表{ SqList L1,L2;int a,b;InitList_Sq(L1); InitList_Sq(L2);cout<<"请输入第一个有序表的长度:"; cin>>a;cout<<"请输入第一个有序表的元素(共"<<a<<"个)"<<endl;create(L1,a);show(L1,a);cout<<"请输入第二个有序表的长度:"; cin>>b;cout<<"请输入第二个有序表的元素(共"<<b<<"个)"<<endl;create(L2,b);show(L2,b);MergeList(L1,L2,L3);cout<<"合并后的有序表如下:"; show(L3,a+b);}void main() //主菜单{ int choice;for(;;){ cout<<" 顺序表的基本操作"<<endl;cout<<" 1.顺序表的创建"<<endl;cout<<" 2.顺序表的显示"<<endl;cout<<" 3.顺序表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到顺序表里"<<endl;cout<<" 7.删除顺序表里的元素"<<endl;cout<<" 8.合并两个顺序表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择:";cin>>choice;switch(choice){ case 1: shuru(Lx);break;case 2: show(Lx,Lx.length);break;case 3: cout<<"顺序表的长度:"<<Listlength(Lx)<<endl;break; case 4: chaxun(Lx);break;case 5: xiugai(Lx);break;case 6: charu(Lx);break;case 7: shanchu(Lx);break;case 8: hebing(Lx);break;case 9: cout<<"退出系统!"<<endl;exit(0);break;default : cout<<"输入有误,请重新选择"<<endl;break; }}}(二)单链表的基本操作#include<iostream>using namespace std;#define true 1#define false 0#define ok 1#define error 0#define overflow -2typedef int Status;typedef int ElemType;typedef struct LNode //存储结构{ ElemType data;struct LNode *next;}LNode,*LinkList;void CreateList(LinkList &L,int n) //尾插法创建单链表{ LinkList p;L=new LNode;L->next=NULL; //建立一个带头结点的单链表LinkList q=L; //使q指向表尾for(int i=1;i<=n;i++){ p=new LNode;cin>>p->data;p->next=NULL;q->next=p;q=p; }}Status GetElem(LinkList L,int i,ElemType &e)//取第i个元素{ LinkList p=L->next;int j=1;while(p&&j<i){ p=p->next;++j; }if(!p||j>i) return error; //第i个元素不存在 e=p->data;return ok;}Status LinkInsert(LinkList &L,int i,ElemType e) //插入{ LinkList p=L;int j=0;while(p&&j<i-1){ p=p->next;++j; } //寻找第i-1个结点 if(!p||j>i-1)return error; //i小于1或者大于表长加1 LinkList s=new LNode; //生成新结点s->data=e;s->next=p->next; //插入L中p->next=s;return ok;}Status ListDelete(LinkList &L,int i,ElemType &e) // 删除{ LinkList p=L;LinkList q;int j=0;while(p->next&&j<i-1){ //寻找第i个结点,并令p指向其前驱p=p->next;++j; }if(!(p->next)||j>i-1) return error; //删除位置不合理q=p->next;p->next=q->next; //删除并释放结点e=q->data;delete(q);return ok;}void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc) { //合并两个顺序链表LinkList pa,pc,pb;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){ if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next; }else{ pc->next=pb;pc=pb;pb=pb->next; }}pc->next=pa?pa:pb;delete(Lb);}void show(LinkList L) //显示{ LinkList p;p=L->next;while(p){ cout<<p->data<<"-->";p=p->next; }cout<<endl;}int Length(LinkList L,int i) //表长{ i=0;LinkList p=L->next;while(p){ ++i;p=p->next; }return i;}void xiugai(LinkList L) //修改{ int i,j=1;ElemType k;ElemType e,m;LinkList p=L->next;cout<<"请输入要修改的元素位置(0<i<length):";cin>>i;GetElem(L,i,e);cout<<"该位置的元素:"<<e<<endl;cout<<"修改后的元素值:";cin>>k;while(p&&j<i){ p=p->next;++j; }m=p->data;p->data=k;cout<<"修改后的单链表显示如下:"<<endl;show(L);}void hebing() //合并两个单链表{ int a,b;LinkList La,Lb,Lc;cout<<"请输入第一个有序链表的长度:"<<endl;cin>>a;cout<<"请输入第一个有序链表的元素共("<<a<<"个):"<<endl;CreateList(La,a);show(La);cout<<"请输入第二个有序链表的长度:"<<endl;cin>>b;cout<<"请输入第二个有序链表的元素共("<<b<<"个):"<<endl;CreateList(Lb,b);show (Lb);MergeList(La,Lb,Lc);cout<<"合并后的有序链表如下:"<<endl;show(Lc);}void main() //主函数{ int select;int x;ElemType y;LinkList list;for(;;){ cout<<" 单链表的基本操作"<<endl;cout<<" 1.单链表的创建"<<endl;cout<<" 2.单链表的显示"<<endl;cout<<" 3.单链表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到单链表里"<<endl;cout<<" 7.删除单链表里的元素"<<endl;cout<<" 8.合并两个单链表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择:";cin>>select;switch(select){ case 1:cout<<"请输入单链表的长度:"<<endl;cin>>x;cout<<"请输入"<<x<<"个元素"<<endl;CreateList(list,x);break;case 2: cout<<"单链表显示如下:"<<endl;show(list);break;case 3: int s;cout<<"单链表的长度为:"<<Length(list,s)<<endl;break;case 4: cout<<"请选择所要取出元素的位置:";while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>x; }GetElem(list,x,y);cout<<"该位置的元素为:"<<y<<endl;break;case 5: xiugai(list); break;case 6: cout<<"请选择要插入的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>x; }cout<<"要插入的元素值:";cin>>y;LinkInsert( list,x,y);cout<<"插入后单链表显示如下:"<<endl;show(list);break;case 7: cout<<"请选择要删除的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>x; }ListDelete(list,x,y);cout<<"要删除的元素值:"<<y<<endl;cout<<"删除后的单链表显示如下:"<<endl;show(list);break;case 8: hebing();break;case 9: exit(0);default : cout<<"输入有误,请重新输入"<<endl;break;}}}四、测试结果1)顺序表的测试结果2)单链表的测试结果五、心得体会当听到老师说写数据结构实验报告时,我有点惊讶,才学了不到一个月,就要写实验报告。
第2章 线性表
【例2】巳知有两个按元素值递增有序的顺序表La和 Lb,设计一个算法将表La和表Lb的全部元素归并 为一个按元素值递增有序的顺序表Lc。
算法思路:用i扫描顺序表La,用j扫描顺序表Lb。 当表La和表Lb都未扫描完时,比较两者的当前元 素,将较小者插入表Lc的表尾,若两者的当前元 素相等,则将这两个元素依次插入表Lc的表尾。 最后,将尚为扫描完的顺序表的余下部分元素依 次插入表Lc的表尾。算法如下: void MergeList_Sq(SqList La, SqList Lb, SqList &Lc)
表中ai-1领先于ai,称ai-1是ai的直接前驱,ai+1是 ai的直接后继。
线性表的抽象数据类型定义 (参见教材)
返回本章目录
2.2 线性表的顺序存储结构
线性表的顺序存储是指在内存中用地址连续的一块存储空间 依次存放线性表的数据元素,用这种存储形式存储的线性表 称其为顺序表。 假设每个数据元素占d个存储单元,且将ai的存储地址表示为 Loc(ai),则有如下关系: Loc(ai)=Loc(a1)+(i-1)*d Loc(a1)是线性表的第一个数据元素a1的存储地址,通常 称作线性表的基地址。
【例1】 编写一算法,从顺序表中删除自第i个元素开 始的k个元素。 算法思路: 为保持顺序表的逻辑特性,需将i+k ~ n位 置的所有元素依次前移k个位置。算法如下:
int deleteK(Sqlist &sq,int i,int k)
{ if (i<1||k<1||i+k-1>sq.len) return 0; for (j=i+k-1;j<=sq.len-1;j++) sq.data[j-k]=sq.data[j]; sq.len-=k; return 1; }// deleteK
实验一顺序表的基本操作实验报告
元素之后的所有数据都前移一个位置,最将线性表长减1。
3.顺序表查找操作的基本步骤:要在顺序表中查找一个给定值的数据元素则可以采用顺序查找的方法,从表中第 1 个数据元素开始依次将值与给定值进行比较,若相等则返回该数据元素在顺序表中的位置,否则返回0 值。
线性表的动态分配顺序存储结构—C语言实现#define MaxSize 50//存储空间的分配量Typedef char ElemType;Typedef struct{ElemType data[MaxSize];int length; //表长度(表中有多少个元素)}SqList;动态创建一个空顺序表的算法:void InitList(SqList *&L) //初始化线性表{L=(SqList *)malloc(sizeof(SqList)); //分配存放线性表的空间L->length=0; //置空线性表长度为0}线性表的插入:status Sqlist_insert(Sqlist &L,int i,Elemtype x)/*在顺序表L中第i个元素前插入新元素x*/{ if (i<1||i>L.length+1) return ERROR; /*插入位置不正确则出错*/if (L.length>=MAXLEN)return OVERFLOW;/*顺序表L中已放满元素,再做插入操作则溢出*/for(j=L.length-1;j>=i-1;j--)L.elem[j+1]=L.elem[j]; /*将第i个元素及后续元素位置向后移一位*/L.elem[i-1]=x; /*在第i个元素位置处插入新元素x*/L.length++; /*顺序表L的长度加1*/return OK;}线性表的删除:status Sqlist_delete(Sqlist &L,int i,Elemtype &e)/*在顺序表L中删除第i个元素*{ if (i<1||i>L.length) return ERROR; /*删除位置不正确则出错*/for(j=i;j<=L.length-1;j++)L.elem[j-1]=L.elem[j]; /*将第i+1个元素及后继元素位置向前移一位*/L.length--;/*顺序表L的长度减1*/return OK;}线性表元素的查找:int LocateElem(SqList *L, ElemType e) //按元素值查找{int i=0;while (i<L->length && L->data[i]!=e)i++; //查找元素eif (i>=L->length) //未找到时返回0return 0;elsereturn i+1; //找到后返回其逻辑序号}输出线性表:void DispList(SqList *L) //输出线性表{int i;if (ListEmpty(L)) return;for (i=0;i<L->length;i++)printf("%c ",L->data[i]);printf("\n");}输出线性表第i个元素的值:bool GetElem(SqList *L,int i,ElemType &e)//求线性表中某个数据元素值{if (i<1 || i>L->length)return false; //参数错误时返回falsee=L->data[i-1]; //取元素值return true; //成功找到元素时返回true}代码:#include <stdio.h>#include <malloc.h>#define MaxSize 50typedef char ElemType;typedef struct{ElemType data[MaxSize];int length;} SqList;void InitList(SqList *&L);void DestroyList(SqList *L);bool ListEmpty(SqList *L);int ListLength(SqList *L);void DispList(SqList *L);bool GetElem(SqList *L,int i,ElemType &e);int LocateElem(SqList *L, ElemType e);bool ListInsert(SqList *&L,int i,ElemType e);bool ListDelete(SqList *&L,int i,ElemType &e);void InitList(SqList *&L)//初始化线性表{L=(SqList *)malloc(sizeof(SqList));//分配存放线性表的空间L->length=0;//置空线性表长度为0 }void DestroyList(SqList *L)//销毁线性表{free(L);}bool ListEmpty(SqList *L)//判线性表是否为空表{return(L->length==0);}int ListLength(SqList *L)//求线性表的长度{return(L->length);}void DispList(SqList *L)//输出线性表{int i;if (ListEmpty(L)) return;for (i=0;i<L->length;i++)printf("%c ",L->data[i]);printf("\n");}bool GetElem(SqList *L,int i,ElemType &e)//求线性表中某个数据元素值{if (i<1 || i>L->length)return false;//参数错误时返回falsee=L->data[i-1];//取元素值return true;//成功找到元素时返回true}int LocateElem(SqList *L, ElemType e)//按元素值查找{int i=0;while (i<L->length && L->data[i]!=e)i++;//查找元素eif (i>=L->length)//未找到时返回0return 0;elsereturn i+1;//找到后返回其逻辑序号}bool ListInsert(SqList *&L,int i,ElemType e)//插入数据元素{int j;if (i<1 || i>L->length+1)return false;//参数错误时返回falsei--;//将顺序表逻辑序号转化为物理序号for (j=L->length;j>i;j--)//将data[i]及后面元素后移一个位置L->data[j]=L->data[j-1];L->data[i]=e;//插入元素eL->length++;//顺序表长度增1return true;//成功插入返回true}bool ListDelete(SqList *&L,int i,ElemType &e)//删除数据元素{int j;if (i<1 || i>L->length)//参数错误时返回falsereturn false;i--;//将顺序表逻辑序号转化为物理序号e=L->data[i];for (j=i;j<L->length-1;j++)//将data[i]之后的元素前移一个位置L->data[j]=L->data[j+1];L->length--;//顺序表长度减1return true;//成功删除返回true}void main(){SqList *L;ElemType e;printf("顺序表的基本运算如下:\n");printf(" (1)初始化顺序表L\n");InitList(L);printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");ListInsert(L,1,'a');ListInsert(L,2,'b');ListInsert(L,3,'c');ListInsert(L,4,'d');ListInsert(L,5,'e');printf(" (3)输出顺序表L:");DispList(L);printf(" (4)顺序表L长度=%d\n",ListLength(L));printf(" (5)顺序表L为%s\n",(ListEmpty(L)?"空":"非空"));GetElem(L,3,e);printf(" (6)顺序表L的第3个元素=%c\n",e);实验结果:心得体会:通过本次实验,实现了数据结构在程序设计上的作用,了解了数据结构语言,加深了对c语言的认识掌并掌握了线性表的顺序存储结构的表示和实现方法,掌握顺序表基本操作的算法实现,同时了解了顺序表的应用。
1.3 线性表及其顺序存储结构
1.3 线性表及其顺序存储结构1.3.1 线性表的基本概念1.线性表的定义在数据结构中,线性表(Linear List)是最简单也是最常用的一种数据结构。
线性表是由n(n≥0)个数据元素a1, a2, …, a n组成的有限序列。
其中,数据元素的个数n定义为表的长度。
当n=0时称为空表,记作( )或 ,若线性表的名字为L,则非空的线性表(n>0)记作:L=(a1,a2,…,a n)这里a i(i=1,2,…,n)是属于数据对象的元素,通常也称其为线性表中的一个结点。
线性表的相邻元素之间存在着前后顺序关系,其中第一个元素无前驱,最后一个元素无后继,其他每个元素有且仅有一个直接前驱和一个直接后继。
可见,线性表是一种线性结构。
例如,英文字母表(A, B, C, …, Z)就是一个长度为26的线性表,表中的每一个英文字母是一个数据元素,四季(春、夏、秋、冬)是一个长度为4的线性表,其中每一个季节是一个数据元素。
矩阵也是一个线性表,只不过它是一个比较复杂的线性表。
在矩阵中,既可以把每一行看成一个数据元素(既每一行向量为一个数据元素),也可以把每一列看成一个数据元素(即每一列向量为一个数据元素)。
其中每一个数据元素(一个行向量或者一个列向量)实际上又是一个简单的线性表。
在复杂的线性表中,一个数据元素由若干数据项组成,此时,把数据元素称为记录(record),而由多个记录构成的线性表又称为文件(file)。
例如,一个按照姓名的拼音字母为序排列的通信录就是一个复杂的线性表,见表1-4,表中每个联系人的情况为一个记录,它由姓名、性别、电话号码、电子邮件和住址5个数据项组成。
表1-4 复杂线性表2.非空线性表的特征非空线性表具有以下一些结构特征:●有且只有一个根结点,它无前件;●有且只有一个终端结点,它无后件;●除根结点与终端结点外,其他所有结点有且只有一个前件,也有且只有一个后件。
结点个数n称为线性表的长度,当n=0时,称为空表。
基本数据结构和算法
1.基本数据结构与算法1.1算法算法:是指解题方案的准确而完整的描述。
特征包括:(1)可行性;(2)确定性,(3)有穷性,(4)拥有足够的情报。
算法的基本要素:一是对数据对象的运算和操作;二是算法的控制结构。
指令系统:一个计算机系统能执行的所有指令的集合。
基本运算和操作包括:算术运算、逻辑运算、关系运算、数据传输。
算法的控制结构:顺序结构、选择结构、循环结构。
算法基本设计方法:列举法、归纳法、递推、递归、减斗递推技术、回溯法。
算法复杂度:算法时间复杂度和算法空间复杂度。
算法时间复杂度是指执行算法所需要的计算工作量。
算法空间复杂度是指执行这个算法所需要的内存空间。
数据的存储结构有顺序、链接、索引等。
线性结构条件:(1)有且只有一个根结点;(2)每一个结点最多有一个前件,也最多有一个后件。
非线性结构:不满足线性结构条件的数据结构。
1.3线性表及其顺序存储结构非空线性表的结构特征:(1)且只有一个根结点a1,它无前件;(2)有且只有一个终端结点an,它无后件;(3)除根结点与终端结点外,其他所有结点有且只有一个前件,也有且只有一个后件。
结点个数n称为线性表的长度,当n=0时,称为空表。
线性表的顺序存储结构具有以下两个基本特点:(1)线性表中所有元素的所占的存储空间是连续的;(2)线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。
顺序表的运算:插入、删除。
1.4栈和队列a)栈是限定在一端进行插入与删除的线性表,允许插入与删除的一端称为栈顶,不允许插入与删除的另一端称为栈底。
栈按照“先进后出"(FILO)或“后进先出"(LIFO)组织数据,栈具有记忆作用。
用top表示栈顶位置,用bottom表示栈底。
栈的基本运算:(1)插入元素称为入栈运算;(2)删除元素称为退栈运算;(3)读栈顶元素是将栈顶元素赋给一个指定的变量,此时指针无变化。
b)队列是指允许在一端(队尾)进入插入,而在另一端(队头)进行删除的线性表。
数据结构实验报告-实验一顺序表、单链表基本操作的实现
数据结构实验报告-实验⼀顺序表、单链表基本操作的实现实验⼀顺序表、单链表基本操作的实现l 实验⽬的1、顺序表(1)掌握线性表的基本运算。
(2)掌握顺序存储的概念,学会对顺序存储数据结构进⾏操作。
(3)加深对顺序存储数据结构的理解,逐步培养解决实际问题的编程能⼒。
l 实验内容1、顺序表1、编写线性表基本操作函数:(1)InitList(LIST *L,int ms)初始化线性表;(2)InsertList(LIST *L,int item,int rc)向线性表的指定位置插⼊元素;(3)DeleteList1(LIST *L,int item)删除指定元素值的线性表记录;(4)DeleteList2(LIST *L,int rc)删除指定位置的线性表记录;(5)FindList(LIST *L,int item)查找线性表的元素;(6)OutputList(LIST *L)输出线性表元素;2、调⽤上述函数实现下列操作:(1)初始化线性表;(2)调⽤插⼊函数建⽴⼀个线性表;(3)在线性表中寻找指定的元素;(4)在线性表中删除指定值的元素;(5)在线性表中删除指定位置的元素;(6)遍历并输出线性表;l 实验结果1、顺序表(1)流程图(2)程序运⾏主要结果截图(3)程序源代码#include<stdio.h>#include<stdlib.h>#include<malloc.h>struct LinearList/*定义线性表结构*/{int *list; /*存线性表元素*/int size; /*存线性表长度*/int Maxsize; /*存list数组元素的个数*/};typedef struct LinearList LIST;void InitList(LIST *L,int ms)/*初始化线性表*/{if((L->list=(int*)malloc(ms*sizeof(int)))==NULL){printf("内存申请错误");exit(1);}L->size=0;L->Maxsize=ms;}int InsertList(LIST *L,int item,int rc)/*item记录值;rc插⼊位置*/ {int i;if(L->size==L->Maxsize)/*线性表已满*/return -1;if(rc<0)rc=0;if(rc>L->size)rc=L->size;for(i=L->size-1;i>=rc;i--)/*将线性表元素后移*/L->list[i+=1]=L->list[i];L->list[rc]=item;L->size++;return0;}void OutputList(LIST *L)/*输出线性表元素*/{int i;printf("%d",L->list[i]);printf("\n");}int FindList(LIST *L,int item)/*查找线性元素,返回值>=0为元素的位置,返回-1为没找到*/ {int i;for(i=0;i<L->size;i++)if(item==L->list[i])return i;return -1;}int DeleteList1(LIST *L,int item)/*删除指定元素值得线性表记录,返回值为>=0为删除成功*/ {int i,n;for(i=0;i<L->size;i++)if(item==L->list[i])break;if(i<L->size){for(n=i;n<L->size-1;n++)L->list[n]=L->list[n+1];L->size--;return i;}return -1;}int DeleteList2(LIST *L,int rc)/*删除指定位置的线性表记录*/{int i,n;if(rc<0||rc>=L->size)return -1;for(n=rc;n<L->size-1;n++)L->list[n]=L->list[n+1];L->size--;return0;}int main(){LIST LL;int i,r;printf("list addr=%p\tsize=%d\tMaxsize=%d\n",LL.list,LL.size,LL.Maxsize);printf("list addr=%p\tsize=%d\tMaxsize=%d\n",LL.list,LL.list,LL.Maxsize);while(1){printf("请输⼊元素值,输⼊0结束插⼊操作:");fflush(stdin);/*清空标准输⼊缓冲区*/scanf("%d",&i);if(i==0)break;printf("请输⼊插⼊位置:");scanf("%d",&r);InsertList(&LL,i,r-1);printf("线性表为:");OutputList(&LL);}while(1){printf("请输⼊查找元素值,输⼊0结束查找操作:");fflush(stdin);/*清空标准输⼊缓冲区*/scanf("%d ",&i);if(i==0)break;r=FindList(&LL,i);if(r<0)printf("没有找到\n");elseprintf("有符合条件的元素,位置为:%d\n",r+1);}while(1){printf("请输⼊删除元素值,输⼊0结束查找操作:");fflush(stdin);/*清楚标准缓存区*/scanf("%d",&i);if(i==0)break;r=DeleteList1(&LL,i);if(i<0)printf("没有找到\n");else{printf("有符合条件的元素,位置为:%d\n线性表为:",r+1);OutputList(&LL);}while(1){printf("请输⼊删除元素位置,输⼊0结束查找操作:");fflush(stdin);/*清楚标准输⼊缓冲区*/scanf("%d",&r);if(r==0)break;i=DeleteList2(&LL,r-1);if(i<0)printf("位置越界\n");else{printf("线性表为:");OutputList(&LL);}}}链表基本操作l 实验⽬的2、链表(1)掌握链表的概念,学会对链表进⾏操作。
数据结构——线性表(选择题)
1.线性表是()。
简单,线性表的概念与性质,02702001 [单选题]A、一个有限序列,可以为空(正确答案)B、一个无限序列,不可以为空C、一个无限序列,可以为空D、一个无限序列,不可以为空2.在一个长度为n 的顺序表中删除第i 个元素(0<=i<=n)时,需向前挪移()个元素。
简单,线性表顺序存储实现,02702003 [单选题]A 、n-i(正确答案)B 、n-i+1C 、n-i-1D 、i3.线性表采用链式存储时,其地址()。
简单,线性表的链式存储原理,02702004 [单选题]A、必须是连续的B、一定是不连续的C、部份地址必须是连续的D、连续与否均可以(正确答案)4.从一个具有n 个结点的单链表中查找其值等于x 的结点时,在查找成功的情况下,需平均比较()个元素结点。
普通,链式存储的实现,02702005 [单选题]A 、n/2B 、nC 、(n+1)/2(正确答案)D 、(n-1)/25.在双向循环链表中p 所指的结点之后插入s 指针所指向的结点,其操作是()。
普通,循环链表实现,02702022 [单选题]A 、p->next=s; s->prior=p; p->next->prior=s; s->next=p->next;B 、s->prior=p; s->next=p->next; p->next=s; p->next->prior=s;C 、p->next=s; p->next->prior=s; s->prior=p; s->next=p->next;D 、s->prior=p; s->next=p->next; p->next->prior=s; p->next=s; (正确答案)6.设单链表中指针p 指向结点m,若要删除m 之后的结点(若存在),则需修改指针的操作为()。
数据结构之线性表详细解答
二章线性表线性表是最简单、最基本、也是最常用的一种线性结构。
它有两种存储方法:顺序存储和链式存储,它的主要基本操作是插入、删除和检索等。
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是给定的一个数据元素。
第3章线性表概要
链式存储的几种形式
单链表 循环链表 双向链表
单链表的定义
typedef int DataType; class Item { public: DataType data; Item * next; Item(){next=NULL;} };
class Link { public: Item *head; Link(){head=NULL;} ~Link(){DeleteAll();} void Initiate(); void DeleteAll(); void HeadCreate(int n); void TailCreate(int n); void HeadCreateWithHead(int n); void TailCreateWithHead(int n); int Length(); Item *Locatex(DataType x); Item *Locatei(int i); DataType Get(int i); bool Insert(DataType x,int i); bool Deleted(int i); void Print(); };
Ein P i (n i 1)
i 1
n 1
在等概率情况下,Pi=1/(n+1),则
1 n1 n Ein P (n i 1) i (n i 1) n 1 i 1 2 i 1
n 1
时间复杂度为O(n)
典型操作的算法实现
3. 删除运算
线性表的删除运算是指将表中第i个元素从线性表中删除, 使原表长为n的线性表(a1,a2,…,ai-1,ai,ai+1,…, an)变成表长为n-1的线性表 (a1,a2,…,ai-1,ai+1,…,an) i的取值范围为1≤i≤n。
数据结构课件之线性表(ppt 86页)
删除算法
int DelList(SeqList *L,int i,ElemType *e)
/*在顺序表L中删除第i个数据元素,并用指针参数e返回其值*/
{ int k;
if((i<1)||(i>L->last+1))
{ printf(“删除位置不合法!”); return(ERROR); }
*e= L->elem[i-1]; /* 将删除的元素存放到e所指向的变量中*/
loc(ai) =loc(a1)+(i-1)×k
8
15.10.2019
顺序存储结构示意图
存储地址
Loc(a1) Loc(a1)+(2-1)k
…
loc(a1)+(i-1)k
…
loc(a1)+(n-1)k
...
loc(a1)+(maxlen-1)k
内存空间状态
a1 a2
…
ai
…
an
9
逻辑地址
1 2
…
i
操作前提:L为未初始化线性表。 操作结果:将L初始化为空表。 操作前提:线性表L已存在。 操作结果:将L销毁。 操作前提:线性表L已存在 。 操作结果:将表L置为空表。
………
}ADT LinearList
6
15.10.2019
2.2 线性表的顺序存储
2.2.1 线性表的顺序存储结构 2.2.2 线性表顺序存储结构上的基本运算
17
15.10.2019
删除算法示意
将线性表(4,9,15,21,28,30,30,42,51,62)中的第5个元素 删除。
序号
1 2 3 4 5 6 7 8 9 10 4 9 15 21 28 30 30 42 51 62
2.2 线性表及其顺序存储结构
一般情况下,要删除第i (1≤i≤n )个 元素,需要从第i+1 个元素开始,直到第n 个元素之间,共有n-i 个元素依次向前移动 了一个位置。删除结束后,顺序表的长度就 缩小了1。在平均情况下,要在顺序表中删 除一个元素,需要移动表中一半的元素。
在顺序表L中删除第i个元素并用x 返回其 值的算法DeleteList描述如下:
void DeleteList(SeqList *L,int i, ElemType *x) {
int j,n=L->length; if(i<1||i>n) {
printf(" \n i值不合法!"); exit(1); }
在顺序表中删除一个元素,平均约移动表 中一半的元素。平均时间复杂度为O(n)。最 好的情况是当i=n,即在表尾删除时,不需要 移动元素;最坏的情况是当i=1,即在表头删 除时,需要移动表中n-1个元素。
栈和队列是两种特殊的线性表,它们的逻 辑结构和线性表相同,只是运算规则较线 性表有更多的限制 。
在表中插入一个元素,平均要移动一半的元 素,平均时间复杂度为O(n)。最好的情况是
在表尾插入时,不需要移动元素;最坏的情况 是在表头插入时,需要移动表中n个元素。
假设,在长度为n的顺序表的任意位置i (1≤i≤n)删除该位置元素的概率为qi=1/n, 所需移动元素的次数为n-i,那么,每删除一 个元素,所需移动元素的次数的平均值为: Ade = (n-1)/2
ElemType GetElem(SeqList *L,int i) {/*取表中第i个数据元素*/
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验项目名称:线性表的顺序存储结构上的基本运算
(所属课程:数据结构--用C语言描述)
院系:计算机科学与信息工程学院专业班级:网络工程
姓名:000000 学号:0000000000 实验日期:2016.10.20 实验地点:A-06 406 合作者:指导教师:孙高飞
本实验项目成绩:教师签字:日期:
(以下为实验报告正文)
一、实验目的
本次实验的目的掌握顺序表的存储结构形式及其描述和基本运算的实现;掌握动
态链表结构及相关算法设计
实验要求:输入和验证程序例题。
正确调试程序,记录程序运行结果。
完成实验报
告。
二、实验条件
Windows7系统的电脑,vc++6.0软件,书本《数据结构--用c语言描述》
三、实验内容
3.1 根据41页代码,用c语言定义线性表的顺序存储结构。
3.2 根据42页算法2.1实现顺序表的按内容查找。
3.3 根据43页算法2.2实现顺序表的插入运算。
3.4 根据45页算法2.3实现顺序表的删除运算。
四、实验步骤
3.2实验步骤
(1)编写头文件,创建ElemType。
(2)根据根据41页代码,“用c语言定义线性表的顺序存储结构”定义顺序表。
(3)根据42页算法2.1实现顺序表的按内容查找,创建Locate函数。
(4)创建main函数,输入SeqList L的数据元素。
(5)输入要查找的数据元素的值,调用Locate函数,输出结果。
3.3实验步骤
(1)编写头文件,创建ElemType。
(2)根据41页代码,“用c语言定义线性表的顺序存储结构”定义顺序表。
(3)根据43页算法2.2实现顺序表的插入运算,创建InsList函数。
(4)创建printList函数,逐项输出顺序表内的元素及顺序表元素的个数。
(5)创建main函数,输入插入的元素和其位置,调用printLinst函数输出顺序表,调用IntList函数,再次调用printLinst函数输出顺序表。
3.4实验步骤
(1)编写头文件,创建ElemType。
(2)根据根据41页代码,“用c语言定义线性表的顺序存储结构”定义顺序表。
(3)根据45页算法2.3实现顺序表的删除运算,创建DelList函数。
(4)创建printList函数,逐项输出顺序表内的元素及顺序表元素的个数。
(5)创建main函数,输入删除元素的位置,调用printLinst函数输出顺序表,调用DelList函数,再次调用printLinst函数输出顺序表。
五、实验结果
(1)实验3.2顺序表的按内容查找
# include <stdio.h>
typedef int Elemtype;
typedef struct{
Elemtype elem[100];
int last;
}SeqList;
int Locate(SeqList L,Elemtype e){
int i;
i=0;
while((i<=st)&&(L.elem[i]=e)) i++;
if(i<=st)
return(i+1);
else
return(-1);
}
void main(){
SeqList s={{1,2,3,6,8,10,5,3},7};
int e=5;
int pos=Locate(s,e);
printf("Locate to %d\n",pos);
}
(2)实验3.3顺序表的插入运算
# include <stdio.h>
typedef int Elemtype;
typedef struct{
Elemtype elem[100];
int last;
}SeqList;
#define OK 1
#define ERROR 0
int IntList(SeqList*L,int i,Elemtype e) {
int k;
if((i<1)||(i>L->last+2))
{
printf("插入位置i值不合法");
return(ERROR);
}
if(L->last>=100-1)
{
printf("表已满,无法插入");
return(ERROR);
}
for(k=L->last;k>=i-1;k--)
L->elem[k+1]=L->elem[k];
L->elem[i-1]=e;
L->last++;
return(OK);
}
void printList(SeqList s)
{
for(int i=0;i<=st;i++)
printf("%d\t",s.elem[i]);
printf("\n");
}
void main(){
SeqList L={{1,2,4,6,8,10,5,11},8};
printList(L);
IntList(&L,3,10);
printList(L);
}
(3)实验3.4顺序表的删除运算
# include <stdio.h>
typedef int Elemtype;
typedef struct{
Elemtype elem[100];
int last;
}SeqList;
int DelList(SeqList * L,int i,ElemType * e) {
int k;
if((i<=1)||(i>L->last+1))
{
printf("删除位置不合法!");
return(ERROR);
}
* e=L->elem[i-1];
for(k=i;i<=L->last;k++)
L->elem[k-1]=L->elem[k];
L->last--;
return(OK);
}
void printList(SeqList s){ printf("%d",st);
for (int i=0;i<=st;i++){
printf("%d\t",s.elem[i]);
}
printf("\n");
}
void main(){
SeqList L={{1,2,9,8,4,5,3,6,2},9};
int * h;
printList(L);
DelList(&L,3,h);
printList(L);
}
六、讨论
1.在实现顺序表的插入与删除运算时,不懂的创建printList函数,把顺序表的元素逐项输出。
2.在实现3个算法时,不会编写main函数。
3.在编写程序时,在语法上出现了很多错误,包括一些细节问题。
七、参考文献
列举自己在本次准备实验、进行实验和撰写实验报告过程中用到的参考文献资料。
格式如下:
耿国华张德全周明全等编著,《数据结构--用C语言描述》,高等教育出版社,2015年7月,41-45页。