排序算法歸納(c語言)①冒泡排序

冒泡排序

這是最早學到的一個排序算法,它的原理比較簡單。就像它的名字一樣,很形象,讓大數(或小數)“冒出頭”。
本代碼中,待排序的數據放在一個順序表中。
數據存放沒有從0開始,而是選擇從1開始,data[0]則可做他用。
這裏一共列出三個,由簡單到複雜的冒泡排序代碼。代碼參考於《大話數據結構》。

初始設定

#include<stdio.h>
#define MAXSIZE 20	//順序表最大容量
#define N 10		//表中數據個數
typedef enum{ False = 0, True = 1 }Bool;//一個用枚舉寫的簡單的布爾變量

順序表結構體

typedef struct
{
 int data[MAXSIZE + 1];
 int len;		//已存儲元素個數
}Sqlist;

swap函數

void Swap(Sqlist* lp,int a, int b)
{
 int t = lp->data[a];
 lp->data[a] = lp->data[b];
 lp->data[b] = t;
}

輸出順序表

void Show(Sqlist L)
{
 int i;
 for (i = 1; i < L.len; ++i)
 {
  printf("%d,", L.data[i]);
 }
 printf("%d\n", L.data[i]);
}

輸入函數

void Input(Sqlist* lp)
{
 int d[N] = { 9, 1, 5, 8, 3, 0, 7, 4, 6, 2 };
 for (int i = 0; i < N; i++)
  lp->data[i + 1] = d[i];
 lp->len = N;
}

交換排序

嚴格來說,這似乎不是一個冒泡排序,它沒有“冒”的過程。它的效率甚至比冒泡排序還要低。因爲它讓每個元素都跟別的元素比較了一遍。

void SwapSort(Sqlist* lp)
{
 for (int i = 1; i < lp->len; ++i)
 {
  for (int j = i + 1; j <= lp->len; ++j)
  {
   if (lp->data[i] > lp->data[j])
   {
    Swap(lp, i, j);//調用swap做交換
   }
  }
 }
}

冒泡排序

這是一個比較常見的冒泡排序代碼。只是內層循環是從後往前的,和外層循環正好相反。

void BubbleSort(Sqlist* lp)
{
 for (int i = 1; i < lp->len; ++i)
 {
  for (int j = lp->len - 1; j >= i; --j)//從後往前
  {
   if (lp->data[j] > lp->data[j + 1])
   {
    Swap(lp, j, j + 1);//調用swap做交換
   }
  }
 }
}

冒泡排序_檢測版

這是比較高級的一個版本。多定義了一個變量flag,用以檢測是否還有進行後續冒泡的需要。
即,在每次外層循環開始時,將flag置爲false。一旦本次外層循環發生了交換,則將flag置爲true。
如果下次外層循環開始時,flag爲true,即發生過交換,則不能保證是否還有排序必要,則繼續冒泡排序。
如果下次外層循環開始時,flag爲false,即未發生交換,則說明,此時順序表已經有序,則結束冒泡排序。

void BubbleSort_check(Sqlist* lp)
{
 Bool flag = True;		//用於檢測的旗子變量
 for (int i = 1; i < lp->len && flag; ++i)//flag爲false則結束排序
 {
  flag = False;		//外層開始時置爲false
  for (int j = lp->len - 1; j >= i; --j)
  {
   if (lp->data[j] > lp->data[j + 1])
   {
    Swap(lp, j, j + 1);	//調用swap做交換
    flag = True;		//發生交換則置爲true
   }
  }
 }
}

系列鏈接

上一個排序算法:

下一個排序算法:
選擇排序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章