冒泡排序
這是最早學到的一個排序算法,它的原理比較簡單。就像它的名字一樣,很形象,讓大數(或小數)“冒出頭”。
本代碼中,待排序的數據放在一個順序表中。
數據存放沒有從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
}
}
}
}
系列鏈接
上一個排序算法:
無
下一個排序算法:
選擇排序