C语言经典编程282例03排序(直接、冒泡、快速排序等)

018 直接插入排序

插入排序是把一个记录插入到已排序的有序序列中,使整个序列在插入该记录后仍然有序,插入排序中较简单的一种方法是直接插入排序,其插入位置的确定方法是将待插入的记录与有序区中的各记录自右向左依次比较其关键字值得大小,
要求: 使用直接插入排序法将数字由小到大排序。
——直接插入排序基本思想:每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
在这里插入图片描述

可以看出s[0]为监视参考的值,左边为排序好的值,右边为待排序的值,在这里插入图片描述

在这里插入图片描述

#include<stdio.h>
#include<math.h>

void insort(int s[], int n)
{
	int i, j;
	for(i = 2; i <= n; i++) //数组下标从2开始,s[0]做监视哨,s[1]开始数据无可比性
	{
		s[0] = s[i];		//给监视哨赋值
		j = i - 1;			//确定要比较元素最右边位置
		while(s[0] < s[j])
		{
			s[j + 1] = s[j];  	//数据右移
			j--;				//移向左边一个未可比数
		}
		s[j + 1] = s[0];		//在确定得位置插入s[i]
	}
	
}

  main()
{
	int a[11], i;
	printf(" 请输入10个数据\n    ");
	
//	scanf(" %d\n", &n);
	
	for(i = 1; i <= 10; i++)
	{
		scanf(" %d \n", &a[i]);
	}
	
	printf(" 原始顺序: \n    ");
	for(i = 1; i <= 10; i++)
	{
		printf(" %5d    ", a[i]);
	}
	
	insort(a, 10); 
		
	printf("\n 插入数据排序后顺序: \n    ");
	 
	for(i = 1; i < 11; i++)
	{
		printf(" %5d    ", a[i]);
	}
   	 
   	printf("\n    ");
 } 
//_____ me  ————————————————

#include<stdio.h>
#include<math.h>

  main()
{
	int a[100], n, i, j, temp;
	
	scanf(" %d\n", &n);				//确认输入的个数
	
	for(i = 0; i < n; i++)			//输入数组
	{
		scanf(" %d \n", &a[i]);
	}
	
	//进行比较。
	for(i = 0; i < n; i++)		
	{
		for(j = i + 1; j < n; j++)
		{
			if(a[i] > a[j])
			{
				temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}
	 
	 //输出
	for(i = 0; i < n; i++)
	{
		printf(" %02d    ", a[i]);
	}
 } 

019 希尔排序

用希尔排序法对一组数据由小到大进行排列,数据分别是:69、56、12、136、3、55、46、99、88、25

希尔排序:把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
在这里插入图片描述
在这里插入图片描述
例子说明:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<math.h>

 void shsort(int s[], int n)
 {
     int i, j, d;
	 d = n / 2;
	 
	 while(d >= 1)
	 {
	 	for(i = d + 1; i <= n; i++) //数组下标从d + 1 开始进行直接插入排序
	 	{
	 		s[0] = s[i];			//设置监视哨
	 		j = i - d;				//确定要进行比较元素最右的位置
	 		
	 		while((j > 0) && (s[0] < s[j]))
	 		{
	 			s[j + d] = s[j];	//数据右移
	 			j = j - d;			//向左移d个位置
	 			
			 }
			 s[j + d] = s[0];		//在确定位置插入s[i]
			 
	    }
		 
	 	d = d / 2;
	 }	
 	
 }  
 
  main()
{
	int a[11], i;
	
	printf(" 请输入10个数据\n ");
	
	for(i = 1; i < 11; i++)			//输入数组
	{
		scanf(" %d \n", &a[i]);
	}
	shsort(a, 10);					//希尔比较
	
	printf(" 排序后的顺序\n ");
	 
	 //输出
	for(i = 1; i < 11; i++)
	{
		printf(" %5d    ", a[i]);
	}
 } 

020 冒泡排序

冒泡法:如果要对n个数进行冒泡排序,那要进行n - 1 躺比较,在第一趟n-1次两两比较,在第j趟比较中要进行n - i次次两两比较。
用冒泡法对任意输入的10个数由小到大进行排序,

#include<stdio.h>
#include<math.h>
 
  main()
{
	int a[11], i, j, t;
	
	printf(" 请输入10个数据\n ");
	
	for(i = 0; i < 10; i++)			//输入数组
	{
		scanf(" %d \n", &a[i]);
	}

    for(i = 1; i < 10; i++)         //冒泡法
    {
    	for(j = 0; j < 10 - i; j++ )
    	{
    		if(a[j] > a[ j + 1])
			{
			   	t = a[j];
				a[j] = a[j +1];
				a[j + 1] = t;	
			}
		}
	}
	
	printf(" 排序后的顺序\n ");
	 
	 //输出
	for(i = 0; i < 10; i++)
	{
		printf(" %5d    ", a[i]);
	}
 } 

在这里插入图片描述

021 快速排序

快速排序:在待排序的n个数据中取第一个数据作为基准值,

  • 第一趟分割:将所有记录分为3组,使第一组中各数据值均小于或等于基准值,第二组做基准值的数据,第三组中各数据值均大于或等于基准值,
  • 然后再对第一组和第二组分别重复上诉方法。

步骤:
①、挑选基准值:从数列中挑出一个元素,称为“基准”(pivot),
②、分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成,
③、递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。

在这里插入图片描述

用快速排序法对一组数据由小到大进行排序,数据分别为:99、45、12、36、69、22、62、796、4、696
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<math.h>
 
void qusort(int s[], int start, int end)
{
	int i, j;
	i = start;
	j = end;
	s[0] = s[start];               		//参考基准
	
	while(i < j)
	{
		while(i < j && s[0] < s[j])		//位置左移
		{
			j--;

		}
		
		if(i < j)
		{
			s[i] = s[j];				//将s[j]放在a[i]位置
			i++;						//位置右移
			 
		}
		
		while(i < j && s[i] <= s[0])
		{
			i++;
		}
		
		if(i < j)
		{
			s[j] = s[i];				//将大于基准的s[i]放在s[j]
			j--;						//左移
		}
	}
	
	s[i] = s[0];
	//对分割出的部分递归调用qusort
	if(start < i)
	{
		qusort(s, start, j-1);
	}
		
	if(i < end)
	{
		qusort(s, j + 1, end);
	}
}
 
  main()
{
	int a[11], i;
	
	printf(" 请输入10个数据\n ");
	
	for(i = 1; i <= 10; i++)			//输入数组
	{
		scanf(" %d \n", &a[i]);
	}
    
    qusort(a, 1, 10);
	
	printf(" 排序后的顺序\n ");
	 
	 //输出
	for(i = 1; i <= 10; i++)
	{
		printf(" %5d    ", a[i]);
	}
 } 

022 选择排序

选择算法:从待排序的区间中经过选择和交换后选出最小(最大)的数值存放在a[0]中,再从剩余的未排序区间中经过选择和交换后选出最小(最大)的数值存在a[1]中,依次类推。

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,
然后,再从剩余未排序元素中继续寻找最小(大)元素,
然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
——维基百科

在这里插入图片描述

用选择排序对一组数据由小到大进行排序,数据分别为:526、36、2、369、56、45、78、92、125、52

在这里插入图片描述

#include<stdio.h>
#include<math.h>

  main()
{
	int a[11], i, j, t;
	
	printf(" 请输入10个数据\n ");
	
	for(i = 1; i <= 10; i++)			//输入数组
	{
		scanf(" %d \n", &a[i]);
	}
    
    for(i = 1; i < 10; i++)
	{
		for(j = i + 1; j < 11; j++)
		{
			if(a[i] > a[j])  //如果前一个比后一个大,互换
			{
				t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
		}
	 } 
	 
	printf(" 排序后的顺序\n ");
	 
	 //输出
	for(i = 1; i <= 10; i++)
	{
		printf(" %5d    ", a[i]);
	}
 } 

023 归并排序

归并是将两个或多个有序记录序列合并成一个有序序列。采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
在这里插入图片描述

  • 归并方法:

  • 一次对两个有序记录序列进行归并——二路归并排序。

  • 三路归并排序以及多路归并排序

  • 基本方法:

  • 将n个记录堪称是n个长度为1的有序子表

  • 将两两相邻的有序子表进行归并

  • 重复执行步骤(2),直到归并成一个长度为n的有序表。

在这里插入图片描述
用归并排序对一组数据由小到大进行排序,数据:695、458、362、789、12、15、163、23、2、986

#include<stdio.h>
#include<math.h>

void merge(int r[], int s[], int x1, int x2, int x3)
{
	int i, j, k;
	i = x1;
	j = x2 + 1;
	k = x1;

	while ((i <= x2) && (j <= x3))
	{
		if (r[i] <= r[j])
		{
			s[k] = r[i];
			i++;
			k++;
		}
		else
		{
			s[k] = r[j];
			j++;
			k++;
		}
	}

	while (i <= x2)
	{
		s[k++] = r[i++];
	}

	while (j <= x3)
	{
		s[k++] = r[j++];
	}

}

void merge_sort(int r[], int s[], int m, int n)
{
	int p;
	int t[20];

	if (m == n)
	{
		s[m] = r[m];
	}
	else
	{
		p = (m + n) / 2;
		merge_sort(r, t, m, p);
		merge_sort(r, t, p + 1, n);
		merge(t, s, m, p, n);
	}
}

main()
{
	int a[11], i, j, t;

	printf(" 请输入10个数据\n ");

	for (i = 1; i <= 10; i++)			//输入数组
	{
		scanf_s(" %d \n", &a[i]);
	}

	merge_sort(a, a, 1, 10);

	printf(" 排序后的顺序\n ");

	//输出
	for (i = 1; i <= 10; i++)
	{
		printf(" %5d    ", a[i]);
	}
}

参考文献: 希尔排序:https://www.cnblogs.com/chengxiao/p/6104371.html
快速排序:https://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F
选择排序:https://zh.wikipedia.org/wiki/%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F
归并排序:https://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F
https://www.cnblogs.com/chengxiao/p/6194356.html

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您介绍这几种排序算法的 C 语言实现。 1. 冒泡排序算法 冒泡排序是一种简单的排序算法,其基本思想是通过不断交换相邻的元素,将最大或最小的元素逐步“冒泡”到序列的顶部(或底部)。具体实现如下: ``` void bubble_sort(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; } } } } ``` 2. 选择排序算法 选择排序是一种简单的排序算法,其基本思想是每次从未排序的部分中选出最小的元素,放到已排序的部分的末尾。具体实现如下: ``` void selection_sort(int arr[], int len) { int i, j, min_idx, temp; for (i = 0; i < len - 1; i++) { min_idx = i; for (j = i + 1; j < len; j++) { if (arr[j] < arr[min_idx]) { min_idx = j; } } temp = arr[i]; arr[i] = arr[min_idx]; arr[min_idx] = temp; } } ``` 3. 插入排序算法 插入排序是一种简单的排序算法,其基本思想是将未排序的元素逐个插入到已排序的部分中,使得已排序的部分仍然有序。具体实现如下: ``` void insertion_sort(int arr[], int len) { int i, j, key; for (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. 快速排序算法 快速排序是一种高效的排序算法,其基本思想是通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有元素都比另一部分小,然后递归地对这两部分继续进行排序。具体实现如下: ``` void quick_sort(int arr[], int left, int right) { if (left >= right) { return; } int i, j, pivot, temp; pivot = arr[left]; i = left; j = right; while (i < j) { while (i < j && arr[j] >= pivot) { j--; } while (i < j && arr[i] <= pivot) { i++; } if (i < j) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } arr[left] = arr[i]; arr[i] = pivot; quick_sort(arr, left, i - 1); quick_sort(arr, i + 1, right); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值