排序的稳定性
我们经常会看到说一个排序算法是稳定排序或者说是不稳定的排序,那么到底什么是稳定排序呢?
举个例子来说{9,2,2,4,0,8,6},这个数组中下标为1和下标为2的地方数字都是2,是相同的,我们经过排序之后这两个数字之间的顺序不变,那么就是稳定排序,如果两者之间顺序颠倒,那么就称之为不稳定排序。
冒泡排序算法
#include<iostream>
using namespace std;
void bubble(int arr[],int length)
{
for(int i = 0; i<length; i++)
{
if(arr[i] > arr[i+1])
{
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
void bubbleSort(int arr[], int length)
{
for(int i=length; i>0; i--)
{
bubble(arr,i);
}
}
int main()
{
int arr[7] = {1,4,2,3,8,6,9};
bubbleSort(arr,6);
for(auto i : arr)
{
cout<<i<<endl;
}
}
注意length和调用时候的数字,防止数组越界。
快速排序算法
#include<iostream>
using namespace std;
void swap(int arr[],int a, int b)
{
cout<< "swap" <<arr[a] << " " <<arr[b] <<endl;
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
int quick(int arr[], int low, int high)
{
int key = arr[low];
int pos = low;
while(low < high)
{
while(low<high && arr[high] >= key)
{
high--;
}
while(low<high && arr[low] <= key)
{
low++;
}
swap(arr,low,high);
}
swap(arr,pos,high);
return low;
}
void quickSort(int arr[],int low,int high)
{
int p = 0;
if(low >= high)
{
return;
}
p = quick(arr,low,high);
quickSort(arr,low,p-1);
quickSort(arr,p+1,high);
}
int main()
{
int arr[7] = {4,1,2,3,8,6,9};
quickSort(arr,0,6);
//quick(arr,0,6);
for(auto i : arr)
{
cout<<i<<endl;
}
}
或者quick函数可以写成下面这个函数
int partition(int arr[], int left, int right)
{
int key = arr[left];
while(left < right)
{
while(left<right && arr[right] >= key)
right--;
swap(arr,left,right);
while(left<right && arr[left] <= key)
left++;
swap(arr,left,right);
}
return left;
}
- 选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴。 设置两个变量left =0;right = N - 1;从left一直向后走,直到找到一个大于key的值,right从后至前,直至找到一个小于key的值,然后交换这两个数。 重复第三步,一直往后找,直到left和right相遇,这时将key放置left的位置即可。
- 冒泡排序和快速排序都是属于交换排序类
堆排序
#include <iostream>
using namespace std;
void swap(int arr[],int a, int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
void adjust(int arr[], int begin, int end)
{
int temp = arr[begin];
for(int i = 2*begin+1; i<=end; i*=2)
{
if(i<end && arr[i] <arr[i+1])
i++;
if(temp > arr[i])
break;
arr[begin] = arr[i];
begin = i;
}
arr[begin] = temp;
}
void Sort(int arr[], int size)
{
for(int i = size/2; i>=0; i--)
{
adjust(arr,i,size);
}
for(int i =size; i>0; i--)
{
swap(arr,i,0);
adjust(arr,0,i-1);
}
}
int main()
{
int arr[6] = {12,3,5,8,9,10};
Sort(arr,5);
for(auto ele: arr){
cout<<ele<<endl;
}
return 0;
}
选择排序算法
#include<iostream>
using namespace std;
void swap(int arr[],int a, int b)
{
cout<< "swap" <<arr[a] << " " <<arr[b] <<endl;
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
int finfMax(int arr[], int length)
{
int flag = arr[0];
int pos = 0;
for(int i=0;i<length;i++)
{
if(arr[i] > flag)
{
flag = arr[i];
pos = i;
}
}
return pos;
}
int selectionSort(int arr[], int length)
{
for(int i =length; i>0; i--)
{
int j = finfMax(arr,i);
swap(arr,i,j);
}
}
int main()
{
int arr[7] = {4,1,2,3,8,6,9};
selectionSort(arr,6);
//quick(arr,0,6);
for(auto i : arr)
{
cout<<i<<endl;
}
}
插入排序算法
代码:
#include<iostream>
using namespace std;
void insertSort(int arr[],int n){
int i= 0;
int j = 0;
for( i=0; i<n; i++){
if(arr[i+1] < arr[i])
{
//保存值并且做flag用
int temp = arr[i+1];
for(j = i; arr[j]>temp; j--)
{
//往后移
arr[j+1] = arr[j];
}
//放到正确的位置
arr[j+1] = temp;
}
}
}
int main(){
int arr[6] = {0,3,5,1,4,2};
insertSort(arr,6);
for (auto it:arr)
{
cout<<it<<endl;
}
}
时间复杂度
选择排序和冒泡排序算法的时间复杂度都是n的平方。
快速排序算法的时间复杂度 如果每次的关键字都选的很好 ,那么时间复杂度就是o(nlogn),如果最坏每次都只能分出来一个的话,那么时间复杂度就是o(n平方)。
空间复杂度
选择排序和冒泡排序算法都借助了0(1)的空间复杂度。
快速排序算法的空间复杂度也是logn到n之间。
稳定||不稳定
冒泡排序和选择排序都是稳定排序,但是快速排序是不稳定的排序算法。