七大经典排序算法(排序思想、算法步骤、代码实现)--C语言

1、冒泡排序

冒泡排序思想:冒泡排序是一种简单直观的排序算法,它需要重复循环遍历,每次两两比较,最后确定一个最大值,直到全部元素都被有序化,这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
算法步骤:
Step1:相邻元素进行比较,若前一个比后一个大,则进行交换。
Step2:对每一对相邻元素都进行比较,从第一对到最后一对,一次下来确定一个最大的元素。
Step3:针对所有元素重复以上步骤。

代码实现:

#include<stdio.h>
//冒泡排序
void bubble_sort(int arr[], int len)
{
	int i, j, temp;
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		//循环完一次末尾都会确定一个最大的数字,已经排序好的末尾的数字不参与比较
		{
			if (arr[j]>arr[j + 1])
			{
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
	int len = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, len);
	for (int i = 0; i < len; i++)
	{
		printf("%d->", arr[i]);
	}
	printf("\n");
	return 0;
}

2、选择排序

选择排序思想: 选择排序也是一种简单的排序算法,它也是循环遍历数组,每次只确定未排序元素中的一个最小(大)值。
算法步骤:(假如排好后为升序数组)
Step1:在未排序数组中先选出一个最小值放到排序序列的起始位置
Step2:再从未排序序列中寻找最小元素放到已排序序列的末尾
Step3:重复第二步直到所有元素排序完毕

void swap(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = *a;
}
void select_sort(int arr[], int len)
{
	int i, j, min;
	for (int i = 0; i < len; i++)
	{
		min = i;
		for (int j = i + 1; j < len - i; j++)
		{
			if (arr[j] < arr[min])
			{
				min = j;
			}
			swap(&arr[j], &arr[min]);
		}
	}
}

3、插入排序

插入排序思想: 插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
算法步骤:
1.将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
2.从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

代码:

void Insert_sort(int arr[], int len)
{
	int i, j, key;
	for (int i = 1; i < len; i++)
	{
		key = arr[i];
		j = i - 1;
		while (j >= 0 && arr[j] > key)
		{
			arr[j + 1] = arr[j];
			j--;
		}
		arr[j + 1] = key;
	}
}

4、希尔排序

希尔排序思想: 希尔排序也叫做缩小增量排序,它通过先设置一个增量n,大小为数组长度的一半,将间隔为n的元素视作一个组,然后对每个组内部的元素进行从小到大进行插入排序;然后再将增量n缩小一半,再次进行分组插入排序,直到增量n为1,因为增量为1的时候,所有的元素都为同一个组了
算法步骤:
Step1:选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
Step2:按增量序列个数 k,对序列进行 k 趟排序;
Step3:每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直 接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度 。

void shellsort(int *ar, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 2;
		int i = 0;
		for (i = 0; i < n - gap; ++i)
		{
			int end = i;
			int tmp = ar[end + gap];
			while (end >= 0)
			{
				if (tmp < ar[end])
				{
					ar[end + gap] = ar[end];
					end -= gap;
				}
				else
					break;
			}
			ar[end + gap] = tmp;
		}
	}
}

5、归并排序

**归并排序思想:**归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采 用分治法(Divide and Conquer)的一个非常典型的应用。
Step 1:将n个元素分成两个含n/2元素的子序列
Step 2:用MS将两个子序列递归排序(最后可以将整个原序列分解成n个子序列)
Step 3:合并两个已排序好的序列

void merge(int *arr, int L, int M, int R){
	int left_size = M-L;
	int right_size = R-M+1;
	int *L_arr = new int [left_size];
	int *R_arr = new int [right_size];

	for(int i=L; i<M; i++)
		L_arr[i-L] = arr[i];
	for(int i=M; i<=R; i++)
		R_arr[i-M] = arr[i];

	int i = 0, j = 0, k = L;
	while(i < left_size && j < right_size)
		if(L_arr[i]<R_arr[j])
			arr[k++] = L_arr[i++];
		else
			arr[k++] = R_arr[j++];

	while(i < left_size)
		arr[k++] = L_arr[i++];
	while(j < right_size)
		arr[k++] = R_arr[j++];
}

void merge_sort(int *arr, int L, int R){
	if(L == R)
		return;
	else
	{
		int M = (L+R)/2;
		merge_sort(arr, L, M);
		merge_sort(arr, M+1, R);
		merge(arr, L, M+1, R);
	}
}

6、堆排序

堆排序思想: 是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
算法步骤:
Step1:最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
Step2:创建最大堆(Build Max Heap):将堆中的所有数据重新排序
Step3:堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

void swap(int arr[], int i, int j)
{
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}
void heapify(int tree[], int n,int i) //n代表有多少节点,i表示对哪一个节点进行操作
{
	if (i >= n)
		return;
	int c1 = 2 * i + 1;
	int c2 = 2 * i + 2;
	int max = i;
	//找出最大值
	if (c1<n && tree[c1] > tree[max])
		max = c1;
	if (c2<n && tree[c2] > tree[max])
		max = c2;
	//拿最大值和i做交换
	if (max != i)
	{
		swap(tree, max, i);
		heapify(tree, n, max);
	}
}
void build_heap(int tree[], int n)
{
	int last_node = n - 1;
	int parent = (last_node - 1) / 2;
	int i;
	for (i = parent; i >= 0; --i)
	{
		heapify(tree, n, i);
	}
}
void heap_sort(int tree[], int n)
{
	build_heap(tree, n);
	int i;
	for (i = n - 1; i >= 0; --i)
	{
		swap(tree, i, 0);//把建好的大堆做交换堆顶与最后一个元素交换
		heapify(tree, i, 0);
	}
}

7、快速排序

快速排序思想::快速排序算法是冒泡排序的一次改进,通过多次比较和交换来实现排序。
算法步骤:
Step1:首先在数组中选取一个分界值key,通过key将数组分成两部分。
Step2:将数组中大于等于key的元素集中到key的右边,将小于key的元素集中到key的左边
Step3:然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理

代码实现:

int _Partition(int *ar, int left, int right)
{
	int low = left, high = right;
	int key = ar[low];
	while (low < high)
	{
		while (low < high&&ar[high] > key)
			high--;
		swap(&ar[high], &ar[low]);
		while (low < high&&ar[low] <= key)
			low++;
		swap(&ar[low], &ar[high]);
	}
	return low;
}
void Quicksort(int ar[], int left, int right)
{
	if (left < right)
		return;
	int Pos = _Partition(ar, left, right);
		Quicksort(ar, left, Pos - 1);
		Quicksort(ar, Pos + 1, right);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值