15.排序-冒泡排序
15.1 知识点
排序的基本概念
排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。常用的排序例子如下:
无序序列:8, 7, 1, 5, 4, 2, 6, 3, 9
有序序列(升序):1, 2, 3, 4, 5, 6, 7, 8, 9
有序序列(降序):9, 8, 7, 6, 5, 4, 3, 2, 1
在程序中,序列一般存储在数组中,因此排序往往是对数组进行排序:
int[] arr = new int[] { 8, 7, 1, 5, 4, 2, 6, 3, 9 };
冒泡排序的基本原理
冒泡排序的基本原理是通过两两比较相邻的元素,不停交换,比较多轮,将最大(或最小)的元素慢慢“冒泡”到正确的位置。
冒泡排序代码实现过程
第一步:每轮遍历比较数组中两两相邻的数
for (int n = 0; n < arr.Length - 1; n++)
{
// 比较第n个数和第n+1个数
}
第二步:满足条件时交换位置
for (int n = 0; n < arr.Length - 1; n++)
{
if (arr[n] > arr[n + 1])
{
// 如果第n个数比第n+1个数大,交换位置
int temp = arr[n];
arr[n] = arr[n + 1];
arr[n + 1] = temp;
}
}
第三步:比较的轮数
for (int m = 0; m < arr.Length; m++)
{
for (int n = 0; n < arr.Length - 1 - m; n++)
{
// 在每一轮中,比较相邻的元素
}
}
第四步:优化
确定位置的数字不用比较了: 每轮遍历后,本轮的极值(最大或最小)已经放到了对应的位置,所以下一轮不需要再比较。
特殊情况的优化: 外面声明一个标识
isSort
,用于表示该轮是否进行了交换。每一轮开始时默认没有进行过交换,当一轮结束后,如果isSort
还是false
,说明已经是最终的序列了,不需要再判断交换了。
bool isSort = false;
for (int m = 0; m < arr.Length; m++)
{
isSort = false;
for (int n = 0; n < arr.Length - 1 - m; n++)
{
if (arr[n] > arr[n + 1])
{
isSort = true;
int temp = arr[n];
arr[n] = arr[n + 1];
arr[n + 1] = temp;
}
}
if (!isSort)
{
break;
}
}
冒泡排序最终代码
bool isSort = false;
for (int m = 0; m < arr.Length; m++)
{
isSort = false;
for (int n = 0; n < arr.Length - 1 - m; n++)
{
if (arr[n] > arr[n + 1])
{
isSort = true;
int temp = arr[n];
arr[n] = arr[n + 1];
arr[n + 1] = temp;
}
}
if (!isSort)
{
break;
}
}
打印出排序后的数组
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " "); // 输出:1 2 3 4 5 6 7 8 9
}
总结
- 基本概念: 两两相邻,不停比较,不停交换,比较多轮。
- 套路写法: 两层循环,外层轮数,内层比较,两值比较,满足交换。
- 优化写法: 比过不比,加入
bool
标识。
15.2 知识点代码
using System;
namespace Lesson13_冒泡排序
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("冒泡排序");
#region 知识点一 排序的基本概念
//排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列
//常用的排序例子
// 8 7 1 5 4 2 6 3 9
// 把上面的这个无序序列 变为 有序(升序或降序)序列的过程
// 1 2 3 4 5 6 7 8 9 (升序)
// 9 8 7 6 5 4 3 2 1 (降序)
//在程序中 序列一般 存储在数组当中
//所以 排序往往是对 数组进行排序
int[] arr = new int[] { 8, 7, 1, 5, 4, 2, 6, 3, 9, };
//把数组里面的内容变为有序的
#endregion
#region 知识点二 冒泡排序基本原理
// 8 7 1 5 4 2 6 3 9
// 两两相邻
// 不停比较
// 不停交换
// 比较n轮
#endregion
#region 知识点三 冒泡排序代码实现过程
//第一步 每轮遍历比较数组中两两相邻的数
//8, 7, 1, 5, 4, 2, 6, 3, 9
//从头开始
//第n个数和第n+1个数 比较
//for (int n = 0; n < arr.Length - 1; n++)
//{
//}
//第二步 满足条件时交换位置
//如果 第n个数 比第n+1个数 大 他们就要交换位置
// 中间商不赚差价
//for (int n = 0; n < arr.Length - 1; n++)
//{
// if (arr[n] > arr[n + 1])
// {
// int temp = arr[n];
// arr[n] = arr[n + 1];
// arr[n + 1] = temp;
// }
//}
//第三步 比较的轮数
//有几个数 就比较多少轮
//进一次循环 就需要比较一轮
//for (int m = 0; m < arr.Length; m++)
//{
// for (int n = 0; n < arr.Length - 1; n++)
// {
// if (arr[n] > arr[n + 1])
// {
// int temp = arr[n];
// arr[n] = arr[n + 1];
// arr[n + 1] = temp;
// }
// }
//}
//第四步 优化
//1.确定位置的数字 不用比较了
// 确定了一轮后 本轮的极值(最大或者最小)已经放到了对应的位置(往后放)
// 每完成m轮 后面位置的数 就不用再参与比较了
// 所以 每轮遍历的比较的次数从arr.Length - 1改成arr.Length - 1 - m
//for (int m = 0; m < arr.Length; m++)
//{
// for (int n = 0; n < arr.Length - 1 - m; n++)
// {
// if (arr[n] > arr[n + 1])
// {
// int temp = arr[n];
// arr[n] = arr[n + 1];
// arr[n + 1] = temp;
// }
// }
//}
//2.特使情况的优化
//外面声明一个标识 来表示 该轮是否进行了交换
//每一轮开始时 默认没有进行过交换
//当一轮结束过后 如果isSort这个标识 还是false
//那就意味着 已经是最终的序列了 不需要再判断交换了
//bool isSort = false;
//for (int m = 0; m < arr.Length; m++)
//{
// isSort = false;
// for (int n = 0; n < arr.Length - 1 - m; n++)
// {
// if (arr[n] > arr[n + 1])
// {
// isSort = true;
// int temp = arr[n];
// arr[n] = arr[n + 1];
// arr[n + 1] = temp;
// }
// }
// if( !isSort )
// {
// break;
// }
//}
#endregion
#region 知识点四 冒泡排序最终代码
// 冒泡排序代码
bool isSort = false;
for (int m = 0; m < arr.Length; m++)
{
isSort = false;
for (int n = 0; n < arr.Length - 1 - m; n++)
{
if (arr[n] > arr[n + 1])
{
isSort = true;
int temp = arr[n];
arr[n] = arr[n + 1];
arr[n + 1] = temp;
}
}
if (!isSort)
{
break;
}
}
//打印出排序后的数组
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");//1 2 3 4 5 6 7 8 9
}
#endregion
//总结
//基本概念
//两两相邻
//不停比较
//不停交换
//比较m轮
//套路写法
//两层循环
//外层轮数
//内层比较
//两值比较
//满足交换
//优化写法
//1.比过不比
//2.加入bool
}
}
}
15.3 练习题
定义一个数组,长度为20,每个元素值随机0~100的数,使用冒泡排序进行升序排序或降序排序并打印
声明随机数组
int[] arr = new int[20];
Random r = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = r.Next(0, 101);
Console.Write(arr[i] + " ");
}
Console.WriteLine();
进行冒泡排序
//套路写法
//两层循环
//外层轮数
bool isSort = false;
for (int i = 0; i < arr.Length; i++)
{
isSort = false;
//内层比较
for (int j = 0; j < arr.Length - 1 - i; j++)
{
//两值比较
//满足交换
//降序还是升序 改这的比较条件就行了
//if (arr[j] > arr[j + 1])
if (arr[j] < arr[j + 1])
{
isSort = true;
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (!isSort)
{
break;
}
}
打印排序后的结果
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");
}
写一个函数,实现一个数组的排序,并返回结果。可以根据参数决定是升序还是降序
主函数外 class 语句块内
static int[] Sort(int[] array, bool isAscendingOrder)
{
//小优化 在循环外声明变量 可以提高一些性能
bool order;
int temp;
for (int i = 0; i < array.Length; i++)
{
for (int j = 0; j < array.Length - 1 - i; j++)
{
//根据传入的 升序降序类型 决定使用什么规则 然后返回给一个 bool 值
order = isAscendingOrder ? array[j] > array[j + 1] : array[j] < array[j + 1];
if (order)
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
主函数内
int[] arr2 = { 3, 7, 2, 1, 9, 8, 6, 5, 4 };
Console.WriteLine();
Sort(arr2, false);
for (int i = 0; i < arr2.Length; i++)
{
Console.Write(arr2[i] + " ");
}
15.4 练习题代码
using System;
namespace Lesson13_练习题
{
class Program
{
#region 练习题二
//主函数外 class语句块内
static int[] Sort(int[] array, bool isAscendingOrder)
{
//小优化 在循环外声明变量 可以提高一些性能
bool order;
int temp;
for (int i = 0; i < array.Length; i++)
{
for (int j = 0; j < array.Length - 1 - i; j++)
{
//根据传入的 升序降序类型 决定使用什么规则 然后返回给一个bool值
order = isAscendingOrder ? array[j] > array[j + 1] : array[j] < array[j + 1];
if (order)
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
#endregion
static void Main(string[] args)
{
Console.WriteLine("冒泡排序练习题");
#region 练习题一
//定义一个数组,长度为20,每个元素值随机0~100的数,使用冒泡排序进行升序排序或降序排序并打印
//声明随机数组
int[] arr = new int[20];
Random r = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = r.Next(0, 101);
Console.Write(arr[i] + " ");//35 34 68 40 33 1 58 3 95 87 37 17 35 13 22 66 9 25 2 20
}
Console.WriteLine();
//进行冒泡排序
//套路写法
//两层循环
//外层轮数
bool isSort = false;
for (int i = 0; i < arr.Length; i++)
{
isSort = false;
//内层比较
for (int j = 0; j < arr.Length - 1 - i; j++)
{
//两值比较
//满足交换
// 降序还是升序 改这的比较条件就行了
//if (arr[j] > arr[j + 1])
if ( arr[j] < arr[j + 1] )
{
isSort = true;
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if(!isSort)
{
break;
}
}
//打印排序后的结果
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");//95 87 68 66 58 40 37 35 35 34 33 25 22 20 17 13 9 3 2 1
}
#endregion
#region 练习题二
//写一个函数,实现一个数组的排序,并返回结果。可以根据参数决定是升序还是降序
//主函数内
int[] arr2 = { 3, 7, 2, 1, 9, 8, 6, 5, 4 };
Console.WriteLine();
Sort(arr2, false);
for (int i = 0; i < arr2.Length; i++)
{
Console.Write(arr2[i] + " ");//9 8 7 6 5 4 3 2 1
}
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com