數(shù)據(jù)結(jié)構(gòu)與算法—常用的排序算法
排序算法是計(jì)算機(jī)科學(xué)領(lǐng)域中非常重要的基礎(chǔ)算法之一,主要應(yīng)用于數(shù)據(jù)處理中,將未排序的數(shù)據(jù)按照一定規(guī)則排列,以便后續(xù)的計(jì)算和數(shù)據(jù)分析。目前常用的排序算法有多種,包括冒泡排序、插入排序、選擇排序、歸并排序、快速排序等。本文將逐一介紹每一種排序算法的具體實(shí)現(xiàn)方法、優(yōu)缺點(diǎn)以及時(shí)間復(fù)雜度等。
一、冒泡排序
冒泡排序是一種簡單易懂的排序算法,它的基本思路是將待排序的元素比較相鄰的兩個(gè)數(shù),如果前面的數(shù)大于后面的數(shù),則交換它們的位置。這樣一輪比較下來,最大的數(shù)就會(huì)被移動(dòng)到數(shù)列的末尾。接下來,再對剩下的數(shù)列進(jìn)行相同的操作,直到排序完成。
冒泡排序的具體實(shí)現(xiàn)如下:
void bubble_sort(int arr[], int len)
{
int i, j, temp;
for(i = 0; i < len - 1; i++)
{
for(j = len - 1; j > i; j--)
{
if(arr[j] < arr[j - 1])
{
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
}
冒泡排序的優(yōu)點(diǎn)是實(shí)現(xiàn)簡單易懂,缺點(diǎn)是時(shí)間復(fù)雜度較高,為O(n^2),在數(shù)據(jù)量較大的情況下比較耗時(shí),不適合處理大規(guī)模數(shù)據(jù)。
二、插入排序
插入排序是一種直觀、簡單的排序算法,它的基本思路是將待排序的元素逐個(gè)插入到已排好序的序列中,以保證插入后的序列仍然有序。插入排序分為直接插入排序和希爾排序兩種。
1、直接插入排序
直接插入排序的具體實(shí)現(xiàn)如下:
void insert_sort(int arr[], int len)
{
int i, j, temp;
for(i = 1; i < len; i++)
{
temp = arr[i];
j = i - 1;
while(j >= 0 && arr[j] > temp)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
直接插入排序的優(yōu)點(diǎn)是實(shí)現(xiàn)簡單,對于數(shù)據(jù)量較小的情況下性能較好。缺點(diǎn)是時(shí)間復(fù)雜度為O(n^2),同樣不適合處理大規(guī)模數(shù)據(jù)。
2、希爾排序
希爾排序是插入排序的一種改進(jìn)算法,它的基本思路是通過將序列分成若干個(gè)子序列來進(jìn)行插入排序,使得整個(gè)序列基本有序,然后再對整個(gè)序列進(jìn)行插入排序。希爾排序具有時(shí)間復(fù)雜度為O(n^(3/2))的優(yōu)點(diǎn),在實(shí)際應(yīng)用中性能較好。
希爾排序的具體實(shí)現(xiàn)如下:
void shell_sort(int arr[], int len)
{
int i, j, gap, temp;
for(gap = len / 2; gap > 0; gap /= 2)
{
for(i = gap; i < len; i++)
{
temp = arr[i];
j = i - gap;
while(j >= 0 && arr[j] > temp)
{
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = temp;
}
}
}
三、選擇排序
選擇排序是一種簡單直觀的排序算法,它的基本思路是將待排序的序列分成已排序和未排序兩部分,從未排序的部分中找到最小的元素,將其放到已排序部分的末尾。接著再從未排序部分中繼續(xù)尋找最小的元素,重復(fù)上述過程,直到最終排序完成。
選擇排序的具體實(shí)現(xiàn)如下:
void select_sort(int arr[], int len)
{
int i, j, k, temp;
for(i = 0; i < len - 1; i++)
{
k = i;
for(j = i + 1; j < len; j++)
{
if(arr[j] < arr[k])
{
k = j;
}
}
if(k != i)
{
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
}
選擇排序的優(yōu)點(diǎn)是實(shí)現(xiàn)簡單直觀,缺點(diǎn)是時(shí)間復(fù)雜度較高,為O(n^2),同樣不適合處理大規(guī)模數(shù)據(jù)。
四、歸并排序
歸并排序是一種非常高效的排序算法,它的基本思路是分治法,將待排序的序列分成若干個(gè)單獨(dú)的子序列,分別對每個(gè)子序列進(jìn)行排序,最后將排序好的子序列合并,形成一個(gè)排好序的序列。
歸并排序的具體實(shí)現(xiàn)如下:
void merge_sort(int arr[], int len)
{
int *a = arr;
int *b = (int*)malloc(len*sizeof(int));
int seg, start;
for(seg = 1; seg < len; seg += seg)
{
for(start = 0; start < len; start += seg+seg)
{
int low = start, mid = min(start+seg, len), high = min(start+seg+seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while(start1 < end1 && start2 < end2)
{
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
}
while(start1 < end1) {
b[k++] = a[start1++];
}
while(start2 < end2)
{
b[k++] = a[start2++];
}
}
int *temp = a;
a = b;
b = temp;
}
if(a != arr)
{
int i;
for(i = 0; i < len; i++)
{
b[i] = a[i];
}
b = a;
}
free(b);
}
歸并排序的優(yōu)點(diǎn)是具有時(shí)間復(fù)雜度為O(nlogn)的優(yōu)點(diǎn),適合處理大規(guī)模的數(shù)據(jù)。缺點(diǎn)是空間開銷較大,需要額外的內(nèi)存空間進(jìn)行歸并操作。
五、快速排序
快速排序是一種高效的排序算法,它的基本思路是分治法,選取一個(gè)中間的基準(zhǔn)值,將序列分成兩個(gè)子序列,一邊小于基準(zhǔn)值,一邊大于基準(zhǔn)值,再對這兩個(gè)子序列進(jìn)行遞歸操作,直到排序完成。
快速排序的具體實(shí)現(xiàn)如下:
void quick_sort(int arr[], int left, int right)
{
int i, j, pivot, temp;
if(left < right)
{
i = left;
j = right;
pivot = arr[left];
while(i < j)
{
while(i < j && arr[j] >= pivot)
{
j--;
}
if(i < j)
{
arr[i++] = arr[j];
}
while(i < j && arr[i] < pivot)
{
i++;
}
if(i < j)
{
arr[j--] = arr[i];
}
}
arr[i] = pivot;
quick_sort(arr, left, i - 1);
quick_sort(arr, i + 1, right);
}
}
快速排序的優(yōu)點(diǎn)是具有時(shí)間復(fù)雜度為O(nlogn)的優(yōu)點(diǎn),適合處理大規(guī)模的數(shù)據(jù)。缺點(diǎn)是對于特殊情況下容易出現(xiàn)性能退化,需要進(jìn)行優(yōu)化。
小結(jié)
各種排序算法各有優(yōu)缺點(diǎn),在實(shí)際應(yīng)用中需要根據(jù)具體場景選擇適合的排序算法,以求得最佳的性能和效率。