排序是日常工作和軟體設計中最常用的運算之一,今天給大家帶來的五類八種排序演算法的具體介紹;
1.選擇排序(常用,較為簡單)
選擇排序的基本思想是:在每一趟的排序中,在待排序子表中選出關鍵字最小或最大的元素放在其最終位置上。
基於這種思想,我們衍生出來的常用的有兩種排序方法,即直接選擇排序和堆排序。
a.直接選擇排序:直觀,不穩定,平均時間複雜度為o(n^2)
方式:通過待排序子表中完整地比較一遍以確定最大(小)元素,並將該元素放在子表的最前(後)面,啥意思呢?模擬求一組資料的最小值,和交換演算法就可想清楚了。
具體**實現如下:
#include
using namespace std;
typedef int elementtype;
int main()
void select_sort(elementtype a,int n);
select_sort(a,length);
cout<<"排序後的序列(使用直接選擇排序)為:"//控制min取次數在n-1次,其實也就是最大交換次數
for(int i=0;ielementtype temp;
min=i;//將第乙個當成最小元素
for(int j=i+1;jif(a[min]>a[j])
}//遍歷一次檢查最小元素是否排好位子,沒有就交換
if(min!=i)}}
b.堆排序:穩定排序,演算法時間複雜度為o(nlog
2n)
所謂堆排序,相信大家都已經了解了儲存結構了,所謂的堆疊其實是一體的,都是記憶體中的儲存結構。
不過堆這種儲存結構很特殊,可以具體化的描述是使用完全二叉樹來描述,因為他的要求是:
要麼該結點的左子樹和右子樹結點的值都小於他自己的值,這時稱為是大根堆
要麼該結點的左子樹和右子樹結點的值都大於他自己的值,這時稱為是小根堆
因為這樣的特點,那麼在選擇哪種堆型別是有講究的;當我們要從小到大排序是,無疑選擇大根堆來的更容易。
那麼究竟怎樣建立乙個大根堆無疑是今天這個問題的重點:這裡使用文本來說明可能來的不直觀,建議自己動手去畫出建堆過程便於理解。
#include
using namespace std;
typedef int elementtype;
int main()
void heap_sort(elementtype a,int n);
heap_sort(a,length);
cout<<"排序後的序列(使用堆排序)為:"elementtype x;
x=a[k];//臨時儲存當前根結點的值,來空出位置
bool finished =false;//設定結束標誌,當finished為false表示堆需要被調整,為true則結束。
i=k;//i來儲存當前根結點
j=2*i;//j先指向他的左孩子
while( j<=m && !finished)
}a[i]=x;//將原根值填充到所搜尋到的當前空位置中
}void heap_sort(elementtype a,int n)
//可以看到堆排序不會改變相同值得順序,所以是穩定的
for(i=n;i>=2;i--)
}2.插入排序:
插入排序的基本思想是:將待排序表看做是左右兩部分,其中左邊為有序區,右邊為無序區,整個排序的過程就是將右邊無序區中的元素逐個的插入到左邊的有序區中,直到全部完成排序,基於這種思想,我們構建出兩種演算法,我們構建出兩種插入排序的演算法,直接插入排序和希爾排序。
a,直接插入排序:(較簡單,很直接)穩定的,平均時間複雜度o(n^2)
這個演算法很簡單,相信讀者通過**注釋能很快理解:
#include
using namespace std;
typedef int elementtype;
int main()
void insert_sort(elementtype a,int n);
insert_sort(a,length);
cout<<"排序後的序列(使用直接插入排序)為:"for(int i=1;i<=n;i++)
a[j+1]=temp;//插入元素}}
b.希爾排序 不穩定的,時間複雜度為o(nlog
2n)
希爾排序可以看成是直接插入排序演算法改進版,多了乙個分組的概念,不會太難,相信讀者能夠在程式注釋中理解透徹.
3.交換排序
交換排序的基本思想是:兩兩比較待排列的元素,發現倒序就交換
基於交換排序這種思想,有的是經典的氣泡排序和快速排序。
a.氣泡排序:(較簡單)時間複雜度為o(n^2)
執行方式為:
典型的做法是從後往前,或從下往上逐個比較相鄰元素,發現倒序立即交換
一遍下來,一定能將最大或最小的元素交換到最終的位子上,就像水泡一樣冒到水面上,所以稱之為氣泡排序。
#include
using namespace std;
typedef int elementtype;
int main()
void bubble_sort(elementtype a,int n);
bubble_sort(a,length);
cout<<"排序後的序列(使用氣泡排序)為:"for(i=1;ifor(j=n;j>=i;j--)}}
b.快速排序:是對氣泡排序的一種改進,是不穩定的,時間複雜度為o(
nlog2n
) 基本思想是:首選選定乙個元素作為中間元素,然後將表中所有的元素與該中間元素比較,將比他大的放後面,比他小的放前面,再將中間數放在這兩部分之間以作為分界點,由此在對左右兩部分分別進行快速排序。
所以要進行快速排序,必須要先知道他的劃分演算法partition:
1.儲存中間元素的值到臨時變數x以騰出其空間,並用變數i指示該空位
2.從最後邊往前邊搜尋比中間數小的元素,並將其放置在前面的這個空位上,使後面空出乙個位子(用整型變數j指示)
3.從最前邊往後邊搜尋比中間數大的元素,並將其放置在後面的這個空位上,使前面空出乙個位子(用整型變數i指示)
重複以上過程,直到完成劃分。然後進行遞迴,就能快速排序了。由於作者時間倉促,這裡的**不能及時給出,如有需要的,可以聯絡我,我會及時更新補全。
4歸併排序:是穩定的,時間複雜度為o(
nlog2n
) 先說一下歸併的思想:是指將兩個或兩以上的有序表合併成乙個新的有序表,有點像插入排序的變形哦,但因為會出現新錶,所以不是插入排序。
怎麼去產生這個新錶呢?這必然是我們最要關心的問題.
其實就是用乙個表做參照,另乙個表來做插入,因為有序,所以比較的時候會十分簡單,下面是歸併演算法:就是c表等於a表加b表;
/*基於歸併演算法的思想,我們可以將整個表看成是n個子表,每個子表長度為1,然後兩兩做歸併,
得到的是 n/2個子表,每個子表長度為2,繼續兩兩合併,直到得到乙個長度為n的有序表。*/
//序列的歸併演算法
void merge(elementtype a, int low , int mid, int high)
while(i<=mid)
b[p++]=a[i++];
while(j<=high)
b[p++]=a[j++];
for(i=low,p=0;p<(high-low+1);i++,p++) //將結果複製到原陣列當中
arr[i] = newarr[p];
}5.基數排序:穩定的,時間複雜度為o(d(n+r)
)
八種排序演算法
include include 氣泡排序 void boblesort int arr,int n 插入排序 void insertsort2 int arr,int n 希爾排序 void shellsort2 int arr,int n 選擇排序 void selectsort int arr,...
八種基本排序演算法
1 思路 對尚未排序的各元素從頭到尾依次比較相鄰的兩個元素是否逆序 與欲排順序相反 若逆序就交換這兩元素,經過第一輪比較排序後便可把最大 或最小 的元素排好 然後再用同樣的方法把剩下的元素逐個進行比較,就得到了你所要的順序 可以看出如果有 n 個元素,那麼一共要進行 n 1 輪比較,第 i 輪要進行...
八種常用排序演算法
include include include define len 10 1 冒泡 將序列每輪找出的最大值從下標n到0依次存放 void bubble int data,int len 2 直插 void insert int array,int n array j 1 temp 3 將array...