画解数据结构1.1顺序表 排序 二分查找

本文介绍了顺序表的存储结构,包括数据结构定义和常用接口,如索引、查找、获取长度和插入操作。同时,详细阐述了几种数组相关的算法,如线性枚举、前缀和差分、双指针、二分查找、插入排序、选择排序和冒泡排序。这些内容对于理解和实现数组操作具有指导意义。

顺序表

顺序储存,是指用一段地址连续的存储单元依次存储线性表的数据元素。

数据结构定义

length为当前数组长度

#define maxn[10000]
#define Datatype int
struct leqlist{
Datatype data[maxn];
int length;
}

2.常用接口

(1)索引:通过数组下标寻找数组元素

Datatype SeqlistIndex(struct Seqlist *sq,int i)

{return sq->data[i];}

(2)查找

Datatype SeqlistFind(struct Seqlist *sq,Datatype dt)

{

for(int i=0;i<sq->length;i++)

{
​​​​​​​if(sq->data[i]==dt)
{
return i;
}
}
return -1;
}

(3)获取长度(length)

Datatyepe SeqlistgetLength(struct Seqlist *sq)
{
return Sq->length;}

sq为结构体,直接获取结构体内变量

(3)插入

在第k个元素前插入一个数v

int Seqlistinsert{Seqlist*sq,intk,Datatype k}
{
if(sq->length==maxn)
{return 0;}
for(int i=sq->length;i>k;i--)
{sq->data[i]=sq->data[i-1];}
sq->data[k]=v;
sq->lengtg++;
return 1;}

0代表插入失败,1代表成功

(4)删除

数组相关算法

1.线性枚举

普通for循环

2.前缀和差分

 int sum[maxn];

int * prem(int *nums,int*numsSize,int m,int*l,int*r)

{
for(int i=0;i<numsSize;i++)
{
sum[i]=num[i];
if(i)
{
sum[i]+=sum[i-1];
}
}
for(int i=0;i<m;i++)//m组数据
{
int leftsum=sum[l[i]];
int rightsum=sum[r[i]];
ret[i]=rightsum-leftsum;
}
return ret;
}

前缀和差分,记录1到n的实时sum,再通过输入两个边界left和right,计算left到right的差值

3.双指针

4.二分查找(用于数组有序排列时)

注意循环条件为(l<=r)

5.三分枚举

6.插入排序

void charupaixu (int*a,int n)//n为数组长度
{
for(int i=0;i<n;i++)
{
if(i)
{
for(int j=i-1;j>=0;j--)
{
if(a[i]<=a[j])
{
a[j+1]=a[j];
}
else{
break;
a[j+1]=a[i];
}
}

7.选择排序

void xuaznepaixu(int*a,int n)
{
for(int i=0;i<n;i++)
{
int min=i;
for(int j=i;i<n;j++)
{
if(a[j]<=a[min])
{
min=j;
}
}
swap(&a[i],&a[min])
}

选择排序和插入排序的区别:

选择排序是从前往后遍历,在后面找出最小值,插入已经排好的队列后面

插入排序是从前往后遍历,为对应的i在前面已经排好的队列里面找一个合适的位置插入

8.冒泡排序

void bubblesort(int *a,intn)
{
bool swapped;
int last=n;
do
{
swapped=false;
for(int i=0;i<last-1;i++)
{
if(a[i]>a[i+1])
{
swap(&a[i],&a[i+1]);
swapped=true;
}
}
--last;
while(swapped=true)
}

每次do循环后最后一位排序好,因此--last;

<think>我们正在处理用户关于查找与排序相关数据结构知识点的请求。根据用户的要求,我们需要总结查找算法和排序算法的主要知识点。同时,结合提供的引用,特别是引用[1]和引用[3]中详细列出了查找排序的目录和内容,引用[4]中也有一些相关的内容,我们将按照引用中的结构来组织回答。查找算法部分:根据引用[1]:一、查找1.基本概念:查找表、动态查找表和静态查找表、平均查找长度ASL2.线性表的查找:顺序查找、折半查找/二分查找、分块查找3.树表的查找:二叉排序树(定义、查找、插入、创建、删除)、平衡二叉树(调整:RR型、LL型、LR型、RL型)4.散列表的查找:构造方法(数字分析法、平方取中法、折叠法、除留余数法)、处理冲突(开放寻址法包括线性探测、二次探测、伪随机探测;链地址法)排序算法部分:根据引用[1]:二、排序1.基本概念2.插入排序:直接插入排序、折半插入排序、希尔排序3.交换排序:冒泡排序、快速排序(代码实现)4.选择排序:简单选择排序(直接选择排序)、树形选择排序(锦标赛排序)、堆排序(调整堆、建初堆、算法实现)5.归并排序6.排序算法总结另外,引用[3]中提到快速排序的优化,引用[4]中提到了线性表的基本操作(包括创建、求长度、查找、插入、删除等),以及顺序存储和链式存储的特点。这些内容也会在适当的地方提到。我们按照以下结构组织回答:1.查找算法知识点总结1.1基本概念1.2线性表的查找1.3树表的查找1.4散列表的查找2.排序算法知识点总结2.1基本概念2.2插入排序2.3交换排序2.4选择排序2.5归并排序2.6排序算法总结(性能比较)在回答中,我们使用行内公式表示数学表达式,独立公式单独成段。由于是总结性内容,我们将尽可能简明扼要。注意:引用中提供的代码实现我们不在这里全部展开,但可以提到关键点,例如快速排序的代码已经在引用[1]中给出。开始编写回答:</think> 以下是根据引用内容整理的**查找算法**与**排序算法**核心知识点总结,结合数据结构特性分类归纳: --- ### 🔍 一、查找算法知识点总结 #### 1. **基本概念** - **查找表**:用于查找的数据集合 - **动态/静态查找表**:是否支持插入/删除操作 - **平均查找长度(ASL)**:$ASL = \sum_{i=1}^{n} P_i C_i$ ($P_i$为查找概率,$C_i$为比较次数)[^1] #### 2. **线性表查找** | 方法 | 时间复杂度 | 特点 | |--------------|------------|----------------------------------| | 顺序查找 | $O(n)$ | 适用于无序线性表 | | 折半查找 | $O(\log n)$ | **有序表**,使用二分思想 | | 分块查找 | $O(\log n+s)$ | 块内无序,块间有序(索引结构) | #### 3. **树表查找** - **二叉排序树(BST)** - 定义:左子树所有结点 $<$ 根结点 $<$ 右子树所有结点 - 操作: ```python # 查找(递归) def search_bst(node, key): if not node: return None if key == node.val: return node elif key < node.val: return search_bst(node.left, key) else: return search_bst(node.right, key) ``` - 删除:分叶子结点、单子树结点、双子树结点三种情况[^1] - **平衡二叉树(AVL)** - 调整类型:RR型(左旋)、LL型(右旋)、LR型(先左后右)、RL型(先右后左) - 目的:确保树高差 $|h_L - h_R| \leq 1$ #### 4. **散列表(Hash Table)** - **构造方法**: - 除留余数法(最常用):$h(key) = key \% p$($p$ 取质数) - 平方取中法、折叠法、数字分析法[^1] - **冲突处理**: | 方法 | 特点 | |----------------|----------------------------------------------------------------------| | 开放定址法 | 线性探测(易聚集)、二次探测(减少聚集)、伪随机探测 | | 链地址法 | 冲突结点组织成单链表,空间利用率高 | --- ### 🔄 二、排序算法知识点总结 #### 1. **基本概念** - **稳定性**:相等元素排序后相对位置不变(如冒泡、插入稳定) - **内排序**:所有操作在内存完成 - **外排序**:涉及磁盘读写(如大文件归并排序) #### 2. **经典算法分类** | 类别 | 算法 | 时间复杂度 | 空间复杂度 | 特点 | |------------|-------------------|------------------|------------|--------------------------| | **插入排序** | 直接插入排序 | $O(n^2)$ | $O(1)$ | 小规模数据高效 | | | 折半插入排序 | $O(n^2)$ | $O(1)$ | 减少比较次数 | | | 希尔排序 | $O(n^{1.3})$ | $O(1)$ | 分组增量排序 | | **交换排序** | 冒泡排序 | $O(n^2)$ | $O(1)$ | 稳定但效率低 | | | **快速排序** | $O(n \log n)$ | $O(\log n)$| 分治思想,枢纽元选择关键 | | **选择排序** | 简单选择排序 | $O(n^2)$ | $O(1)$ | 不稳定,移动次数少 | | | **堆排序** | $O(n \log n)$ | $O(1)$ | 建堆+调整堆 | | | 树形选择排序 | $O(n \log n)$ | $O(n)$ | 锦标赛思想 | | **归并排序** | 二路归并 | $O(n \log n)$ | $O(n)$ | 稳定,外排序基础 | > **快速排序核心代码**(分治递归): > ```python > def quick_sort(arr): > if len(arr) <= 1: > return arr > pivot = arr[0] > left = [x for x in arr[1:] if x < pivot] > right = [x for x in arr[1:] if x >= pivot] > return quick_sort(left) + [pivot] + quick_sort(right) > ``` #### 3. **排序算法对比** | 排序方法 | 最优情况 | 最差情况 | 稳定性 | 适用场景 | |--------------|------------|------------|--------|------------------------| | 快速排序 | $O(n \log n)$ | $O(n^2)$ | 不稳定 | 大规模随机数据 | | 堆排序 | $O(n \log n)$ | $O(n \log n)$| 不稳定 | 实时系统,空间有限 | | 归并排序 | $O(n \log n)$ | $O(n \log n)$| 稳定 | 外部排序、链表排序 | | 直接插入排序 | $O(n)$ | $O(n^2)$ | 稳定 | 小规模或基本有序数据 | --- ### 💡 关键问题延伸 1. **哈希冲突解决中,链地址法与开放定址法有何优劣?** - **链地址法**:避免聚集,但需要额外指针空间。 - **开放定址法**:空间紧凑,但易引发二次聚集,删除需标记逻辑删除[^1]。 2. **快速排序的优化策略有哪些?** - 三数取中法(避免最坏情况) - 小数组切换插入排序 - 尾递归优化(减少栈空间)[^3] 3. **堆排序的调整堆操作如何实现?** ```python def heapify(arr, n, i): largest = i left, right = 2*i + 1, 2*i + 2 # 左右子节点索引 if left < n and arr[i] < arr[left]: largest = left if right < n and arr[largest] < arr[right]: largest = right if largest != i: arr[i], arr[largest] = arr[largest], arr[i] heapify(arr, n, largest) # 递归调整子树 ``` --- ### 📚 参考资料 [^1]: 【数据结构】查找排序复习笔记总结 [^2]: 【数据结构与算法】数据结构知识点总结 [^3]: 数据结构相关概念与算法总结 [^4]: 数据结构与算法——线性表与排序基础
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值