冒泡排序
每次进行两两比较,大的或者小的就往后移,每进行一次,最后一个数就是已经排好序的。
#include <stdio.h>
void bullerSort(int arr[], int len)
{
int i,j,temp;
for (i = 0; i < len - 1; i++)
{
for (j = 0; j < len - 1 - i; j++)
{
if (arr[j]>arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//遍历
void print(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[10]={
5,9,11,32,18,54,78,0,87,111};
bullerSort(arr,10);
print(arr,10);
printf("\n");
return 0;
}
桶排序
准备桶的时候,桶的大小是原来排序数组中最大元素的值加一,然后遍历无序的数组,把无序数组中的元素的值当成下标给到桶,每存在一个值,桶中的数量就加一。输出的时候,桶的下标值就是之前需要排序的数组的值,只有桶中的数量大于等于一的时候才表示有数据,再进行输出
简单地说: 待排序数组 分配到若干个桶 各自执行排序任务
#include <stdio.h>
#include <stdlib.h>
int main()
{
//桶排序
//先准备桶 桶的大小是需要排序数组中的最大元素的值加一
int app[10] = {
0 };
//无序的数组
int arr[9]={
5,4,8,6,2,0,3,7,9};
// 遍历无序的数组,把无序数组中的元素的值当成下标给到桶
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)//
{
app[arr[i]]++;
}
//输出,把对应的元素出现了几次进行一个输出
for (int i = 0; i < 10; i++)
{
for (int j = 1; j <= app[i]; j++)
{
printf("%d \n", i);
}
}
return 0;
}
选择排序
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕
#include <stdio.h>
#include <string.h>
//选择排序
void selectSort(int arr[], int len)
{
int min;
for (int i = 0; i < len-1; i++)
{
min = i;//假设第一个元素是最小的
for (int j = i + 1; j < len; j++)
{
if (arr[j] < arr[min])
{
min = j;//保存最小元素的下标
}
}
//交换
int temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
//输出
void print(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[15]={
3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
len = strlen(arr);
selectSort(arr,len);
print(arr,len);
printf("\n");
return 0;
}
插入排序
选择元素,插入有序数组
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
#include <stdio.h>
//插入排序
void insertSort(int arr[], int len)
{
int temp;//保存要插入的元素
int j;//从当前要要比较插入的元素的前面一个开始
for (int i = 1; i < len; i++)//第一个元素视为有序,把后面的元素一个一个的插入到前面
{
temp = arr[i];
j = i - 1;
while (j >= 0 && arr[j]>temp)
{
arr[j + 1] = arr[j];//前面的元素往后面移动
j--;
}
arr[j + 1] = temp;//把要插入的元素,插入进对应的位置
}
}
//输出
void print(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[15]={
3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
insertSort(arr,15);
print(arr,15);
printf("\n");
return 0;
}
快速排序*
通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
- 从数列中挑出一个元素,称为 “基准”(pivot)
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到
任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作 - 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序
简单地说:
每次选出一个基准值,小于放在左边,大于它的放右边,重复完成。
#include <stdio.h>
//快速排序
void quickSort(int arr[], int lift, int right)
{
if (lift > right)
return;
int i = lift, j = right, temp = arr[i];//获取左右和基准数
while (i < j)
{
while (temp < arr[j] && i < j)
j--;
if (i < j)
arr[i++] = arr[j];
while (temp > arr[i] && i < j)
i++;
if (i < j)
arr[j--] = arr[i];
}
arr[i] = temp;
quickSort(arr, lift, i - 1);//左边
quickSort(arr, i + 1, right);//右边
}
//输出
void print(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[15]={
3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
quickSort(arr,0,14);
print(arr,15);
printf("\n");
return 0;
}
堆排序
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点
- 初始化数组,创建大顶堆。
- 大顶堆的创建从下往上比较,不能直接用无序数组从根节点比较,否则有的不符合大顶堆的定义
- 交换根节点和倒数第一个数据,现在倒数第一个数据就是最大的
- 重新建立大顶堆
- 因为只有 array[0] 改变,其它都符合大顶堆的定义,所以可以根节点 array[0] 重新建立
- 重复3,4的步骤,直到只剩根节点 array[0],即 i=1
交换函数:void swap(int array[],int x,int y)
初始化大顶堆函数:void BuildHeap(int array[],int size)
生成大顶堆函数:void Down(int array[],int i,int n)
排序函数:void heapSort(int array[],int size)
#include <stdio.h>
void display(int array[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
void swap(int array[], int x, int y) {
int key = array[x];
array[x] = array[y];
array[y] = key;
}
// 从大到小排序
// void Down(int array[], int i, int n) {
// int child = 2 * i + 1;
// int key = array[i];
// while (child < n) {
// if (child + 1 < n && array[child] > array[child + 1]) {
// child++;
// }
// if (key > array[child]) {
// swap(array, i, child);
// i = child;
// } else {
// break;
// }
// child = child * 2 + 1;
// }
// }
// 从小到大排序
void Down(int array[], int i, int n) {
// 最后结果就是大顶堆
int parent = i; // 父节点下标
int child = 2 * i + 1; // 子节点下标
while (child < n) {
if (child + 1 < n && array[child] < array[child + 1]) {
// 判断子节点那个大,大的与父节点比较
child++;
}
if (array[parent] < array[child]) {
// 判断父节点是否小于子节点
swap(array, parent, child); // 交换父节点和子节点
parent = child; // 子节点下标 赋给 父节点下标
}
child = child * 2 + 1; // 换行,比较下面的父节点和子节点
}
}
void BuildHeap(int array[], int size) {
for (int i = size / 2 - 1; i >= 0; i--) {
// 倒数第二排开始, 创建大顶堆,必须从下往上比较
Down(array, i, size); // 否则有的不符合大顶堆定义
}
}
void HeapSort(int array[], int size) {
printf("初始化数组:");
BuildHeap(array, size); // 初始化堆
display(array, size); // 查看初始化结果
for (int i = size - 1; i > 0; i--) {
swap(array, 0, i); // 交换顶点和第 i 个数据
// 因为只有array[0]改变,其它都符合大顶堆的定义,所以可以从上往下重新建立
Down(array, 0, i); // 重新建立大顶堆
printf("排序的数组:");
display(array, size);
}
}
int main() {
int array[] = {
49, 38, 65, 97, 76, 13, 27, 49, 10};
int size = sizeof(array) / sizeof(int);
// 打印数据
printf("%d \n", size);
printf("排序前数组:");
display(array, size);
HeapSort(array, size);
return 0;
}