1 冒泡排序
冒泡排序的思路:从序列的一头开始,每次比较相邻的两个数,将大的往后移.当走到序列结尾的时候,最后一个即是最大的;然后再从头开始比较,只是这次比较到倒数第二个就好,因为最后一个已经确定是最大了。如此往复,直到没有需要比较的元素为止。个人表述有限,可参考维基百科介绍。
参考代码:
//冒泡排序
void sortUp(int arr[],int size){
for (int i = 0; i < size ; i++) {
for (int j = size-1; j > i; j--) {
if(arr[i] > arr[j]){
arr[i] += arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
}
}
}
}
时间复杂度:
冒泡排序一般是作为程序员入门算法进行讨论的,因为他的效率着实有些低。别的不说,相比选择排序就落好几条街。
最好时间复杂度是O(n);
这种情况是: 6 , 1, 2, 3, 4, 5, 类似吧。即只需一趟即可把顺序完全排好。出现的概率有点儿低。
最坏时间复杂度是O(n2);
这种情况是:6,5,4,3,2,1类似吧,即每一趟的每一次比较都需要进行数据交换。对此不予评论。
2 选择排序
选择排序的思路:每一趟扫描选取剩下的元素中一个最大的放在后边。他与冒泡排序的区别在于,在扫描的过程中,只是保留选中元素的下标,而并不是将元素进行位移。更换选中的数据也只是更换一下下标的值,中间不会产生数据移动。所以在效率上会高很多很多。
参考代码
//选择排序
void sortSelect(int arr[],int size){
int re[size];
for (int i = 0; i < size; i++) {
int min = i;
for (int j = i+1; j < size; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
if(min != i){
arr[i] += arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
}
}
}
时间复杂度:
比较次数O(n2),交换次数O(n),因为在计算机中交换的CPU时间需要的比比较所需要的CPU时间要长的多,所以选择排序比冒泡排序要快许多。最好情况是,已经有序,交换0次;最坏情况是,逆序,交换n-1次。
3 快速排序
快速排序的思路:在序列中选择一个标杆,通常选择序列的第一个数,然后对序列中的数从两头开始,将小于他的数放在左边,大于他的数放在他右边。这时以这个数为标杆,分成了左右两块,左边的都小于他,右边的都大于他。然后再递归调用,直到没有可排序的。即只有两个元素。感觉不大容易看懂,所以贴了一个动图来看看。
算法思路:我贴一下百度的讲解吧。
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
6
|
2
|
7
|
3
|
8
|
9
|
下标
|
0
|
1
|
2
| 3 |
5
|
5
|
数据
|
3
|
2
|
7
|
3
|
8
|
9
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
7
|
7
|
8
|
9
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
//快速排序
void sortQuickly(int arr[],int low,int high){
//m代表前面的标记,n代表后面的标记。L表示当前的中间位
int m = low,n = high;
int temp = arr[low];
if (low < high) {
while(m < n){
while((arr[n] >= temp) && (m < n)){
n--;
}
arr[m] = arr[n];
while((arr[m] <= temp) && (m < n)){
m++;
}
arr[n] = arr[m];
}
arr[n] = temp;
sortQuickly(arr,low,m-1);
sortQuickly(arr,n+1,high);
}else{
return;
}
}