数据结构(2):线性表【新】

目录

1 线性表的定义和基本操作

1.1 定义

1.2 基本操作

1.3 小结

2 线性表的顺序表示和实现

2.1 顺序表示

1)存储结构

2)静态分配

3)动态分配

4)小结

2.2 基本操作实现

1)插入

2)删除

3)查找

4)小结

3 线性表的链式表示和实现

3.1 单链式表示

1)存储结构

2)代码定义

3)不带头结点的初始化

4)带头结点的初始化

5)小结

3.2 单链表基本操作

1)插入

2)删除

3)查找

4)单链表的建立

3.3 双链表

1)初始化

2)插入

3)删除

4)遍历

5)小结

3.4 循环链表

1)循环单链表

2)循环双链表

3)小结

3.5 静态链表

1)概念

2)定义

3)实现

4)小结

4 顺序表和链表的比较

4.1 逻辑结构

4.2 存储结构

4.3 基本操作

4.4 小结

5 线性表的应用


1 线性表的定义和基本操作

在这里插入图片描述

1.1 定义

​ 线性表的定义(2-1):线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列

在这里插入图片描述

  • 注意,线性表是一种逻辑结构,它只有(2-1)这句定义,表示元素之间一对一的相邻关系
  • 之后我们学习的顺序表和链表才指存储结构,所以线性表只考虑逻辑方面的关系

1.2 基本操作

在这里插入图片描述


1.3 小结

在这里插入图片描述


2 线性表的顺序表示和实现

在这里插入图片描述

2.1 顺序表示

1)存储结构

  • 顺序表就是用一组地址连续的存储单元依次存储线性表中的数据元素
  • ① 线性表 + 顺序存储 = 顺序表
    • 数据元素现在不仅是逻辑上 按序 且 前后相邻,而且物理上也是 按序 且 前后相邻,顺序表用一块连续的存储空间顺序****实现线性表
  • ② 线性表的顺序存储 + 元素类型相同 = 随机存取

在这里插入图片描述

  • ③ 存储空间分配方式
  • 顺序表在高级语言中是使用数组来实现的,根据对顺序表存储空间分配方式的不同,分成静态分配和动态分配
  • 静态分配时,数组的大小在一开始是固定的,空间满了数据就会溢出;
  • 动态分配时,存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,不够在扩充。
  • 这里就有一处很重要的地方需要注意,当动态分配的数组空间不够用的时候,想再扩充L个存储空间(数组N个存储空间),这时候程序是在内存开辟一个N+L大小的空间,而不是L大小。因为顺序表就得占用着一块连续的内存空间

2)静态分配

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
 
#include <stdio.h>
#define MaxSize 10 //定义顺序表的长度
typedef struct {
	int data[MaxSize];//用静态的数组存放元素!
	int length;
}SqList;
//相当于python中的类,这个类有一个属性是 长度
 
//基本操作--初始化一个顺序表
void InitList(SqList& L) {
	for (int i = 0; i < MaxSize; i++) {
		L.data[i] = 0;
	}//初始化每一个值为0
	L.length = 0;
}
 
 
//主函数
int main() {
	SqList L;//创建一个顺序表
	InitList(L);//初始化一个顺序表!!!
	return 0;
}


3)动态分配

在这里插入图片描述

在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

#define INITSIZE 10
typedef struct
{
    int val;
} ElemType;

typedef struct
{
    ElemType *data;
    int length;
    int maxSize;
} SqList;

void InitList(SqList &list)
{
    list.data = (ElemType *)malloc(INITSIZE * sizeof(ElemType));
    list.length = 0;
    list.maxSize = INITSIZE;
}

int main()
{
    SqList l;
    InitList(l);
    int elem, i = 0;
    while (cin >> elem)
    {
        l.data[i].val = elem;
        l.length++;
        i++;
    }
    for (i = 0; i < l.length; i++)
    {
        cout << "data[" << i << "] = " << l.data[i].val << endl;
    }
}


4)小结

在这里插入图片描述

在这里插入图片描述


2.2 基本操作实现

1)插入

在这里插入图片描述


2)删除

在这里插入图片描述


3)查找

  • ① 按位查找

静态:

动态分配:

在这里插入图片描述

  • ② 按值查找

在这里插入图片描述


4)小结

在这里插入图片描述

在这里插入图片描述


3 线性表的链式表示和实现

在这里插入图片描述

3.1 单链式表示

1)存储结构

在这里插入图片描述


2)代码定义

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3)不带头结点的初始化

在这里插入图片描述


4)带头结点的初始化

在这里插入图片描述


5)小结

在这里插入图片描述

头结点不存储数据,不带头结点那么这个头指针指向的就是实际用于存放数据的结点而带头结点 这个头指针指向的是头结点 这个结点不存放数据,这个头结点之后的下一个结点才会用于存放数据!!!

在这里插入图片描述


3.2 单链表基本操作

  • 对于不带头结点的情况,虽然考查较少,当也有可能考
  • 除了插入操作有带头、不带头情况,其它操作默认带头结点

在这里插入图片描述

1)插入

在这里插入图片描述

  • ① 带头结点

在这里插入图片描述

在这里插入图片描述

  • ② 不带头结点

在这里插入图片描述

在这里插入图片描述

  • ③ 指定后插

在这里插入图片描述

在这里插入图片描述

  • ④ 指定前插

在这里插入图片描述

  • 该方法虽然间接实现了指定结点的前插操作,但是无法获得前驱结点的指针

在这里插入图片描述


2)删除

在这里插入图片描述

  • ① 带头结点

在这里插入图片描述

  • ② 指定删除
  • 无法删除最后一个结点

在这里插入图片描述

如果p是最后一个结点的话:【只能采用方法一来弄!】

在这里插入图片描述


3)查找

在这里插入图片描述

  • ① 按位查找

在这里插入图片描述

  • ② 优化插入操作代码

在这里插入图片描述

  • ③ 按值查找

在这里插入图片描述

  • ④ 求表长度

在这里插入图片描述

  • ⑤ 小结

在这里插入图片描述


4)单链表的建立

  • ① 尾插法

这样的问题是每次都要遍历到找到最后一个元素,那么时间复杂度就是0+1+2+3+.....+(n-1)这样的话时间复杂度就是o(n^2)  太高了,引入尾指针

  • 下面时间复杂度是O(n),但是如果题目说明每次都重头开始遍历进行尾插,就是O(n^2)

在这里插入图片描述

  • ② 头插法

在这里插入图片描述


3.3 双链表

1)初始化

在这里插入图片描述

  • 带头结点情况

在这里插入图片描述


2)插入

在这里插入图片描述


3)删除

在这里插入图片描述


4)遍历

在这里插入图片描述


5)小结

在这里插入图片描述


3.4 循环链表

1)循环单链表

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


2)循环双链表

在这里插入图片描述

  • ① 初始化

在这里插入图片描述

  • ② 插入

在这里插入图片描述

  • ③ 删除

在这里插入图片描述


3)小结

在这里插入图片描述


3.5 静态链表

1)概念

在这里插入图片描述


2)定义

在这里插入图片描述


3)实现

在这里插入图片描述

在这里插入图片描述


4)小结

在这里插入图片描述


4 顺序表和链表的比较

4.1 逻辑结构

在这里插入图片描述


4.2 存储结构

在这里插入图片描述


4.3 基本操作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


4.4 小结

在这里插入图片描述


5 线性表的应用

必定不考,放在这里主要是为了知识结构的完整性

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值