C语言数据结构基础学习笔记——基础线性表
线性表是指具有相同数据类型的n(n>=0)个数据元素的有限序列,它具有一个表头元素和一个表尾元素,并且每一个数据元素最多只有一个直接前驱和一个直接后继。
线性表的顺序存储也叫作顺序表,它的特性是地址连接、依次存储。
顺序表的定义有静态建表和动态建表两种。
静态建表的实现方法为:
#define MaxSize 50 //定义线性表的最大长度
typedef int ElemType; //假定表中元素类型是int
typedef struct{
ElemType data[MaxSize]; //顺序表的元素(数组)
int length; //顺序表的当前长度
}SqList;
动态建表的实现方法为:
typedef int ElemType;
typedef struct{
ElemType *data; //指示动态分配数组的指针
int MaxSize,length; //数组的最大容量个当前个数
}SeqList;
在动态建表中,内存的分配语句为:
#define InitSize 100
SeqList L;
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
描述或定义一个顺序表需要:①存储空间的起始位置;②顺序表的最大存储量;③顺序表当前的长度。
对于顺序表第i位置插入值e操作实现:
bool ListInsert(SqList&L,int i,ElemType e){
if(i<||i>L.length+) return false; //判断i的范围是否有效
if(L.length>=MaxSize) return false; //当前存储空间已满,不能插入
for(int j=L.length;j>=i;j--) L.data[j]=L.data[j-]; //将第i个元素及之后的元素后移
L.data[i-]=e;
L.length++;
return true;
}
对于顺序表第i位置删除值操作实现:
bool ListDel(SqList &L,int i,ElemType &e){
if(i<||i>L.length) return false; //判断i的范围是否有效
e=L.data[i-]; //将被删除的元素赋值给e
for(int j=i;j<L.length;j++) L.data[j-i]=L.data[j]; //将第i个位置之后的元素前移
L.length--;
return true;
}
根据数组的特性,如果想向顺序表中进行插入和删除的操作时需要移动插入/删除点后的所有值,浪费了很多的系统资源。同时,存储顺序表需要一大块连续的地址空间,使得空间利用率下降。因此,我们引入链式存储的线性表,也叫作链表。
对于链表中最简单的单链表,其定义为:
typedef struct LNode{ //定义单链表节点类型
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
对于一个新建立的单链表,向其中加入结点有两种方法:
①头插法建立单链表:将新结点插入到当前链表的表头(向前建表);
LinkList CreatList1(LinkList &L){
LNode *s; //辅助指针
int x; //存储插入结点数据的值
L=(LinkList)malloc(sizrof(LNode)); //创建头结点
L->next=NULL; //初始为空链表
scanf("%d",&x); //输入结点的值
while(x!=){ //输入9999表示结束
s=(LNode*)malloc(sizeof(LNode)); //创建新的结点
s->data=x; //对新结点的数据赋值
s->next=L->next; //新结点的后继指向第一个结点
L->next=s; //头结点的后继指向新结点
scanf("%d",&x); //读入下一个结点值
}
return L;
}
②尾插法建立单链表:将新结点插入到当前链表的表尾(向后建表);
LinkList CreatList1(LinkList &L){
int x; //存储插入结点数据的值
L=(LinkList)malloc(sizrof(LNode)); //创建头结点
LNode *s,*r=L; //辅助指针,r为表尾指针
scanf("%d",&x); //输入结点的值
while(x!=){ //输入9999表示结束
s=(LNode*)malloc(sizeof(LNode)); //创建新的结点
s->data=x; //对新结点的数据赋值
r->next=s; //新结点在尾结点的后面
r=s; //r指向新的表尾结点
scanf("%d",&x); //读入下一个结点值
}
r->next=NULL; //尾结点指针置空
return L;
}
对于单链表的查找也有两种方法:
①按序号查找结点:在单链表中从第一个结点出发,顺指针next域逐个往下搜索,知道找到第i个结点为止,否则返回最后一个结点指针域NULL;
LNode *GetElem(LinkList L,int i){
int j=; //计数,初始为1
LNode *p=L->next; //第一个结点指针赋值给p
if(i==) return L; //若i等于0,则返回头结点
if(i<) return NULL; //若i无效,则返回NULL
while(p&&j<i){ //从第1个结点开始找,查找第i个结点
p=p->next;
j++;
}
return p;
}
②按值查找结点:从单链表的第一个结点开始,由前向后依次比较表中各结点数据域的值,若结点数据域的值等于给定值e,则返回该结点的指针,若没有则返回NULL。
LNode *LocateElem(LinkList L,ElemType e){
LNode *p=L->next;
while(p!=NULL&&p->data!=e) //从第1个结点开始查找data域为e的结点
p=p->next;
return p; //找到后返回该结点指针,否则返回NULL
}
单链表的插入操作:
①取指向插入位置的前驱结点的指针 p=GetElem(L,i-1);
②令新结点*s的指针域指向*p的后继结点 s->next=p->next;
③令新结点*p的指针域指向新插入的结点*s p->next=s。
单链表的删除操作:
①p=GetElem(L,i-1);
②q=p->next;
③p->next=q->next;
④free(q).
对于单链表,对数据结点的前驱访问比较困难,所以我们引入双链表,其定义为:
typedef struct DNode{ //定义双链表节点类型
ElemType data; //数据域
struct DNode *prior,*next; //指针域 (前驱+后继)
}DNode,*DLinkList;
双链表的插入操作:
①s->next=p->next;
②p->next->prior=s;
③s->prior=p;
④p->next=s.
双链表的删除操作:
①p->next=q->next;
②q->next->prior=p;
③free(q).
循环单链表:①最后一个结点的指针指向头结点;②从任何一个结点出发都能访问到链表的每一个元素;③判空的条件是头结点的后继为头指针;④对循环单链表仅设置尾指针使得操作效率更高。
循环双链表:①尾结点的后继指向头结点,头结点前驱指向尾结点;②当循环双链表为空表时,其头结点的前驱和后继都为头结点。
静态链表:是借助数组来描述线性表链式存储结构的一种链表,结点中也包含数据域data和指针next,与前面链表中的指针不同的是,这里的指针是结点的相对地址(数组下标),又称为游标。
对于一个a->b->c->d的数据链表,它的静态链表的表示形式为:
| 数组下标 | data | next |
| 0 | 头 | 2 |
| 1 | b | 6 |
| 2 | a | 1 |
| 3 | d | -1(结束) |
| 4 | ||
| 5 | ||
| 6 | c | 3 |
对静态链表的插入、删除操作与动态链表一样,只需要修改指针,而不需要移动元素。
静态链表的定义为:
#define MaxSize 50 //定义静态链表的最大长度
typedef int ElemType //假定表中元素类型是int
typedef struct{ //静态链表结构类型的定义
ElemType data; //存储数据元素
int next; //下一个元素的数组下标
}SLinkList[MaxSize];
C语言数据结构基础学习笔记——基础线性表的更多相关文章
- C语言数据结构基础学习笔记——静态查找表
查找:在数据集合中寻找满足某种条件的数据元素的过程称为查找. 查找表:用于查找的数据集合称为查找表,一般有以下操作:①查找是否在表中:②查找属性:③进行操作. 查找表又分为: ①静态查找表:只可以进行 ...
- 数据结构学习笔记 <1> 线性表
一.线性表的抽象数据类型描述 类型名:线性表(List) 数据对象集:线性表示n(>=0)个元素构成的有序序列(a1,a2,……,an) 操作集:线性表L∈List, 整数i表示位置,元素X∈ ...
- C语言数据结构基础学习笔记——动态查找表
动态查找表包括二叉排序树和二叉平衡树. 二叉排序树:也叫二叉搜索树,它或是一颗空树,或是具有以下性质的二叉树: ①若左子树不空,则左子树上所有结点的值均小于它的根结点的值: ②若右子树不空,则右子树上 ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
- Oracle基础学习笔记
Oracle基础学习笔记 最近找到一份实习工作,有点头疼的是,有阶段性考核,这...,实际想想看,大学期间只学过数据库原理,并没有针对某一数据库管理系统而系统的学习,这正好是一个机会,于是乎用了三天时 ...
- 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)
注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...
- C#RabbitMQ基础学习笔记
RabbitMQ基础学习笔记(C#代码示例) 一.定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开发).MQ是一种应用程序对应用程序的通信方法. ...
- C++基础 学习笔记之一:源代码的格式化
C++基础 学习笔记之一:源代码的格式化 1. 源代码中的标记与空白 C++中的语句是以分号表示语句的结束.在C++中空格和回车以及制表符均为相同作用,即三者通常可以互相替代. 例如可以将一个简单的m ...
- jQuery学习笔记 - 基础知识扫盲入门篇
jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...
随机推荐
- xftp免费版使用
转自https://www.jb51.net/softs/621774.html
- 解决SpringMVC+Thymeleaf中文乱码
乱码效果截图 解决办法:在org.thymeleaf.templateresolver.ServletContextTemplateResolver和org.thymeleaf.spring5.vie ...
- python笔记二
一 运算符 1算术运算+ - * / % ** //其中%为取余,**为取幂如2**10=1024 9//4=2 需要注意的是python2.7中如9/2=4 需要正确表示,则在开头添加 fr ...
- day37-多进程多线程二-锁
Lock组件 当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,如果两个文件同时进行,肯定是不行的,必须是文件写结束以后,才可以进行读操作.或者是多个进程在共享一些资源的时候,同 ...
- Java库中的集合
集合类型 描述 ArrayList 一种可以动态增长和缩减的索引序列 LinkedList 一种可以在任何位置进行高效的插入和删除操作的有序序列 ArrayDeque 一种用循环数组实现的双端队列 H ...
- HTML5:定位
定位 一.介绍: position设置块级元素相对于其父块的位置和相对于它自身应该在的位置,任何使用定位的元素都会成为块级元素. 1.属性值 属性值 描述 absolute 生成绝对定位的元素,相对于 ...
- setfacl语法
1.setfacl的用途setfacl命令可以用来细分linux下的文件权限. chmod命令可以把文件权限分为u,g,o三个组,而setfacl可以对每一个文件或目录设置更精确的文件权限. 换句话说 ...
- nginx下运行php的程序时返回200访问却是空白页问题的解决方法
由于nginx与php-fpm之间的一个小bug,会导致这样的现象: 网站中的静态页面 *.html 都能正常访问,而 *.php 文件虽然会返回200状态码, 但实际输出给浏览器的页面内容却是空白. ...
- Canvas名侦探柯南-canvas练习
var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); / ...
- mysql locking
1. 意向锁 https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-insert-intention-locks 官方文 ...