核心思想:分治 + 递归
1:找一个基准元素,将比它小的都移到它左边,将比它大的都移到它右边,这样就分成了左右两个子区间——分治思想
2:分别对左右两子区间再进行上述步骤,最终子区间越来却小,所有元素均有序—递归思想
时间复杂度:快速排序的时间复杂度在最坏情况下是O(n^2),平均的时间复杂度是O(n*log n)。
另外,快速排序是一种不稳定的排序算法,即两个相等元素排序前后的相对位置可能会改变。
算法实现步骤:
1:使数组第一个元素为基准,用temp记住,建立索引 i, j 用于两头遍历,当arr[i]<temp时,i往后移,当arr[j]>temp时,j往前移,两个停下的时候就说明此时arr[i]>temp, arr[j]<temp ,此时我们交换arr[i]和arr[j]的值 ,交换完之后更新索引,只要i<j ,就一直进行上面的步骤。最终i和j会相遇 ,此时把基准值赋值给j位置 ,就达到了 j左边的元素都比arr[j]小 ,而j右边的元素都比arr[j]大 ,返回基准值所在索引j
2:分别对 j 左边区间和j右边的区间进行上述步骤,再调用函数本身,不断将区间划分为子区间,直到子区间内只有1个元素,整个数组达到有序。
下面给出具体的代码:
感觉懂C++的人比较多,就先给出用C++写的代码,便于理解:
int Partition(int arr[],int low,int high)
{
int temp=arr[low];//初始基准
int i=low+1;
int j=high;
while(i<=j)
{
while(arr[i]<temp)//当i对应的值小于基准值,就一直向右移动
{
i++;
}
while(arr[j]>temp)//当j对应的值大于基准值,就一直向左移动
{
j--;
}
if(i<j)//两者未相遇,交换位置
{
swap(arr[i],arr[j]);
i++;
j--;
}
}
swap(arr[low],arr[j]); //两者相遇,将基准值放到正确的位置
return j;
}
void Quick_sort(int arr[],int low,int high)
{
if(low>high)
{
return;
}
int pivot=Partition(arr,low,high);
Quick_sort(arr,low,pivot-1);//排序左边区间
Quick_sort(arr,pivot+1,high);//排序右边区间
}
测试结果如下:
顺便用python写了一下,思想是一样的,只是语法上有点小区别:
def Partition(lst,low,high):
temp=lst[low]
i=low+1
j=high
while i<=j:
while lst[i]<temp:
i+=1
while lst[j]>temp:
j-=1
if i<j:
lst[i],lst[j]=lst[j],lst[i]
i+=1
j-=1
lst[low],lst[j]=lst[j],lst[low]
return j
def Quick_sort(lst,low,high):
if low>high:
return
else:
povit_index=Partition(lst,low,high)
Quick_sort(lst,low,povit_index-1)
Quick_sort(lst,povit_index+1,high)
lst1=[5,3,4,9,8,0,2,1,7,6]
print(lst1)
Quick_sort(lst1,0,9)
print(lst1)
上面的代码是初学python时写的,几乎就差不多是直接从C++翻译过来的,这就不符合python 简洁易懂的风格了,今天按感觉写了个快速排序,回来贴上,感觉这种写法理解起来比较符合快速排序算法思想和 python的风格。真是学无止境啊!
def quick_sort(arr):
if len(arr)<2:
return arr
#找个基准,随便哪个都行,便于理解,这里找中间那个
mid=arr[len(arr)//2]
left,right=[],[]
#移除基准
arr.remove(mid)
for item in arr:
#小于基准的放在左边
if item<=mid:
left.append(item)
#大于基准的放在右边
else:
right.append(item)
return quick_sort(left)+[mid]+quick_sort(right)
arr=[-9,-78,3.8,2,4,7]
print(quick_sort(arr))
这样写,时间复杂度虽然还是 n*log(n) 但是空间复杂度增加了不少,因为每次得重新声明数组。
如有问题,欢迎随时指出!最近打算将这些常用数据结构、算法总结整理一下,将不定期更新内容。