前言
爲了更加直觀的展示排序的過程,用了動態圖方便理解,並且對每一步的排序過程顯示打印出來。
文章目錄
一 排序算法
1.1什麼是排序
排序是指把一組數據以某種關係(遞增或遞減)按順序排列起來的一種算法。
1.2排序的穩定性
如果在一組需要排序的數據序列中,數據ki和kj的值相同,即ki= =kj,且在排序前ki在序列中的位置領先於kj,那麼當排序後,如果ki和kj的相對前後次序保持不變,即ki仍然領先於kj,則稱此類排序算法是穩定的。如果ki和kj的相對前後次序變了,即kj領先於ki了,則稱此類排序算法是不穩定的。
1.3排序的分類
1.內部排序:指待排序數據全部存放在內存中進行排序的過程。
2.外部排序:指待排序數據的數量很大,內存無法全部容納所有數據,在排序過程中需要對外存進行訪問的排序過程。
1.4排序的過程
排序的過程中需要進行如下兩種基本操作:
(1)比較兩個數據的大小;
(2)移動兩個數據的位置。
1.5排序算法
排序算法按照其實現的思想和方法的不同,可以分爲許多種。
我們比較常用的排序算法有:冒泡排序、 插入排序、選擇排序、希爾排序、快速排序、堆排序、歸併排序。
1.6複雜度
時間複雜度和空間複雜度
二 冒泡排序
2.1動態圖解
2.2基本思路
2.2.1核心思路
n個數據進行冒泡排序,首先將第一個數據和第二個數據進行比較,如果爲逆序就交換兩個數據的值,然後比較第二個和第三個數據,依此類推,直到第最後一個和倒數第二個比較完了爲止。上述過程爲冒泡排序的第一趟冒泡排序,其結果是最大或者最小的數據被放置在末尾的位置。然後進行第二趟排序,把第二大或者第二小的數放置在倒數第二的位置,之後每一趟排序都會使一個數據有序,直到此序列的全部數據都有序爲止。
2.2.2算法實現
void BubSort(int a[],int N)//冒泡排序
{
for (int i = 0; i < N; i++)//外層是輪數 每一輪選出一個最大的
{
for (int j = 0; j <N - i - 1; j++)//內循環是比較
{
if (a[j]>a[j + 1])//前後兩個數兩兩進行比較,滿足要求的進行交換
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
2.3排序示例
1.代碼實現
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void BubSort(int a[], int N)//冒泡排序
{
for (int i = 0; i < N; i++)//外層是輪數 每一輪選出一個最大的
{
for (int j = 0; j <N - i - 1; j++)//內循環是比較
{
if (a[j]>a[j + 1])//前後兩個數兩兩進行比較,滿足要求的進行交換
{
int temp = a[j];//交換
a[j] = a[j+1];
a[j+1] = temp;
}
}
printf("第%d步排序結果:", i);
for (int k = 0; k < N; k++)//把每一步都打印出來
{
printf("%d ", a[k]);
}
printf("\n");
}
}
int main()
{
int shuzu[SIZE], i;
srand(time(NULL));//生成隨機數種子
for (i = 0; i < SIZE; i++)//隨機產生SIZE個數據
{
shuzu[i] = rand()%100;
}
printf("排序前的數組爲:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
BubSort(shuzu, SIZE);
printf("排序後的數組爲:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.結果展示
三 選擇排序
3.1動態圖解
3.2 基本思路
3.2.1核心思路
對一個序列進行選擇排序,首先通過一輪循環比較,從n個數據中找出最大或者最小的那個數據的位置,然後按照遞增或者遞減的順序,將此數據與第一個或最後一個數據進行交換。然後再找第二大或者第二小的數據進行交換,以此類推,直到序列全部有序爲止。
3.2.2算法實現
void SelectionSort(int x[], int n)//選擇排序
{
int i, j, min,k;
for (i = 0; i < n; i++)//每一輪選出一個最小的放最左邊
{
min=i;//默認當前選擇位置上的元素是最小的
for (j = i; j < n; j++)//內循環是比較 是不是比它小
{
if (x[min] > x[j])
min = j;//如果有小於默認最小元素min的數組元素,min記錄其下標
}
k = x[i];
x[i] = x[min];
x[min] = k;
}
for (i=0;i<n;i++)
printf("%d\t",x[i]);
}
3.3排序示例
1.代碼實現
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void SelectionSort(int a[], int N)
{
for (int i = 0; i < N; i++)//每一輪選出一個最小的放最左邊
{
int min = i; //默認當前選擇位置上的元素是最小的
for (int j = i + 1; j < N; j++)//內循環是比較 是不是比它小
{
if (a[min]>a[j])
{
min = j; //如果有小於默認最小元素min的數組元素,min記錄其下標
}
}
int k = a[min];
a[min] = a[i];
a[i] = k;
printf("第%d步排序結果:", i);
for (int h = 0; h < N; h++)
{
printf("%d ", a[h]);
}
printf("\n");
}
}
int main()
{
int shuzu[SIZE];
srand(time(NULL));
for (int i = 0; i < SIZE; i++)
{
shuzu[i] = rand()%100;
}
printf("排序前的數組爲:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
SelectionSort(shuzu, SIZE);
printf("排序後的數組爲:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.結果展示
四 插入排序
4.1動態圖解
4.2基本思路
4.2.1核心思路
插入排序的規則是:第一輪開始時默認序列中第一個數據是有序的,之後各個數據以此爲基準,判斷是插入在此數據的前面還是後面,之後的數據依次向後移動,騰出位置,讓數據插入,以此類推,直到整個序列有序爲止。每比較一次,如果滿足條件(升序:前面一個數比後面需要插入的數大),就直接交換。
4.2.2算法實現
void Insort(int x[], int n)//插入排序
{
for (int i = 1; i < N; i++)//i數據以此爲基準
{
for (int j = i; j >= 0; j--)//內循環是比較
{
if (x[j]<x[j - 1]) //如果前面有序數列的值比後面的大,就依次交換
{
int k = x[j];//交換
x[j] = x[j - 1];
x[j - 1] = k;
}
}
}
}
4.3排序示例
1代碼實現
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void Insort(int x[], int N) //插入排序
{
for (int i = 1; i < N; i++)//i數據以此爲基準
{
for (int j = i; j >= 0; j--)//內循環是比較
{
if (x[j]<x[j - 1]) //如果前面有序數列的值比後面的大,就依次交換
{
int k = x[j];//交換
x[j] = x[j - 1];
x[j - 1] = k;
}
}
printf("第%d步排序結果:", i);
for (int h = 0; h < N; h++)
{
printf("%3d ", x[h]);
}
printf("\n");
}
}
int main()
{
int shuzu[SIZE];
srand(time(NULL));//生成隨機數種子
for (int i = 0; i < SIZE; i++)//隨機產生SIZE個數據
{
shuzu[i] = rand()%100;//隨機數據在100以內
}
printf("排序前的數組爲:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
Insort(shuzu, SIZE);
printf("排序後的數組爲:\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.結果展示
五 快速排序
5.1動態圖解
5.2基本思路
5.2.1核心思路
快速排序的基本思想是:通過一趟排序將待排序的序列劃分爲獨立的兩部分,其中一部分的數據比另一部分的數據小,然後再分別對這兩部分記錄繼續進行排序,直到整個序列有序。
一趟快速排序的具體做法是:設置兩個標記low和high,它們初始值分別指向序列的第一個數據和最後一個數據,並設置一箇中樞變量key,初始值記錄序列第一個數據的值。首先high指針向前搜索,如果找到有數據小於中樞變量key的,則將其數據與中樞變量互相交換;然後low指針向後搜索,如果找到第一個關鍵字大於中樞變量key的,則將其數據與中樞變量互相交換;重複上述步驟,直到low==high爲止。
5.2.2算法實現
void QuickSort(int x[],int low,int high)
{
int i, j, key; //變量key是用來保存當前參考元素的值
if (low<high) //判斷高低位標記是否重合
{
key = x[low]; //key默認保存第一個元素的值
i = low; //用i代替最低下標low做運算
j = high; //用j代替最高下標high做運算
while (i < j) //判斷高低位標記是否重合
{
//從數組後半部分向前比較,找到小於參考元素值的位置,直到標記i和j重合
while (i < j && x[j] >= key)j--;
if (i < j) x[i++] = x[j]; //數組後半部分的較小元素往前丟
//從數組前半部分向後比較,找到大於參考元素值的位置,直到標記i和j重合
while (i < j && x[i] <= key)i++;
if (i < j) x[j--] = x[i]; //數組前半部分的較大元素往後丟
}
x[i] = key; //參考元素放回數組中
//把整個數組劃分爲兩半部分,前半部分的元素總是比後半部分小
QuickSort(x, low, i - 1); //前半部分遞歸排序
QuickSort(x, i + 1, high); //後半部分遞歸排序
}
}
5.3排序示例
1代碼實現
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 8
void QuickSort(int x[], int low, int high)//快速排序,後面滿足條件的往前面丟,前面滿足條件的往後面丟
{
int i, j, key; //變量key是用來保存當前參考元素的值
if (low<high) //判斷高低位標記是否重合
{
key = x[low]; //key默認保存第一個元素的值
i = low; //用i代替最低下標low做運算
j = high; //用j代替最高下標high做運算
while (i < j) //判斷高低位標記是否重合
{
//從數組後半部分向前比較,找到小於參考元素值的位置,直到標記i和j重合
while (i < j && x[j] >= key)j--;
if (i < j) x[i++] = x[j]; //數組後半部分的較小元素往前丟
//從數組前半部分向後比較,找到大於參考元素值的位置,直到標記i和j重合
while (i < j && x[i] <= key)i++;
if (i < j) x[j--] = x[i]; //數組前半部分的較大元素往後丟
}
x[i] = key; //參考元素放回數組中
//把整個數組劃分爲兩半部分,前半部分的元素總是比後半部分小
printf("每一步交換結果:");
for (int h = 0; h < SIZE; h++)
{
printf("%3d ", x[h]);
}
printf("\n");
QuickSort(x, low, i - 1); //前半部分遞歸排序
QuickSort(x, i + 1, high); //後半部分遞歸排序
}
}
int main()
{
int shuzu[SIZE] , i;
srand((unsigned int)time(NULL));
for (i = 0; i < SIZE; i++)
{
shuzu[i] = rand()% 100;
}
printf("排序前的數組爲:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
QuickSort(shuzu, 0, SIZE - 1);
printf("排序後的數組爲:\n");
for (i = 0; i < SIZE; i++)
{
printf("%d ", shuzu[i]);
}
printf("\n");
system("pause");
return 0;
}
2.結果展示
六 總結
選擇排序與冒泡排序的區別在於,冒泡排序每比較一次後,滿足條件的數據就交換,而選擇排序是每次比較後,記錄滿足條件數據的位置,一輪循環過後再作交換。
以上都是用到隨機函數,產生一組隨機數據進行排序,並且打印每一步的排序結果。如果對你有幫助的話,請點個贊吧!謝謝你的支持。