前言
为了更加直观的展示排序的过程,用了动态图方便理解,并且对每一步的排序过程显示打印出来。
文章目录
一 排序算法
1.1什么是排序
排序是指把一组数据以某种关系(递增或递减)按顺序排列起来的一种算法。
1.2排序的稳定性
如果在一组需要排序的数据序列中,数据ki和kj的值相同,即ki= =kj,且在排序前ki在序列中的位置领先于kj,那么当排序后,如果ki和kj的相对前后次序保持不变,即ki仍然领先于kj,则称此类排序算法是稳定的。如果ki和kj的相对前后次序变了,即kj领先于ki了,则称此类排序算法是不稳定的。
1.3排序的分类
1.内部排序:指待排序数据全部存放在内存中进行排序的过程。
2.外部排序:指待排序数据的数量很大,内存无法全部容纳所有数据,在排序过程中需要对外存进行访问的排序过程。
1.4排序的过程
排序的过程中需要进行如下两种基本操作:
(1)比较两个数据的大小;
(2)移动两个数据的位置。
1.5排序算法
排序算法按照其实现的思想和方法的不同,可以分为许多种。
我们比较常用的排序算法有:冒泡排序、 插入排序、选择排序、希尔排序、快速排序、堆排序、归并排序。
1.6复杂度
时间复杂度和空间复杂度
二 冒泡排序
2.1动态图解
2.2基本思路
2.2.1核心思路
n个数据进行冒泡排序,首先将第一个数据和第二个数据进行比较,如果为逆序就交换两个数据的值,然后比较第二个和第三个数据,依此类推,直到第最后一个和倒数第二个比较完了为止。上述过程为冒泡排序的第一趟冒泡排序,其结果是最大或者最小的数据被放置在末尾的位置。然后进行第二趟排序,把第二大或者第二小的数放置在倒数第二的位置,之后每一趟排序都会使一个数据有序,直到此序列的全部数据都有序为止。
2.2.2算法实现
void BubSort(int a[],int N)//冒泡排序
{
for (int i = 0; i < N; i++)//外层是轮数 每一轮选出一个最大的
{
for (int j = 0; j <N - i - 1; j++)//内循环是比较
{
if (a[j]>a[j + 1])//前后两个数两两进行比较,满足要求的进行交换
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
2.3排序示例
1.代码实现
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void BubSort(int a[], int N)//冒泡排序
{
for (int i = 0; i < N; i++)//外层是轮数 每一轮选出一个最大的
{
for (int j = 0; j <N - i - 1; j++)//内循环是比较
{
if (a[j]>a[j + 1])//前后两个数两两进行比较,满足要求的进行交换
{
int temp = a[j];//交换
a[j] = a[j+1];
a[j+1] = temp;
}
}
printf("第%d步排序结果:", i);
for (int k = 0; k < N; k++)//把每一步都打印出来
{
printf("%d ", a[k]);
}
printf("\n");
}
}
int main()
{
int shuzu[SIZE], i;
srand(time(NULL));//生成随机数种子
for (i = 0; i < SIZE; i++)//随机产生SIZE个数据
{
shuzu[i] = rand()%100;
}
printf("排序前的数组为:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
BubSort(shuzu, SIZE);
printf("排序后的数组为:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.结果展示
三 选择排序
3.1动态图解
3.2 基本思路
3.2.1核心思路
对一个序列进行选择排序,首先通过一轮循环比较,从n个数据中找出最大或者最小的那个数据的位置,然后按照递增或者递减的顺序,将此数据与第一个或最后一个数据进行交换。然后再找第二大或者第二小的数据进行交换,以此类推,直到序列全部有序为止。
3.2.2算法实现
void SelectionSort(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;//如果有小于默认最小元素min的数组元素,min记录其下标
}
k = x[i];
x[i] = x[min];
x[min] = k;
}
for (i=0;i<n;i++)
printf("%d\t",x[i]);
}
3.3排序示例
1.代码实现
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void SelectionSort(int a[], int N)
{
for (int i = 0; i < N; i++)//每一轮选出一个最小的放最左边
{
int min = i; //默认当前选择位置上的元素是最小的
for (int j = i + 1; j < N; j++)//内循环是比较 是不是比它小
{
if (a[min]>a[j])
{
min = j; //如果有小于默认最小元素min的数组元素,min记录其下标
}
}
int k = a[min];
a[min] = a[i];
a[i] = k;
printf("第%d步排序结果:", i);
for (int h = 0; h < N; h++)
{
printf("%d ", a[h]);
}
printf("\n");
}
}
int main()
{
int shuzu[SIZE];
srand(time(NULL));
for (int i = 0; i < SIZE; i++)
{
shuzu[i] = rand()%100;
}
printf("排序前的数组为:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
SelectionSort(shuzu, SIZE);
printf("排序后的数组为:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.结果展示
四 插入排序
4.1动态图解
4.2基本思路
4.2.1核心思路
插入排序的规则是:第一轮开始时默认序列中第一个数据是有序的,之后各个数据以此为基准,判断是插入在此数据的前面还是后面,之后的数据依次向后移动,腾出位置,让数据插入,以此类推,直到整个序列有序为止。每比较一次,如果满足条件(升序:前面一个数比后面需要插入的数大),就直接交换。
4.2.2算法实现
void Insort(int x[], int n)//插入排序
{
for (int i = 1; i < N; i++)//i数据以此为基准
{
for (int j = i; j >= 0; j--)//内循环是比较
{
if (x[j]<x[j - 1]) //如果前面有序数列的值比后面的大,就依次交换
{
int k = x[j];//交换
x[j] = x[j - 1];
x[j - 1] = k;
}
}
}
}
4.3排序示例
1代码实现
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void Insort(int x[], int N) //插入排序
{
for (int i = 1; i < N; i++)//i数据以此为基准
{
for (int j = i; j >= 0; j--)//内循环是比较
{
if (x[j]<x[j - 1]) //如果前面有序数列的值比后面的大,就依次交换
{
int k = x[j];//交换
x[j] = x[j - 1];
x[j - 1] = k;
}
}
printf("第%d步排序结果:", i);
for (int h = 0; h < N; h++)
{
printf("%3d ", x[h]);
}
printf("\n");
}
}
int main()
{
int shuzu[SIZE];
srand(time(NULL));//生成随机数种子
for (int i = 0; i < SIZE; i++)//随机产生SIZE个数据
{
shuzu[i] = rand()%100;//随机数据在100以内
}
printf("排序前的数组为:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
Insort(shuzu, SIZE);
printf("排序后的数组为:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.结果展示
五 快速排序
5.1动态图解
5.2基本思路
5.2.1核心思路
快速排序的基本思想是:通过一趟排序将待排序的序列划分为独立的两部分,其中一部分的数据比另一部分的数据小,然后再分别对这两部分记录继续进行排序,直到整个序列有序。
一趟快速排序的具体做法是:设置两个标记low和high,它们初始值分别指向序列的第一个数据和最后一个数据,并设置一个中枢变量key,初始值记录序列第一个数据的值。首先high指针向前搜索,如果找到有数据小于中枢变量key的,则将其数据与中枢变量互相交换;然后low指针向后搜索,如果找到第一个关键字大于中枢变量key的,则将其数据与中枢变量互相交换;重复上述步骤,直到low==high为止。
5.2.2算法实现
void QuickSort(int x[],int low,int high)
{
int i, j, key; //变量key是用来保存当前参考元素的值
if (low<high) //判断高低位标记是否重合
{
key = x[low]; //key默认保存第一个元素的值
i = low; //用i代替最低下标low做运算
j = high; //用j代替最高下标high做运算
while (i < j) //判断高低位标记是否重合
{
//从数组后半部分向前比较,找到小于参考元素值的位置,直到标记i和j重合
while (i < j && x[j] >= key)j--;
if (i < j) x[i++] = x[j]; //数组后半部分的较小元素往前丢
//从数组前半部分向后比较,找到大于参考元素值的位置,直到标记i和j重合
while (i < j && x[i] <= key)i++;
if (i < j) x[j--] = x[i]; //数组前半部分的较大元素往后丢
}
x[i] = key; //参考元素放回数组中
//把整个数组划分为两半部分,前半部分的元素总是比后半部分小
QuickSort(x, low, i - 1); //前半部分递归排序
QuickSort(x, i + 1, high); //后半部分递归排序
}
}
5.3排序示例
1代码实现
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 8
void QuickSort(int x[], int low, int high)//快速排序,后面满足条件的往前面丢,前面满足条件的往后面丢
{
int i, j, key; //变量key是用来保存当前参考元素的值
if (low<high) //判断高低位标记是否重合
{
key = x[low]; //key默认保存第一个元素的值
i = low; //用i代替最低下标low做运算
j = high; //用j代替最高下标high做运算
while (i < j) //判断高低位标记是否重合
{
//从数组后半部分向前比较,找到小于参考元素值的位置,直到标记i和j重合
while (i < j && x[j] >= key)j--;
if (i < j) x[i++] = x[j]; //数组后半部分的较小元素往前丢
//从数组前半部分向后比较,找到大于参考元素值的位置,直到标记i和j重合
while (i < j && x[i] <= key)i++;
if (i < j) x[j--] = x[i]; //数组前半部分的较大元素往后丢
}
x[i] = key; //参考元素放回数组中
//把整个数组划分为两半部分,前半部分的元素总是比后半部分小
printf("每一步交换结果:");
for (int h = 0; h < SIZE; h++)
{
printf("%3d ", x[h]);
}
printf("\n");
QuickSort(x, low, i - 1); //前半部分递归排序
QuickSort(x, i + 1, high); //后半部分递归排序
}
}
int main()
{
int shuzu[SIZE] , i;
srand((unsigned int)time(NULL));
for (i = 0; i < SIZE; i++)
{
shuzu[i] = rand()% 100;
}
printf("排序前的数组为:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
QuickSort(shuzu, 0, SIZE - 1);
printf("排序后的数组为:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.结果展示
六 总结
选择排序与冒泡排序的区别在于,冒泡排序每比较一次后,满足条件的数据就交换,而选择排序是每次比较后,记录满足条件数据的位置,一轮循环过后再作交换。
以上都是用到随机函数,产生一组随机数据进行排序,并且打印每一步的排序结果。如果对你有帮助的话,请点个赞吧!谢谢你的支持。