內排序
void mkarr(int **arr, int size)
void checksorted(int *arr, int size, int flag)
}else
}printf("all right\n");
}
1.插入排序
假設陣列的前i個數已經排好序,然後將第i+1個數插入到前i個中,只到n個數都插入到自己的位置。
平均時間複雜度 o(n2),當序列已經排好序時時間複雜度低o(n),當序列是逆序時時間複雜度最高為o(n2)。插入過程都是從後往前,所以演算法是穩定的。
void insertsort(int *arr, int size)
arr[j + 1] = tmp;
}}
2.選擇排序
假設前i-1個元素已經排好序,從第i到n個元素中選擇最小的放到第i個位置,只到第n個元素。
因為每次選擇都要把剩下的元素全部檢查一遍所以,演算法的最低、最高、平均時間複雜度都是o(n2)。選擇排序在第一輪的最小元素是最後乙個,這樣第乙個元素就直接被交換到最後,如果序列中有和第乙個元素相同的元素,那他們的相對位置肯定變了,所以演算法是不穩定的。
void selectionsort(int *arr, int size)
int tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}}
3.氣泡排序
從前到後相鄰的元素比較大小,如果前面的元素大於後面的,兩個元素交換,如果沒有大於,下乙個元素繼續與相鄰的下乙個元素進行比較,每一輪可以確定乙個最大的元素。
每一輪冒泡都要把所有相鄰元素進行比較,所以演算法的最低、最高、平均時間複雜度都是o(n2)。冒泡方向不變,所以演算法是穩定的。
void bubblesort(int *arr, int size) }}
}
4.快排
選擇乙個基準元素對陣列進行分割,比基準大的在一邊,比基準小的在一邊,分割結束後基準元素已經排好序。再對左右兩個部分遞迴進行分割,直到整個陣列有序。
平均時間複雜度o(nlogn),當演算法每次選擇基準值時都選擇到最大或最小元素時,演算法時間複雜度最高o(n2),每次都選到中間值時時間複雜度最低為o(nlogn)。劃分的過程是從兩邊向中間走,所以快速排序不穩定。
// 劃分陣列,返回基準值位置
int parition(int *arr, int size)
while (arr[low] < tmp && low < high)
low++;
if (low < high)
}arr[pivot] = tmp;
return pivot; //返回基準元素的位置
}void quicksort(int *arr, int size)
int pivot = parition(arr, size);
quicksort(arr, pivot);
quicksort(arr + pivot + 1, size - pivot - 1);
}
5.歸併排序
把兩個相對有序的子串行合併成乙個.
時間複雜度 o(nlogn),空間複雜度 n。兩個序列歸併的過程相同排序欄位的元素不會發生交換,所以是穩定的。
// 合併兩個子串行
void merge(int *arr, int *res, int start1, int end1, int start2, int end2)
while (start1 <= end1)
arr[ix++] = res[start1++];
while (start2 <= end2)
arr[ix++] = res[start2++];
}void mergesort(int *arr, int *res, int start, int end)
6.堆排序
對陣列的前n個元素建堆,將第乙個元素與第n個元素交換,然後對前n-1元素建堆.
重新建堆的時間複雜度為o(logn),所以演算法的最好、最壞、平均時間複雜度都o(nlogn)。建堆過程中排序字段相同元素的父節點可能不相同,導致相對順序有可能改變,所以堆排序不穩定。
void heapsort(int* arr, int start, int end)
if (i * 2 + 2
<= end && arr[i] < arr[i * 2 + 2])
}// 最大的元素與最後乙個元素交換,然後繼續對start到end-1建立大根堆
tmp = arr[start]; arr[start] = arr[end]; arr[end] = tmp;
end--;
}}
7.shell排序
先用增量x對原陣列進行劃分,(0,x,2*x…)/(1,1+x,1+2*x…)/(2,2+x,2+2*x…)…
然後在每個劃分上執行插入排序,然後增量減半x=x/2,繼續執行,知道x=1;
與插入排序相同,當原序列有序是時間複雜度最低為o(n),平均和最高時間複雜度都為o(n2)。相同排序關鍵字的元素可能會劃入不同的子串行,導致相對位置變化,所以shell排序是不穩定的。
void shellinsertsort(int *arr, int start, int end, int step)
}void shellsort(int* arr, int start, int end)
}}
查詢
8.順序查詢
時間複雜度o(n)
int linersearch(int *arr, int target, int start, int end)
return -1; // 查詢失敗
}
9.二分查詢
假設原序列有序(遞增),先查詢序列中間的元素,如果相等返回座標,如果小於目標則繼續在後一半中進行二分查詢,大於時在前一半進行二分查詢.
時間複雜度o(logn)
int binsearch(int *arr, int target, int start, int end)
基礎排序演算法複習
1.計數排序 計數排序的四個步驟 a.初始化c 0 k 為0 b.對於每個元素a i c a i c記錄a中各個元素出現的次數,比如中,c 1 2,c 2 0,c 3 1 c.對於i 1 to k,c i c i c i 1 此時c記錄小於等於i的元素的個數,c 1 2,c 2 2,c 3 3 d....
基礎演算法複習 快速排序
1.最近一直在忙課程,每天只能抽空刷幾道leetcode,好久沒看js了.有點慌,但是先抽空把排序演算法啥的寫一遍吧,等忙完作業系統課設再好好複習js.2.快速排序演算法思想大概就是設定乙個基準值,根據基準值不斷地交換陣列中前後的元素值,在此過程中目的是把基準值排序到最終的位置,再對基準值位置之前和...
內排序演算法
每次需要排序的時候總是會忘記基本的排序演算法,為了防止自己再次忘記,寫個部落格加深自己的印象 簡單選擇排序大概就是最簡單我們最容易想到的一種排序方法,一共進行n 1次選擇,在第i次選擇中選擇第i小的數放在相應的位置。我們可以想象一種場景,有一些賬單需要我們按照時間進行排序,我媽每次選擇最早的一張拿在...