排序算法
排序算法作为算法的入门,大家必须掌握,我也是刚开始刷算法,从这里开始记叙我的算法历程吧。
冒泡排序
复杂度O(n2)
- 算法描述
1、外部循环0-n,代表要对n个元素都进行一次匹配
2、内部j = n-1-j
是匹配完一个元素就将每次进行比对的元素减少一个,即只比较未排好序列的前面n-1-j
个元素。
3、每次比对都是相邻元素进行比对,而匹配完成的元素都"沉"到最后面去了,就不用管了。 - 动态演示
- 代码实现
#include <iostream>
using namespace std;
void swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}
int main(int argc, char** argv){
int len;
cout << "please input arr lenth:";
cin >> len;
int arr[len];
for(int i=0; i<len; i++){
cout << "please input" << i << "num:";
cin >> arr[i];
}
for(int i=0; i<len; i++){
for(int j=0; j<len-i-1; j++){
if(arr[j] > arr[j+1]){
swap(&arr[j],&arr[j+1]);
}
}
}
for(int i=0; i<len; i++){
cout << arr[i] << " ";
}
cout << "\n";
return 0;
}
快速排序
复杂度O(nlog2n)快速排序是这样的。
首先由"3 2 3 5 1 9 6"这样一组数据,快速排序分为下面几个步骤完成。
- 1、找一个基准数,这里就找第一个arr[0](也就是3)。
- 2、进行比较将比3大的数换到3左边,比3小的数换到3右边。
- 3、然后将相遇时侯的值跟基准数换位置。
- 4、然后用递归分别对左边和右边进行排序
注意:这里右边是要先动的,因为基准数是选择的左边,如果选取最左边的数arr[left]作为基准数,那么先从右边开始可保证i,j在相遇时,相遇数是小于基准数的,交换之后temp所在位置的左边都小于temp。但先从左边开始,相遇数是大于基准数的,无法满足temp左边的数都小于它。所以进行扫描,要从基准数的对面开始。举个例子:
初始数列:3 2 3 5 1 9 6
变换后数列:3 2 3 1 5 9 6(到这里只有1和5换了位置)
我们可以看到上面一步将1和5交换了位置,这时侯左边哨兵指向1,右边哨兵指向5,如果左边哨兵先走,
那么他就指向了5,然后停下来,右边哨兵也因为条件不满足停在了5这里,然后让3和5交换。这样逻辑就错误了,所以只能是右边先走。
- 代码实现
#include <iostream>
using namespace std;
//快速排序(从小到大)
void quickSort(int left, int right, int * arr)
{
if(left >= right)
return;
int i, j, base, temp;
i = left, j = right;
base = arr[left]; //取最左边的数为基准数
while (i < j)
{
while (arr[j] >= base && i < j)
j--;
while (arr[i] <= base && i < j)
i++;
if(i < j)
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
//基准数归位
arr[left] = arr[i];
arr[i] = base;
quickSort(left, i - 1, arr);//递归左边
quickSort(i + 1, right, arr);//递归右边
}
int main(int argc, char** agrv){
int len;
cout << "please input lenth:";
cin >> len;
int arr[len];
for(int i=0; i<len; i++){
cout << "please input num:";
cin >> arr[i];
}
quickSort(0,len-1,arr);
for(int i=0; i<len; i++){
cout << arr[i] << " ";
}
cout << "\n";
return 0;
}
插入排序
复杂度为O(n2)
插入排序就是从第一个开始进行与前面的对比,因为第0个已经是当作有序的数组了。然后从第一个开始与前面对比,以此往后移动。
以[1, 5, 4, 3, 4, 5, 6, 8]为例:
key = arr[i]
首先j是认定为排好顺序的,然后从i开始与前面的进行对比,i>j所以,5保持位置不变。
第二轮到了这里,然后5>4,所以进行的操作是arr[j+1] = arr[j]也就是5移位到4,然后4再进跟前面1的对比。
然后是这样了,接着比较1跟4,1<4所以不进行操作
接着i和j分别指向3和5.
进行第一次比对,5>3所以5后移
while(j>=0 && arr[j]> key){
arr[j+1] = arr[j];
j--;
}
在比较4和3,4>3所以4后移
while(j>=0 && arr[j]> key){
arr[j+1] = arr[j];
j--;
}
然后重复上面的步骤。
- 代码实现
#include <iostream>
using namespace std;
void Insert_Sort(int *arr, int len){
int j,key;
for(int i=1; i<len; i++){
key = arr[i];
j = i-1;
while(j>=0 && arr[j]> key){
arr[j+1] = arr[j];
//swap(&arr[j+1], &arr[i]);
j--;
}
arr[j+1] = key;
//swap(&arr[j+1], &key);
}
}
int main(){
int len;
cout << "please input len:";
cin >> len;
int arr[len];
for(int i=0; i<len;i++){
cout << "please input num:";
cin >> arr[i];
}
Insert_Sort(arr,len);
for(int i=0; i<len; i++){
cout << arr[i] << " " ;
}
cout << "\n";
return 0;
}