C语言算法——排序

冒泡排序

每次进行两两比较,大的或者小的就往后移,每进行一次,最后一个数就是已经排好序的。

#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;
}

猜你喜欢

转载自blog.csdn.net/weixin_45824920/article/details/114467405
今日推荐