发布网友 发布时间:2022-04-14 22:43
共14个回答
懂视网 时间:2022-04-15 03:04
简化版的桶排序不仅仅有上一节所遗留的问题,更要命的是:它非常浪费空间!例如需要排序数的范围是0~2100000000之间,那你则需要申请2100000001个变量,也就是说要写成int a[2100000001]。因为我们需要用2100000001个“桶”来存储0~2100000000之间每一个数出
简化版的桶排序不仅仅有上一节所遗留的问题,更要命的是:它非常浪费空间!例如需要排序数的范围是0~2100000000之间,那你则需要申请2100000001个变量,也就是说要写成int a[2100000001]。因为我们需要用2100000001个“桶”来存储0~2100000000之间每一个数出现的次数。即便只给你5个数进行排序(例如这5个数是1,1912345678,2100000000,18000000和912345678),你也仍然需要2100000001个“桶”,这真是太浪费了空间了!还有,如果现在需要排序的不再是整数而是一些小数,比如将5.56789,2.12,1.1,3.123,4.1234这五个数进行从小大排序又该怎么办呢?现在我们来学习另一种新的排序算法:冒泡排序。它可以很好的解决这两个问题。
冒泡排序的基本思想是:每次比较两个相邻的元素,如果他们的顺序错误就把他们交换过来。
例如我们需要将12 35 99 18 76这5个数进行从大到小进行排序。既然是从大到小排序也就是说越小的越靠后,你是不是觉得我在说废话,但是这句话很关键(∩_∩)。
首先比较第1位和第2位的大小,现在第1位是12,第2位是35。发现12比35要小,因为我们希望越小越靠后嘛,因此需要交换这两个数的位置。交换之后这5个数的顺序是35 12 99 18 76。
按照刚才的方法,继续比较第2位和第3位的大小,第2位是12,第3位是99。12比99要小,因此需要交换这两个数的位置。交换之后这5个数的顺序是35 99 12 18 76。
根据刚才的规则,继续比较第3位和第4位的大小,如果第3位比第4位小,则交换位置。交换之后这5个数的顺序是35 99 18 12 76。
最后,比较第4位和第5位。4次比较之后5个数的顺序是35 99 18 76 12。
经过4次比较后我们发现最小的一个数已经就位(已经在最后一位,请注意12这个数的移动过程),是不是很神奇。现在再来回忆一下刚才比较的过程。每次都是比较相邻的两个数,如果后面的数比前面的数大,则交换这两个数的位置。一直比较下去直到最后两个数比较完毕后,最小的数就在最后一个了。就如同是一个气泡,一步一步往后“翻滚”,直到最后一位。所以这个排序的方法有一个很好听的名字“冒泡排序”。
说道这里其实我们的排序只将5个数中最小的一个归位了。每将一个数归位我们将其称为“一趟”。下面我们将继续重复刚才的过程,将剩下的4个数一一归位。
好现在开始“第二趟”,目标是将第2小的数归位。首先还是先比较第1位和第2位,如果第1位比第2位小,则交换位置。交换之后这5个数的顺序是99 35 18 76 12。接下来你应该都会了,依次比较第2位和第3位,第3位和第4位。注意此时已经不需要再比较第4位和第5位。因为在第一趟结束后已经可以确定第5位上放的是最小的了。第二趟结束之后这5个数的顺序是99 35 76 18 12。
“第三趟”也是一样的。第三趟之后这5个数的顺序是99 76 35 18 12。
现在到了最后一趟“第四趟”。有的同学又要问了,这不是已经排好了吗?还要继续?当然,这里纯属巧合,你可以用别的数试一试可能就不是了。你能找出这样的数据样例来吗?请试一试。
“冒泡排序”原理是:每一趟只能确定将一个数归位。即第一趟只能确定将末位上的数(既第5位)归位,第二趟只能将倒数第2位上的数(既第4位)归位,第三趟只能将倒数第3位上的数(既第3位)归位,而现在前面还有两个位置上的数没有归位,因此我们仍然需要进行“第四趟”。
“第四趟”只需要比较第1位和第2位的大小。因为后面三个位置上的数归位了,现在第1位是99,第2位是76,无需交换。这5个数的顺序不变仍然是99 76 35 18 12。到此排序完美结束了,5个数已经有4个数归位,那最后一个数也只能放在第1位了。
最后我们总结一下:如果有n个数进行排序,只需将n-1个数归位,也就是说要进行n-1趟操作。而“每一趟”都需要从第1位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较(已经归位的数你还比较个啥,浪费表情)。
这个算法是不是很强悍。记得我每次拍集体照的时候就总是被别人换来换去的,当时特别烦。不知道发明此算法的人当时的灵感是否来源于此。罗里吧嗦地说了这么多,下面是代码。建议先自己尝试去实现一下看看,再来看我是如何实现的。
#includeint main() { int a[100],i,j,t,n; scanf("%d",&n); //输入一个数n,表示接下来有n个数 for(i=1;i<=n;i++) //循环读入n个数到数组a中 scanf("%d",&a[i]); //冒泡排序的核心部分 for(i=1;i<=n-1;i++) //n个数排序,只用进行n-1趟 { for(j=1;j<=n-i;j++) //从第1位开始比较直到最后一个尚未归位的数,想一想为什么到n-i就可以了。 { if(a[j]
可以输入以下数据进行验证
10 8 100 50 22 15 6 1 1000 999 0运行结果是
0 1 6 8 15 22 50 100 999 1000
将上面代码稍加修改,就可以解决第1节遗留的问题,如下。
#includestruct student { char name[21]; char score; };//这里创建了一个结构体用来存储姓名和分数 int main() { struct student a[100],t; int i,j,n; scanf("%d",&n); //输入一个数n for(i=1;i<=n;i++) //循环读入n个人名和分数 scanf("%s %d",a[i].name,&a[i].score); //按分数从高到低进行排序 for(i=1;i<=n-1;i++) { for(j=1;j<=n-i;j++) { if(a[j].score
可以输入以下数据进行验证
5 huhu 5 haha 3 xixi 5 hengheng 2 gaoshou 8运行结果是
gaoshou huhu xixi haha hengheng
冒泡排序的核心部分是双重嵌套循环。不难看出冒泡排序的时间复杂度是O(N2)。这是一个非常高的时间复杂度。冒泡排序早在1956年就有人开始研究,之后有很多人都尝试过对冒泡排序进行改进,但结果却令人失望。如Knuth(Donald E. Knuth中文名为高德纳,1974年图灵奖获得者)所说:“冒泡排序除了它迷人的名字和导致了某些有趣的理论问题这一事实之外,似乎没有什么值得推荐的。”你可能要问:那还有没有更好的排序算法呢?请期待下周更新——快速排序。
【啊哈!算法】算法2:邻居好说话——冒泡排序
http://bbs.ahalei.com/thread-4400-1-1.html (出处: 啊哈磊_编程从这里起步)热心网友 时间:2022-04-15 00:12
冒泡排序算法有两种,一种是从大到小排,另一种是从小到大排。
冒泡排序依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
冒泡排序最核心的思想就是相邻的两个元素相比较,符合冒泡的才冒泡,重复多次执行,待最后没有需要冒泡的元素时才停止执行,表示排序已经完成。
冒泡排序也是一种稳定排序算法。因为冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变。
热心网友 时间:2022-04-15 01:30
有两种写法。
第一种思路:score[j] 和 score[j+1] 比较,如果前者比后者小,把前者和后者调换顺序,两两调换后一轮下来,最小的会被排到最后去。实现代码如下:
第二种思路:用 88 和 75 比较,再和69比较,再和 67 比较,发现88是最大的,把他排到第一位;然后 i=1,也就是第二轮,就不用看下标为 0 的 88 了。实现代码如下:
这就是冒泡排序的两种写法。
热心网友 时间:2022-04-15 03:05
冒泡排序算法有2种。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。假设有一个大小为 N 的无序序列。冒泡排序就是要每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排。
假设有一个无序序列 { 12 35 99 18 76 }
思路:
1、先比较第 1 位和第 2 位的大小,12<35,因为希望越小越靠后,所以要调整两者顺序,交换后的结果:35 12 99 18 76
2、现在比较第 2 位和第 3 位的大小,12<99,所以需要交换位置,交换后的结果为:35 99 12 18 76
3、接着比较第 3 位和第 4 位的大小,12<18,交换后的结果为:35 99 18 12 76
4、最后比较第 4 位和第 5 位的大小,12<76,交换后的结果为:35 99 18 76 12
5、经过 4 次后我们发现 5 个数中最小的一个数已经就位,每将一个数归位我们称其为“一趟”
6、现在我们开始第二趟,目标将第 2 小的数归位,根据之前逻辑,还是从第 1 个数和第 2 个数开始比较上:35 99 18 76 12 --①--> 99 35 18 76 12 --②--> 99 35 18 76 12 --③--> 99 35 76 18 12,在第一趟比较就知道第 5 位是最小的,所以第 4 位不用和第 5 位比较,这一趟只需比较 3 次
7、第3趟:99 35 76 18 12 --> 99 35 76 18 12 --> 99 76 35 18 12 (比较 2 次)
8、第4趟:99 76 35 18 12 --> 99 76 35 18 12 ,有4个数已经就位,那么最后一个数无须比较,它就是最大的
总结: 如果有 n 个数进行排序,只需将 n-1 个数归位,即要进行 n-1 趟操作,而每一趟开始都从第 1 位进行相邻的两个数 进行比较,将小的那个数放在后面,已经归位的就不用进行比较。
热心网友 时间:2022-04-15 04:56
冒泡排序算法有2种写法。
第一种思路:score[j] 和 score[j+1] 比较,如果前者比后者小,把前者和后者调换顺序,两两调换后一轮下来,最小的会被排到最后去。
第二种思路:用 88 和 75 比较,再和69比较,再和 67 比较,发现88是最大的,把他排到第一位;然后 i=1,也就是第二轮,就不用看下标为 0 的 88 了,因为他是老大,然后接着比较。
冒泡排序分从大到小和从小到大两种排序方式。它们的唯一区别就是两个数交换的条件不同,从大到小排序是前面的数比后面的小的时候交换,而从小到大排序是前面的数比后面的数大的时候交换。我这里只说 从小到大的排序方式。
冒泡排序的原理:从第一个数开始,依次往后比较,如果前面的数比后面的数大就交换,否则不作处理。这就类似烧开水时,壶底的水泡往上冒的过程。
每次把相邻的两个比较大小,然后把大一点儿的数据放在最后面,这样第一趟下来,最大的那个数就跑到了最后面,下一次排序就不用跟最后一个数字比较了,然后倒数第二大的数字会在倒数第二...因此可以使用两个函数,一个用于控制每一趟比较的元素个数,一个用于交换。
热心网友 时间:2022-04-15 07:04
有两种写法。
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。
所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
冒泡排序算法的原理如下:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
热心网友 时间:2022-04-15 09:29
冒泡排序算法的写法有好几种,具体的写法还是要看你自己对代码的优化。冒泡排序是十大经典排序算法之一。它的核心是重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
不过冒泡排序也有它的局限性:冒泡排序的每一个元素都可以像小气泡一样,根据自身大小,一点一点向着数组的一侧移动。算法的每一轮从都是从左到右比较元素,进行单向的位置交换。仅仅减少每次的排序次数并加以判断,还是不够的,冒泡排序的时间复杂度是O(n^2)还是比较大。
用Python来实现这种算法的写法是:
冒泡排序是排序算法中比较简单的一种,排序算法在计算机编程中也是一个很重要的基础,到公司面试的时候也有很大机会会考察你的算法能力,所以熟悉这些算法还是非常的有必要的。
热心网友 时间:2022-04-15 12:10
假如有几个数字int score[] = {67, 69, 75, 88}; 按照从大到小排序。
有2种思路,第一种,score[j] 和 score[j+1] 比较 如果 前者比后者小,把前者和后者调换顺序,两两调换后一轮下来 最小的会被排到最后去。每一轮j都从0开始,当i轮排序,就有最后面的i个数字因为他是最小的,所以后面的每轮都不用理他了,也就是 score.length-1-i 往后的数不用管了,如上,第一轮有4个数字 i为0 ,那么score.length-1-i 为3,也就是下标是3以后的可以不用管,3往后没有数字,所以第一轮所有的数字都要参加比较,第二轮I=1 score.length-1-i 为2 也就是说 下标2后面的 下标为3的数字不用比了,因为两两比较厚,67会到 score[3]。
第二种思路,用88 和 75 比较,在和69 比较 在和 67 比较,发现88是最大的,吧他排到第一位(index=0的位置),然后i=1,也就是第二轮,就不用看下标为0的88了因为他是老大,然后接着比较。热心网友 时间:2022-04-15 15:08
一个是从大到小排,第二个是从小到大排。冒泡方法是一样的,只不过第一个玩了点花头,同后面往前面算(跟一般人的想法不一样)。两个都是从小到大排序,都是在(list[i] > list[j])的情况下发生交换。冒泡排序既可以是从小到大,也可以是从大到小。热心网友 时间:2022-04-15 18:23
冒泡排序算法有4种写法。
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。热心网友 时间:2022-04-15 21:54
public static void main(String[] args){
int [] arr= {6,5,4,2,1,7,9,8,10};//新建一个数组
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length-1;j++){
if (arr[j]>arr[j+1]){
//区分较大值和较小值
int bigger=arr[j];
int smaller=arr[j+1];
arr[j]=smaller;//较小的放在左边
arr[j+1]=bigger;//较大的放在右边
}
}
}
//遍历输出
for (int m=0;m<arr.length;m++){
System.out.println(arr[m]);
}
}热心网友 时间:2022-04-16 01:42
有2种思路:
第一种思路:score[j] 和 score[j+1] 比较,如果前者比后者小,把前者和后者调换顺序,两两调换后一轮下来,最小的会被排到最后去。
每一轮j都从0开始,当i轮排序,就有最后面的i个数字因为他是最小的,所以后面的每轮都不用理他了,也就是 score.length-1-i 往后的数不用管了,如上,第一轮有4个数字 i为0 ,那么score.length-1-i 为3,也就是下标是3以后的可以不用管,3往后没有数字,所以第一轮所有的数字都要参加比较,第二轮i=1,score.length-1-i 为2 也就是说 下标2后面的 下标为3的数字不用比了,因为两两比较厚,67会到 score[3],实现代码如下:
第二种思路:用 88 和 75 比较,再和69比较,再和 67 比较,发现88是最大的,把他排到第一位;然后 i=1,也就是第二轮,就不用看下标为 0 的 88 了,因为他是老大,然后接着比较。热心网友 时间:2022-04-16 05:47
五种写法。
class Program
{
static void Main(string[] args)
{
int[] a = { 3, 1, 2, 4, 7, 8, 6, 5, 9 };
Program b = new Program();
//b.MaoPaoOne(a);
//b.MaoPaoTwo(a);
//b.MaoPaoThree(a);
//b.MaoPaoFour(a);//第四种方法最优!!
b.MaoPaoFive(a);
foreach (int temp in a) {
Console.Write(temp + " ");
}
Console.ReadKey();
}
public void Swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public void MaoPaoOne(int [] arr) {
for (int i = 0; i < arr.Length; i++) {
for (int j = i + 1; j < arr.Length; j++) {
if (arr[i] > arr[j]) {
Swap(arr, i, j);
}
}
}
}
public void MaoPaoTwo(int[] arr) {
for (int i = 0; i < arr.Length; i++)
{
for (int j = i; j < arr.Length-1; j++) {
if (arr[j] > arr[j + 1]) {
Swap(arr, j, j + 1);
}
}
}
}
public void MaoPaoThree(int[] arr) {
for (int i = 0; i < arr.Length; i++) {
for (int j = arr.Length -i-2; j >= 0; j--) {
if (arr[j] > arr[j + 1])
Swap(arr, j, j + 1);
}
}
}
public void MaoPaoFour(int[] arr) {
bool isFinish=true;
for (int i = 0; i < arr.Length&&isFinish; i++)
{
isFinish = false;
for (int j = 0 + i; j < arr.Length - 1 && !isFinish; j++)
{
if (arr[j] > arr[j + 1])
{
Swap(arr, j, j + 1);
isFinish = true;
}
}
}
}
public void MaoPaoFive(int[] arr) {
bool isFinish = true;
while (isFinish) {
isFinish = false;
for (int i = 0; i < arr.Length-1; i++) {
if (arr[i] > arr[i + 1]) {
Swap(arr, i, i + 1);
isFinish = true;
}
}
}
}
}热心网友 时间:2022-04-16 10:08
有两种。
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到最大数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最大数。如此下去,直至最终完成排序。