七大排序算法详解:从原理到实现(希尔/堆排/快排/归并等)

目录

引言

1. 希尔排序(Shell Sort)

2. 堆排序(Heap Sort)

3. 快速排序(Quick Sort)

(1)PartSort1(快排原型)

(2)PartSort2(挖坑法)

(3)PartSort3(前后指针法)

扫描二维码关注公众号,回复: 17562772 查看本文章

4. 快速排序(Quick-random Sort)

(1).随机取key

(2)三数取中

5.非递归快速排序(Non-Recursive Quick Sort)

6.三路划分快速排序(3-Way Quick Sort)

7. 冒泡排序(Bubble Sort)

8. 插入排序(Insertion Sort)

9. 归并排序(Merge Sort)

10.非递归归并排序(Non-Recursive Merge Sort)

11. 选择排序(Selection Sort)

引言

排序算法是计算机科学的基石之一。本文将系统讲解7种经典排序算法,通过:
✅ 分步图解算法流程  
✅ 语言代码实现  
✅ 实测性能对比  
帮助你彻底掌握排序算法的核心原理与应用场景。

1. 希尔排序(Shell Sort)

原理
插入排序的改进版,通过将数组按增量序列分组(如间隔 gap = length/2),对每组进行插入排序,逐步缩小增量直至为1,最终进行一次全数组插入排序。
关键点

  • 增量序列的选择影响效率(常用 gap = gap/3 + 1)。

  • 时间复杂度:平均O(n log n) ~ O(n²)。

代码:

void ShellSort(int* a, int n)//希尔排序
{
	
	int gap = 10;
	while (gap > 1)
	{
		gap /= 2;
		for (int j = 0;j < gap;j++)
		{
			for (int i = j;i < n - gap;i = i + gap)
			{
				int end = i;
				int tmp = a[end + gap];
				while (end >= 0)
				{
					if (tmp <a[end])
					{
						a[end + gap] = a[end];
						end -= gap;
					}
					else
					{
						break;
					}
				}
				a[end + gap] = tmp;
			}
		}
	}
}

2. 堆排序(Heap Sort)

原理

  • 建堆:将数组视为完全二叉树,调整成最大堆(父节点值 ≥ 子节点)。

  • 排序:交换堆顶元素(最大值)与末尾元素,缩小堆范围并重新调整堆,重复直至有序。
    关键点

  • 时间复杂度:O(n log n),且是原地排序。

  • 不稳定排序

实现该代码需要我们把堆建立起来

堆代码:

//这是stack.h的代码
#pragma once


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDataType;
	typedef struct Stack
{
	STDataType * a;
	int capacity;
	int top;
}ST;
	void STInit(ST*ps);
	void STPush(ST* ps,STDataType x);
	void STPop(ST* ps);
	int STSize(ST* ps);
	bool STEmpty(ST* ps);
	void STDestroy(ST* ps);
	STDataType STTop(ST* ps);

//这是stack.c的代码
#include"stack.h"
void STInit(ST* ps)
{
    assert(ps);
    ps->a = malloc(sizeof(STDataType) * 4);
    if (ps->a == NULL)
    {
        perror("malloc fail");
        return;
    }
   ps-> capacity = 4;
    ps->top = 0;
}
void STPush(ST* ps, STDataType x)
{
    assert(ps);
    if (ps->top == ps->capacity)
    {
        STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);//新建一个变量加进去,需要我进行空间创建,然后扩容
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }
        ps->a = tmp;
        ps->capacity *= 2;
    }
    ps->a[ps->top] = x;
    ps->top++;

}
void STDestroy(ST* ps)
{
    assert(ps);
    free(ps->a);
    ps->a = NULL;
    ps->top = 0;
    ps->capacity = 0;
}
void STPop(ST* ps)
{
    assert(ps);
    assert(!STEmpty(ps));//等于空就报错
    ps->top--;
}
int STSize(ST* ps)
{
    assert(ps);
    return ps->top;
}
bool STEmpty(ST* ps)
{
    assert(ps);
    return ps->top == 0;
}
STDataType STTop(ST* ps)
{
    assert(ps);
    assert(!STEmpty(ps));//空的话咱们就不能取值了
    return ps->a[ps->top - 1];//是空的话就越界了,哥们

}//访问栈顶元素

堆排序代码:

void HeapSort(int* a, int n)//栈排序
{
	for (int i = (n - 1 - 1) / 2;i >= 0;--i)
	{
		AdjustDown(a, n, i);
	}
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[end], &a[0]);
		AdjustDown(a, end, 0);
		--end;
	}
}

3. 快速排序(Quick Sort)

原理

  • 分治策略:选基准值(pivot),将数组分为“小于pivot”和“大于pivot”两部分。

  • 递归排序:对左右子数组递归执行快排。
    关键点

  • 时间复杂度:平均O(n log n),最坏O(n²)(可通过随机选pivot优化)。

  • 不稳定排序

代码:

(1)PartSort1(快排原型)
int PartSort1