直觀感受排序演算法:
選擇排序
交換排序
歸併排序
根據資料規模狀態,輔助空間,穩定性的要求進行選擇。
資料規模較小,插排,選擇。
基本有序,冒泡(優化過的,達到on),插排。
要求穩定性,插排,冒泡,歸併。
資料規模較大,快排,堆排,歸併都可以。但又要求考慮極端情況,最好用堆排並且輔助空間為o1,考慮穩定性用歸併。
思想是將待插入序列放入已經有序的序列,通過不斷後移元素找到要插入的位置並放入。
因為在比較過程中相同元素不會進行後移,所以是穩定排序。
void
insertsort
(int
*arr,
int size)
if(end != i -1)
}}
可以利用二分查詢來尋找待插入位置,優化後元素比較次數減少。
為了保證穩定排序,在遇到相同元素時,left=mid+1,繼續向後尋找插入位置。
void
insertsortop
(int
*arr,
int size)
else
if(tmp < arr[mid])}
//left是待插位置
while
(end>=left)
if(end != i -1)
}}
插入排序對於資料量大的時候,向後搬移元素次數過多,導致效率低下。
希爾排序設定乙個間隔,在間隔內進行插排,以減少元素搬移次數。
由於在間隔組內無法保證相同元素的比較,所以不穩定。效率大於插排。
void
shellsort
(int
*arr,
int size)
int i, tmp, end;
while
(gap >0)
if(end != i - gap)
} gap /=3
;}}
每次迴圈選出乙個最小的放在第乙個位置,下次迴圈的範圍向後縮小乙個。
void
selectsort
(int
*arr,
int size)}if
(i != minn)
}}
如果每次迴圈同時找到最大和最小的,那麼就能少迴圈一半的次數。
坑:min位置在要放的最大位置,max在第乙個位置。當把最小的放在第乙個位置,就改動了max的值。
void
selectsort
(int
*arr,
int size)
if(arr[maxn]
< arr[j])}
if(i != minn)}if
(size - i -
1!= maxn)
}}
建堆的時間複雜度是 n*log n,不斷拿出堆頂元素並刪除是 log n。
在拿出堆頂元素時,與堆末尾元素交換並調整堆,此時會打亂元素順序,所以不穩定。
void
_adjust
(int
*arr,
int parent,
int len)
}//與根比較
if(arr[child]
> arr[parent]
)else}}
void
heapsort
(int
*arr,
int size)
//拿出堆頂資料放入陣列末尾
for(i = size-
1; i >
0; i--
)}
優化:如果某一趟排序裡,沒有發生過一次交換,證明相鄰的兩兩都有序,傳遞性,所以整個序列有序。
void
bubblesort
(int
*arr,
int size)}if
(!flag)
}}
void
quicksort
(int
*arr,
int left,
int right)
}int
partition
(int
*arr,
int left,
int right)}}
++low;
if(low != right)
return low;
}//獲得三個數中居中的數的下標
int_getdiv
(int
*arr,
int left,
int right)
前後交換法分割陣列
int
partition2
(int
*arr,
int left,
int right)
while
(left < right &&arr[right]
>= arr[key])if
(left != right)
}swap
(&arr[left]
,&arr[key]);
return left;
}
遞迴:
void
_merge
(int
*arr,
int left,
int mid,
int right,
int*tmp)
else
index++;}
//將兩個陣列剩餘的數放入臨時空間
while
(lefts < lefte)
while
(rights < righte)
}void
_mergesort
(int
*arr,
int left,
int right,
int*tmp)
}void
mergesort
(int
*arr,
int left,
int right)
int*tmp =
(int*)
malloc
(sizeof
(arr[0]
)*(right - left));
if(tmp)
free
(tmp)
;}
非遞迴:
void
mergesortnor
(int
*arr,
int left,
int right)
//一次歸併的每個陣列中元素個數
int gap =1;
int size = right - left;
for(
; gap < size; gap *=2
)if(end > size)
_merge
(arr, begin, mid, end, tmp);}
memcpy
(arr, tmp, size *
sizeof
(arr[0]
));}
free
(tmp)
;}
排序演算法總結
1 直接插入排序 1 穩定性 穩定 2 適用情況 待排記錄規模較小,或者記錄已經基本有序 2 希爾排序 1 穩定性 不穩定 2 特點 希爾排序的執行時間依賴於增量序列,它的效率比直接插入排序有較大的改進。3 氣泡排序 1 穩定性 穩定 2 特點 當待排記錄基本有序是,氣泡排序是不錯的選擇 但由於氣泡...
排序演算法總結
1 選擇排序 選擇排序的思想是依次從待排序數列中選擇最大 小 的 第二大 小 的等等,然後依次重新排列為有序數列。void selectionsort int a,int n if min i 時間複雜度o n 2 2 歸併排序 void merge int a,int left,int mid,i...
排序演算法總結
學習了這麼多的排序演算法,還沒有做個總結,呵呵 氣泡排序 氣泡排序是最慢的排序演算法。在實際運用中它是效率最低的演算法。它通過一趟又一趟地比較陣列中的每乙個元素,使較大的資料下沉,較小的資料上公升。它是 o n 2 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來...