氣泡排序
氣泡排序是一種簡單的排序演演算法,其基本思想是重複地交換相鄰兩個元素,將較大的元素向右“冒泡”,較小的元素向左“沉澱”,從而將序列中的最大元素逐漸移到最後面。
#include <stdio.h>
void bub(int arr[],int n){ //首先定義空函式,第一個int引數接受列表,第二個為元素個數
int i,j,temp;
for(i=0;i<n-1;i++){ //這是進行幾輪比較。這裡是6輪。0,1,2,3,4,5 ,這裡有-1可以減少不必要的比較輪次,到最後自己就排好了,因為不是幾個數就比較就次,最後一個數會自己還原。
for(j=0;j<n-i-1;j++){ //下標從0開始而不1所以需要n-1。你如果不-1,後面j++,arr[j+1]會超出範圍。-i是因為之後不需要再與最大數做比較了
if(arr[j]>arr[j+1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main(){
int arr[] = {64,34,97,12,22,11,90};
int n = sizeof(arr) / sizeof(arr[0]);
bub(arr,n);
printf("sort:\t");
for(int i = 0; i < n; i++) {
printf("%d\t",arr[i]);
}
return 0;
}
sort: 11 12 22 34 64 90 97
相較於其他排序演演算法,氣泡排序的優勢在於它的實現簡單、容易理解和編寫,適用於少量資料的排序。此外,氣泡排序在交換相鄰元素的過程中,可以記錄是否發生了交換,如果沒有發生交換則說明序列已經有序,可以提前結束排序,這樣可以減少排序的時間複雜度。但是,對於大量資料排序,氣泡排序的時間複雜度為O(n^2),效率較低,因此不適用於大規模資料的排序。
最佳化冒泡
#include <stdio.h>
#include <stdbool.h> #有bool的時候最好加上
void bubble_sort(int arr[], int n) {
bool is_sorted = false;
int i, j, temp;
for (i = 0; i < n - 1; i++) {
is_sorted = true;
for (j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) { //如果在這個for迴圈裡,此if一次都未執行。那麼is_sorted就不會變為false,也證明已經不需要換位置了。直接跳出當前迴圈,執行if語句,然後跳出大迴圈
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
is_sorted = false;
}
}
if (is_sorted) {
break;
}
}
}
int main() {
int arr[] = { 4, 2, 6, 1, 9, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
int i;
bubble_sort(arr, n);
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
選擇排序
選擇排序是一種簡單直觀的排序演演算法,它的工作原理如下:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
#include <stdio.h>
void selectsort(int arr[],int n){
int min,i,j,temp;
for(i=0; i < n- 1; i++){
min=i; //取得最小的下標
for (j= i+1 ;j < n;j++) //每次都要比較到最後一個元素所以j<n
if(arr[j]<arr[min]){ //如果最小的下標的值不是最小值,將最小值的小標賦予min
min=j;
}
temp=arr[i]; //將這個最小下標的值存起來
arr[i]=arr[min]; //最小值賦予最小下標
arr[min]=temp; //將最小下標的值賦予min。也就是之前j的位置
}
}
int main(){
int a[] = {1,5,23,45,23,92,12};
int n = sizeof(a)/sizeof(a[0]);
selectsort(a,n);
for (int i = 0;i<n;i++) {
printf("%d\t", a[i]);
}
return 0;
}
快速排序
待排序的序列中,隨機選一個數字作為pivot中心軸
所有小於中心軸放左,大於則放右邊
左邊比pivot中心軸小,而右邊全比pivot大
然後對左子序列和右子序列重複以上的操作
/*
快速排序演演算法
思想: 遞迴思想
什麼是遞迴?
自我呼叫(迴圈)的函式
有引數向著遞迴邊界靠,直到達到遞迴邊界
*/
/*
#include <stdio.h>
int f(int n){
if(n==0||n==1){
return 1;
} else{
return n*f(n-1);
}
}
int main(){
int n=5;
printf("%d ",f(n));
return 0;
}
*/
#include <stdio.h>
int FaindPos(int* a, int left, int right) {
int val = a[left];
while (left < right) {
while (left < right && a[right] >= val) {
right--;
}
a[left] = a[right];
while (left < right && a[left] <= val) {
left++;
}
a[right] = a[left];
}
a[left] = val;
return left;
}
void QuickSort(int* a, int left, int right) {
if (left >= right) {
return;
} else {
int val = a[left];
int pos = FaindPos(a, left, right);
a[pos] = val;
QuickSort(a, left, pos - 1);
QuickSort(a, pos + 1, right);
}
}
int main() {
int a[] = {6, 5, 7, 8, 3, 4, 2, 1};
QuickSort(a, 0, 7);
for (int i = 0; i < 8; i++) {
printf("%d ", a[i]);
}
return 0;
}