数据结构

本文介绍了数据结构中的线性表概念,包括抽象数据类型定义、线性表的顺序存储结构和单链表存储结构。讨论了线性表的操作如插入和删除,以及单链表的插入算法思路。还提到了静态链表和腾讯面试题——寻找单链表中间节点的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构

分为逻辑结构
和 物理结构:链式结构,顺序结构。

输出 有穷性。

缓冲区溢出:通过特定的输入使得系统出现问题。
在缓冲区出现问题把指令给修改为我们设计好的指令和跳转来实现我们的目的。

算法效率的度量方法

算法评判更加科学和便捷,得到了事前分析估算方法。
所耗时间取决于下列因素:
1.算法采用的策略和方案。
2.编译产生的代码质量。
3.问题的输入规模。
4.机器执行指令的速度。
(虽然我暂时不懂是什么意思)我们在分析一个算法的运行时间时,重要的是吧基本操作的数量和输入模式关联起来。

算法时间复杂度

在这里插入图片描述

线性表

由另个或者多个数据元素组成的有限序列。

抽象数据类型

定义:一组性质相同的值的集合及定义在此集合上的一些操作的名称。
C语言中分为原子类型和结构类型。
标准格式:
ADT 抽象数据类型名
Data
数据元素之间逻辑关系的定义
Operation
操作
endADT

线性表的抽象数据类型

ADT 线性表(list)
Data
线性表的数据对象集合为a1-an,每个元素的类型均为Datatype。其中,初一第一个元素a1以外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation
initlist:初始化操作,建立一个空的线性表L。
ListEmpty:判断线性表是否为空表,若空返回trun否则返回false。
ClearList:清空线性表。
GetElem:将线性表L中的第i哥位置元素值返回给e。
LocateElem:在线性表L中查找与给定值e相等的元素。返回元素序号表示成功,否则返回0.
ListInsert:在线性表L中第i哥位置插入新元素e。
ListIength:返回哥输
ListDelete 删掉L中第
i个位置的元素并返回那个值。
endADT

线性表的顺序存储结构
有两种物理存储结构:顺序存储(排队放元素),链式存储

#define MAXSIZE 20//定义数组的最大长度 
typedef int ElemType;//定义类型 
typedef struct
{
 ElemType data[MAXSIZE];
 int length;//当前长度 
}SqLsit;

在这里插入图片描述

地址计算方法

从1开始;
假设Elemtypr占用c个存储单元,则第i+1个元素和第i个元素的存储位置的关系是:
LOC(ai+1) = LOC(ai) + c
c表示存储单元的宽度

所以对于第i个元素ai的存储位置可以有a1推算得出:
LOC(ai+1) = LOC(ai) + c*(i-1)
通过这个公式可以随时计算出线性表中任意位置的地址。存储性能为O(1),将其称为随机存储结构。

对线性表的一些操作

ListInsert(*L,i,e) 插入元素
ListDelete(*L,i) 删除元素
顺序存储结构不适合用这两个接口。会完全改变元素所在位置,而适合存储应用数据。

线性表顺序存储结构的优缺点


头节点的数据域一般不存储任何信息。 头指针是链表中指向第一个结点的指针,若链表有头节点,则是指向头结点的指针。
无论链表是否为空,头指针都不为空。
有了头节点,对在第一元素结点前插入结点和删除第一结点起操作与其他节点的操作就统一了。

单链表存储结构

 C语言中用结构指针描述单链表。
typedef structural Node
{Elemtype data;
struct Node *Next;}
Mode;
typedef struct Node *LinkList;
//结点由存放数据元素的数据域和存放后继结点地址的指针域组成。 

在这里插入图片描述

单链表的读取

获取第i个元素:
最尾部的指针是null define,也就是0.

Status GetElem(LinkList L,int i,ElemType*e)
{
 int j;LinkList p;
 
 p = L->next;
 j = 1;
 
 while(p&&j<i)
 {
  p = p->next;
  ++j;
 }
 
 if(!p||j>i) //如果上边的i超出了范围p会停留在最后的指针域上等于0
 {
  return ERROR;
 }
 *e = p->data;
 
 return OK;
}

由于单链表中的结构中没有定义表长所以不能事先知道要循环多少次,因此也就不方便使用for来控制循环。其核心思想叫工作指针后移,这其实也是很多算法的常用技术。

单链表的插入

存储元素e的结点为s 插入ai和ai+1 假设ai的地址为p 则主要思路:
1 s->next = p -> next;
2 p->next = s;
也就是中间生成一个空结点,前边放元素后边放指针指向下一个结点

单链表创建得算法思路

1 声明1结点p和计数器变量i
2 初始化空链表L
3 让L得头节点得指针指向NULL,即建立一个带头结点得单链表
4 循环实现后继结点得赋值和插入

单链表的整表删除

方法
代码

静态链表:用数组表述的链表。

这种描述链表的方法被称作游标实现法。
第一个和最后一个表格都不存放数据。

//线性表的静态链表存储结构
#define MAXSIZE 1000
typedef struct
{
	ElemType data;
	int cur;
 } Component,StaticLinkList[MAXSIZE];

在这里插入图片描述
上图更正为下图:
在这里插入图片描述

 //对静态链表进行初始化   相当于初始化数组
 Status InitList(StaticLinkList space)
 {
 	int i;
 	for( i = 0;i < MAXSIZE -1;i++)
 	space[i].cur = i + 1;
 	
 	space[MAXSIZE - 1].cur = 0;
 	return OK;
  } 
  //cur是下标。

静态链表的插入本质上是数组的插入。

在这里插入图片描述
在这里插入图片描述

i是2时候简单的用上边的静态链表推倒了一下代码
下标5中的e插入到第2个元素前面

腾讯面试题:寻找单链表中间节点。

在这里插入图片描述
在这里插入图片描述
代码。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值