各种排序算法

本文深入解析了四种经典排序算法:选择排序、冒泡排序、快速排序和桶排序。通过详细的代码示例,阐述了每种算法的工作原理、实现过程及其特点。适合初学者理解和掌握排序算法的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.选择排序法

  每一轮执行后的a[i]都为剩下未排序的最大值,循环len-1次,结果就是从大到小的结果。

#include <stdio.h>
int main()
{
	int a[] = { 2, 6, 5, 8, 9 }, i, j, f, max,len;
	len = sizeof(a) / sizeof(a[0]);
	for (i = 0; i < len-1; i++)
	{
		f = i;             //假设f为这一轮循环最大值的下标
		for (j = i + 1; j < len; j++)
		{
			if (a[f] < a[j])
				f = j;    //改变最大值的下标
		}
		if (f != i)       //开始交换
		{
			max = a[f];
			a[f] = a[i];
			a[i] = max;
		}
	}
	for (i = 0; i < 5; i++)
		printf("%d", a[i]);
}

2.冒泡排序法

  一共需要len-1次循环,每次都把最小的值排到后面,所以每次都不需要再比较后面已经排好的i个值

#include <stdio.h>
int main()
{
	int a[] = { 2, 6, 5, 8, 9 }, i, j,len,max;
	len = sizeof(a) / sizeof(a[0]);
	for (i = 0; i < len - 1; i++)       //只需进行len-1次循环
		for (j = 0; j < len - i-1; j++) //已经排好的后面的i个不需要再进行排序
		{
			if (a[j] < a[j + 1])        //交换
			{
				max = a[j + 1];
				a[j + 1] = a[j];
				a[j] = max;
			}
		}

	for (i = 0; i < 5; i++)
		printf("%d", a[i]);
}

3.快速排列

从大到小排列先从左到右寻找,从小到大一定从右到左寻找。如:a[5]={6,1,2,7,9},排列a从小到大,如果先从左开始寻找,那么第一轮后a[0]与a[3]换位,偏离初衷了。

#include <stdio.h>
int a[10];
void quicksort(int left, int right)
{
	int f,i,j,t;
	if (left >= right)
		return;
	f = a[left];
	i = left;
	j = right;
	while (i != j)
	{
		while (a[j] >= f&&j>i)
			j--;
		while (a[i] <= f&&j > i)
			i++;
		if (j > i)
		{
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
	a[left] = a[i];
	a[i] = f;
	quicksort(left, i - 1);
	quicksort(i + 1, right);
	

}
main()
{
	int i,n;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", &a[i]);
	quicksort(0, n - 1);
	for (i = 0; i < n; i++)
		printf("%d ", a[i]);
}

 4.桶排序

#include<stdio.h>
int main()
{
	int a[] = { 2, 6, 5, 8, 9 }; //要进行排序的数组b
	int b[10000] = {0}; //对数组a先进行初始化,都变为0
	int i,j;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
		b[a[i]]++;  //计数,每出现一次就+1
	for (i = 0; i < 10000; i++)  //b[i]的值不为0,说明i出现过,值为几就出现过几次
		for (j = 0; j < b[i]; j++)
			printf("%d ", i);
	return 0;
}

5、堆排序

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <string.h>

typedef int HeapDataType;
enum HEAP_TYPE
{
    HEAP_BIG,   // 从大到小
    HEAP_SMALL, // 从小到大
    HEAP_TYPE_MAX
};
typedef struct
{
    HeapDataType *array;
    HEAP_TYPE type;
    int size;
    int capacity;
} Heap;

// 堆的初始化
void heap_init(Heap *pHeap, HEAP_TYPE type)
{
    assert(type < HEAP_TYPE_MAX);
    pHeap->array = NULL;
    pHeap->size = pHeap->capacity = 0;
    pHeap->type = type;
}

void heap_check(Heap *pHeap)
{
    assert(pHeap);
    assert(pHeap->array);
    assert(pHeap->type < HEAP_TYPE_MAX);
}

// 堆的销毁
void heap_destory(Heap *pHeap)
{
    free(pHeap->array);
    pHeap->size = pHeap->capacity = 0;
}

// 交换函数
void swap(int *px, int *py)
{
    int a = *px;
    *px = *py;
    *py = a;
}

// 堆的向上调整
void heap_adjustUp(HeapDataType *array, int child)
{
    int parent = (child - 1) / 2;
    while (child > 0)
    {

        if (array[child] > array[parent])
        {
            swap(&array[child], &array[parent]);
            child = parent;
            parent = (parent - 1) / 2;
        }
        else
        {
            break;
        }
    }
}

void heap_adjustUp(Heap *pHeap)
{
    heap_check(pHeap);
    HeapDataType *array = pHeap->array;
    int child = pHeap->size - 1;
    int parent = (child - 1) / 2;
    while (child > 0)
    {
        if ((pHeap->type == HEAP_BIG && array[child] > array[parent]) || (pHeap->type == HEAP_SMALL && array[child] < array[parent]))
        {
            swap(&array[child], &array[parent]);
            child = parent;
            parent = (parent - 1) / 2;
        }
        else
        {
            break;
        }
    }
}
void heap_adjustDown(Heap *pHeap)
{
    heap_check(pHeap);
    HeapDataType *array = pHeap->array;
    int size = pHeap->size;
    int parent = 0;
    int child = parent * 2 + 1;
    while (child < size)
    {
        if (child + 1 < size)
        {
            if (pHeap->type == HEAP_BIG && array[child] < array[child + 1])
            {
                child++;
            }
            else if (pHeap->type == HEAP_SMALL && array[child] > array[child + 1])
            {
                child++;
            }
        }
        if ((pHeap->type == HEAP_BIG && array[child] > array[parent]) || (pHeap->type == HEAP_SMALL && array[child] < array[parent]))
        {
            swap(&array[child], &array[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}
void heap_push(Heap *pHeap, HeapDataType val, HEAP_TYPE type)
{
    assert(pHeap);
    if (pHeap->capacity == pHeap->size)
    {
        int newCapacity = pHeap->capacity == 0 ? 4 : 2 * pHeap->capacity;
        HeapDataType *tmp = (HeapDataType *)realloc(pHeap->array, sizeof(HeapDataType) * newCapacity);
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }
        pHeap->array = tmp;
        pHeap->capacity = newCapacity;
    }
    pHeap->array[pHeap->size] = val;
    pHeap->size++;
    heap_adjustUp(pHeap);
}

// 取堆顶元素
HeapDataType heap_getTop(Heap *pHeap)
{
    assert(pHeap);
    return pHeap->array[0];
}

// 堆的头删
void heap_pop(Heap *pHeap)
{
    assert(pHeap);
    assert(pHeap->size > 0);
    swap(&pHeap->array[0], &pHeap->array[pHeap->size - 1]);
    pHeap->size--;
    heap_adjustDown(pHeap);
}

// 堆的判空
bool heap_empty(Heap *pHeap)
{
    heap_check(pHeap);
    return pHeap->size == 0;
}

int heap_sort(HeapDataType *array, int size, HEAP_TYPE type)
{
    Heap heap;
    heap_init(&heap, type);
    for (int i = 0; i < size; i++)
    {
        heap_push(&heap, array[i], type);
    }
    for (int i = 0; i < size; i++)
    {
        array[i] = heap_getTop(&heap);
        heap_pop(&heap);
    }
    heap_destory(&heap);
    return 1;
}

int main()
{
    HeapDataType *buff = NULL;
    int buffSize = 0;
    printf("请输入要排序的长度:\n");
    scanf("%d", &buffSize);
    assert(buffSize > 0);
    buff = (HeapDataType *)malloc(buffSize * sizeof(HeapDataType));
    assert(buff);
    printf("请输入%d个要排序的数字:\n", buffSize);
    for (int i = 0; i < buffSize; i++)
    {
        scanf("%d", &buff[i]);
    }
    printf("排序前:\n");
    for (int i = 0; i < buffSize; i++)
    {
        printf("%d ", buff[i]);
    }
    printf("\n");
    // 堆排序
    HeapDataType *buffSmall = (HeapDataType *)malloc(buffSize * sizeof(HeapDataType));
    memcpy(buffSmall, buff, buffSize * sizeof(HeapDataType));
    heap_sort(buffSmall, buffSize, HEAP_SMALL);
    printf("从小到大排序后:\n");
    for (int i = 0; i < buffSize; i++)
    {
        printf("%d ", buffSmall[i]);
    }
    printf("\n");
    HeapDataType *buffBig = (HeapDataType *)malloc(buffSize * sizeof(HeapDataType));
    memcpy(buffBig, buff, buffSize * sizeof(HeapDataType));
    heap_sort(buffBig, buffSize, HEAP_BIG);
    printf("从大到小排序后:\n");
    for (int i = 0; i < buffSize; i++)
    {
        printf("%d ", buffBig[i]);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

small_planet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值