【基础算法】排序 查找 算法

简介: 【基础算法】排序 查找 算法

一、排序的基本概念

1、什么是排序?

排序是指把一组数据以某种关系(递增或递减)按顺序排列起来的一种算法。例如:数列 8、3、5、6、2、9、1、0、4、7递增排序后 0、1、2、3、4、5、6、7、8、9递减排序后 9、8、7、6、5、4、3、2、1、0

2、排序的过程

排序的过程中需要进行如下两种基本操作:(1)比较两个数据的大小;(2)移动两个数据的位置。

3、排序算法

排序算法按照其实现的思想和方法的不同,可以分为许多种。我们比较常用的排序算法有:

交换类排序:冒泡排序、快速排序

插入类排序: 直接插入排序、希尔排序(缩小增量排序)

选择类排序:简单选择排序、堆排序归并排序基数排序

二、冒泡排序  

冒泡排序的规则:n个数据进行冒泡排序,首先将第一个数据和第二个数据进行比较,如果为逆序就交换两个数据的值,然后比较第二个和第三个数据,依此类推,直到第最后一个和倒数第二个比较完了为止。上述过程为冒泡排序的第一趟冒泡排序,其结果是最大或者最小的数据被放置在末尾的位置。然后进行第二趟排序,把第二大或者第二小的数放置在倒数第二的位置,之后每一趟排序都会使一个数据有序,直到此序列的全部数据都有序为止。冒泡排序的演示示例:

 

void BubbleSort(int x[],int n)//冒泡排序
{
int i, j;
for (i = 0;i<n-1;i++)
for (j = 0; j <n-1-i; j++)
{
if (x[j] > x[j + 1])
{
x[j] += x[j + 1];
x[j + 1] = x[j] - x[j + 1];
x[j] = x[j] - x[j + 1];
}
}
for (i=0;i<n;i++)
printf("%d\t",x[i]);
}

三、选择排序

对一个序列进行选择排序,首先通过一轮循环比较,从n个数据中找出最大或者最小的那个数据的位置,然后按照递增或者递减的顺序,将此数据与第一个或最后一个数据进行交换。然后再找第二大或者第二小的数据进行交换,以此类推,直到序列全部有序为止。选择排序与冒泡排序的区别在于,冒泡排序每比较一次后,满足条件的数据就交换,而选择排序是每次比较后,记录满足条件数据的位置,一轮循环过后再作交换。

选择排序的演示示例:

 

void SelectSort(int x[], int n)//选择排序
{
int i, j, min,k;
for (i = 0; i < n; i++)
{
min=i;
for (j = i; j < n; j++)
{
if (x[min] > x[j])
min = j;
}
k = x[i];
x[i] = x[min];
x[min] = k;
}
for (i=0;i<n;i++)
printf("%d\t",x[i]);
}

四、查找的基本概念

我们常常需要在一个数列中查找我们所需要的数据,这里就需要用到查找算法了。

查找的目的,是在「已排序的数列」中寻找指定的数据,而当中顺序查找是最基本的查找算法,只要从数列的开头寻找到最后,看看是否找到指定数据即可。

常用的查找算法有顺序查找、折半查找。


五、顺序查找

顺序查找的基本思想:

从序列中的一端开始,逐个把需要查找的值与序列中的数据进行比较,如果找到一个数据与需要查找的数据值相等,则查找成功;如果整个序列中的数据都比较过,仍未找到需要查找的数,则说明此序列中不存在此数据,查找失败。

顺序查找的程序示例:

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h> //时间函数头文件
int main()
{
srand(time(NULL)); //随机数种子
int n = 1, m = 0, arr[100] = { 0 }, i = 0, index = -1;
printf("请输入随机数的个数n(n<=100):");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
arr[i] = rand() % 100; //产生n个100以内的随机数,并存入数组
}
for (i = 0; i < n; i++)
{
printf("%d\t", arr[i]);
}
putchar('\n');
printf("请输入要查找的数m:");
scanf("%d", &m);
//顺序查找Sequential search
for (i = 0; i < n; i++)
{
if (arr[i] == m)
{
index = i;
printf("此数在数组中下标为[%d]的位置出现!\n", index);
}
}
if (index < 0)
{
printf("数组中未找到此数的位置!\n");
}
system("pause");
return 0;
}

六、折半查找(二分查找)

二分查找又称为折半查找,也就是对于一个已排序好的队列来说,利用它们已排序的特性,以减少比较的次数,这是查找的基本原则,二分查找是这个基本原则的代表。

在二分查找法中,从数列的中间开始查找,如果这个数小于我们所查找的数,由于数列已排序,则该数左边的数一定都小于要查找的数,所以无需浪费时间在左边的数;如果查找的数大于所查找的对象,则右边的数无需再查找,直接查找左边的数。 所以在二分查找法中,将数列不断的分为两个部份,每次从分割的部分中取中间数进行比较。

例如要查找92于以下的数列,首先中间数索引为(0+9)/2 = 4(索引由0开始):

[3 24 57 57 67 68 83 90 92 95]

由于67小于92,所以转查找右边的数列:

3 24 57 57 67 [68 83 90 92 95

由于90小于92,再查找右边的数列,这次就找到所要的数了:

3 24 57 57 67 68 83 90 [92 95]

二分查找的程序示例:

 

int Binary_Search(int arr[], int size, int findVal)
{
//准备区间
int left = 0, right = size - 1;
int mid;
//开始搜索
while (left<=right)
{
//第一步 确定mid
mid = ((right - left) >> 1) + left; //细节处理数据溢出
//第二步 比较
if (findVal == arr[mid])
return mid;
//第三步 收缩区间
if (arr[mid] > findVal)//前半
right = mid - 1;
if (arr[mid] < findVal)//前半
left = mid + 1;
}
//循环结束了 说明元素不存在
return -1;
}
相关文章
|
10天前
|
算法 C++
【洛谷 P1223】排队接水(贪心算法+结构体排序)
该问题要求安排$n$个人的排队顺序以最小化平均等待时间。每个人接水需时$T_i$,解决方案是让接水时间短的人优先。给定$n\leq1000$和$t_i\leq10^6$,代码示例使用C++实现,通过排序使时间从小到大排列,然后计算平均等待时间。样例输入为10个人的时间数组,输出为优化后的排队顺序及平均等待时间(291.90)。
12 0
|
14天前
|
搜索推荐 算法
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
|
17天前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
5天前
|
算法 Java 调度
Java数据结构与算法:拓扑排序
Java数据结构与算法:拓扑排序
|
5天前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
14 0
|
10天前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
10天前
|
人工智能 算法 BI
【洛谷 P1803】凌乱的yyy _ 线段覆盖 题解(贪心算法+结构体排序)
**线段覆盖问题**: YYY 想在 NOIP 前参加最多比赛。给定 $n$ 场比赛的开始和结束时间,每场比赛必须连续且不能冲突。输入包含每场比赛的时间段,输出最多可参加的比赛数。$20\%$ 数据 $n\leq10$,$50\%$ 数据 $n\leq10^3$,$100\%$ 数据 $n\leq10^6$。解决方案:按结束时间排序比赛,若当前比赛开始时间晚于上一个结束时间,则计数加一。样例输入:3 场比赛,输出:2。AC C++ 代码实现了此算法。
11 0
|
17天前
|
算法
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
|
21天前
|
算法 搜索推荐 数据可视化
【漫画算法】指挥官的排序战术:快速排序算法解密
【漫画算法】指挥官的排序战术:快速排序算法解密
|
21天前
|
数据采集 算法 数据挖掘
LeetCode 题目 80:删除排序数组中的重复项 II【算法面试高频题】
LeetCode 题目 80:删除排序数组中的重复项 II【算法面试高频题】