数据结构——冒泡排序(C语言)

一、基本思想

冒泡排序是交换排序中最易理解也最经典的一个排序,其基本思想是从左向右依次比较相邻两个元素的大小,如果左边大于右边就交换,一趟排序后就可以让最大的值浮到最右侧。不断重复这个操作就可以让数组有序。
在这里插入图片描述

二、算法实现及优化

想要实现冒泡排序,我们首先写出一趟冒泡排序,很简单,从左向右依次比较即可,只要左边大于右边就发生交换

注意:
数组有n个元素,我们从数组的第1个元素开始比较,到数组的第n-1个元素结束,共比较了n-1次。例如下图,从第1个开始到第6个结束。一趟排序的代码就可以写出来:
在这里插入图片描述

		//1.第1趟排序,从第1个元素开始到n-1个元素结束,比较n-1次
		for (int j = 0; j < n-1; ++j)
		{
    
    
			//如果左边大于右边,则交换位置
			if (a[j] > a[j + 1])
			{
    
    
				Swap(&a[j], &a[j + 1]);
			}
		}

这样一趟排序下来就可以把最大的数字冒到最右边了,如果我们重复这个操作n-1次就可以把次大的数,再次大的数都冒到最右边,一个循环搞定

void BubbleSort1(int* a, int n)
{
    
    
  //排n趟就可以让数组有序
  int end=n-1;
  while(end>0)
  {
    
    
    //一趟排序,从第一个元素开始到n-1个元素结束,
     for(int j = 0; j<n-1; ++j)
     {
    
    
        //如果左边大于右边,就交换
        if(a[j]>a[j+1])
        {
    
    
          Swap(&a[j],&a[j+1]);
        }
     }
     --end;

    PrintArr(a,n);
  }
}

在这里插入图片描述

这个代码虽然可以让数组有序,但却有冗余的排序,因为一趟排序后数组中的最大元素就可以确定位置,第二趟排序后次大元素的位置也被确定,因此我们可以继续优化代码
在这里插入图片描述
如图,第一趟从一个元素开始比较n-1次,56冒到最右边;
第二趟最后一个元素位置确定,只用比较n-2次即可,55冒到次右边;
……
第6趟只需要比较一次就可以让数组有序。
假设数组中有n个元素,则需要排n-1趟,每一趟用i表示,第i趟就需要比较n-i-1次,代码

void BubbleSort2(int* a, int n)
{
    
    
  //n-1趟排序
  for(int i = 0; i < n-1; ++i)
  {
    
    
    //每一趟比较n-i-1次
    for(int j=0; j<n-i-1; ++j)
    {
    
    
      if(a[j]>a[j+1])
      {
    
    
        Swap(&a[j],&a[j+1]);
      }
    }

    PrintArr(a,n);
  }
}

在这里插入图片描述
这个算法依然可以优化,假设数组在第i趟排序后就已经有序,那么后面就不要再比较了,这种优化更加简单,只需要定义一个flag,如果在一趟排序中flag没有发生变化,我们就可以认为这个数组已经有序,则退出循环。
在这里插入图片描述

void BubbleSort(int* a, int n)
{
    
    
  //n-1趟排序
  for(int i = 0; i < n-1; ++i)
  {
    
    
    int flag = 0; //设置flag
    //每一趟比较n-i-1次
    for(int j=0; j<n-i-1; ++j)
    {
    
    
      if(a[j]>a[j+1])
      {
    
    
        flag = 1; //如果该趟排序发生交换,flag置1
        Swap(&a[j],&a[j+1]);
      }
    }
    PrintArr(a,n);
    //一趟排序过后没有发生变化,说明数组已经有序
    if(flag == 0)
      break;
  }
}

在这里插入图片描述

三、代码清单

#include <stdio.h>

void PrintArr(int* a, int n)
{
    
    
  for(int i = 0; i < n; ++i)
  {
    
    
    printf("%d ",a[i]);
  }
  printf("\n");
}

void Swap(int* px, int* py)
{
    
    
  int tmp = *px;
  *px = *py;
  *py = tmp;
}

void BubbleSort1(int* a, int n)
{
    
    
  //排n趟就可以让数组有序
  int end=n-1;
  while(end>0)
  {
    
    
    //一趟排序,从第一个元素开始到n-1个元素结束,
     for(int j = 0; j<n-1; ++j)
     {
    
    
        //如果左边大于右边,就交换
        if(a[j]>a[j+1])
        {
    
    
          Swap(&a[j],&a[j+1]);
        }
     }
     --end;

    PrintArr(a,n);
  }
}


void BubbleSort2(int* a, int n)
{
    
    
  //n-1趟排序
  for(int i = 0; i < n-1; ++i)
  {
    
    
    //每一趟比较n-i-1次
    for(int j=0; j<n-i-1; ++j)
    {
    
    
      if(a[j]>a[j+1])
      {
    
    
        Swap(&a[j],&a[j+1]);
      }
    }

    PrintArr(a,n);
  }
}

void BubbleSort(int* a, int n)
{
    
    
  //n-1趟排序
  for(int i = 0; i < n-1; ++i)
  {
    
    
    int flag = 0; //设置flag
    //每一趟比较n-i-1次
    for(int j=0; j<n-i-1; ++j)
    {
    
    
      if(a[j]>a[j+1])
      {
    
    
        flag = 1; //如果该趟排序发生交换,flag置1
        Swap(&a[j],&a[j+1]);
      }
    }
    PrintArr(a,n);
    //一趟排序过后没有发生变化,说明数组已经有序
    if(flag == 0)
      break;
  }
}


int main()
{
    
    
  int a[] = {
    
    25,6,56,24,9,12,55};
  int b[] = {
    
    25,6,56,24,9,12,55};
  int c[] = {
    
    25,6,56,24,9,12,55};
  int n = sizeof(a)/sizeof(a[0]);
  printf("-----BubbleSort------\n");
  BubbleSort(a,n);
  printf("-----BubbleSort1------\n");
  BubbleSort1(b,n);
  printf("-----BubbleSort2------\n");
  BubbleSort2(c,n);
   //PrintArr(a,n);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40076022/article/details/113358017
今日推荐