每日一算法|快速排序---第三天
Posted 江小湖资源分享平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一算法|快速排序---第三天相关的知识,希望对你有一定的参考价值。
快速排序
快就完事
算法
原理
快速排序
快速排序是对冒泡排序的一种改进。
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
我们来分析一下
首先是要有一个分界值(也叫基准数,我更喜欢叫它参照值 ),这个分界值一般取要排序数列的第一个数。然后就是排序的过程,先是从右端的数开始和分界值比较,如果该值比分界值小,那这个值就和分界值交换位置(交换值和下标),如果该值比分界值大,则继续用前一位的值和分界值比较,直到找出交换的。在完成从右开始和分界值的交换后,从左往右开始和分界值比较,比分界值大的就和分界值交换,以此类推。从左到右查找和从右到左的查找,都是通过下标来查找的,只要它们两者下标不相遇就可以一直进行排序,直到相遇后第一次一趟快排结束,不过,总有一次会相遇的。
进行完从右边开始的交换后,我们从左边开始进行比较,下标为1的值为30, 30>12, 两者交换位置;再之后又从右边开始,重复上面的步骤,直到分界值12左边的值都比12小,分界值12右边的值都比12大,这就完成了第一趟的遍。结果为:
第二趟遍历:
按照第一趟的方法重复进行即可,分界值依然为12。
C语言
#include<stdio.h>
void Swap(int arr[], int low, int high)
{
int temp;
temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
int Partition(int arr[], int low, int high)
{
int base = arr[low]; //base为基准数,取数组第一个
while(low < high)
{
while(low < high && arr[high] >= base)
{
high --;
}
Swap(arr, low, high);
while(low < high && arr[low] <= base)
{
low ++;
}
Swap(arr, low, high);
}
return low;
}
void QuickSort(int arr[], int low, int high)
{
if(low < high)
{
int base = Partition(arr, low, high);
QuickSort(arr, low, base - 1);
QuickSort(arr, base + 1, high);
}
}
int main()
{
int n;
scanf("%d\n",&n);
int arr[n];
int i , j;
for(i = 0; i < n; i ++)
{
scanf("%d",&arr[i]);
}
printf("\n");
QuickSort(arr, 0, n-1);
for(j = 0; j < n; j ++)
{
printf("%4d",arr[j]);
}
return 0;
}
Java
import java.util.Arrays;public class TestQuickSort { private static int partition(int[] arr, int low, int high) { //指定左指针i和右指针j int i = low; int j= high; //将第一个数作为基准值。挖坑 int x = arr[low]; //使用循环实现分区操作 while(i<j){//5 8 //1.从右向左移动j,找到第一个小于基准值的值 arr[j] while(arr[j]>=x && i<j){ j--; } //2.将右侧找到小于基准数的值加入到左边的(坑)位置, 左指针想中间移动一个位置i++ if(i<j){ arr[i] = arr[j]; i++; } //3.从左向右移动i,找到第一个大于等于基准值的值 arr[i] while(arr[i]<x && i<j){ i++; } //4.将左侧找到的打印等于基准值的值加入到右边的坑中,右指针向中间移动一个位置 j-- if(i<j){ arr[j] = arr[i]; j--; } } //使用基准值填坑,这就是基准值的最终位置 arr[i] = x;//arr[j] = y; //返回基准值的位置索引 return i; //return j; } private static void quickSort(int[] arr, int low, int high) {//???递归何时结束 if(low < high){ //分区操作,将一个数组分成两个分区,返回分区界限索引 int index = partition(arr,low,high); //对左分区进行快排 quickSort(arr,low,index-1); //对右分区进行快排 quickSort(arr,index+1,high); } } public static void quickSort(int[] arr) { int low = 0; int high = arr.length-1; quickSort(arr,low,high); } public static void main(String[] args) { //给出无序数组 int arr[] = {72,6,57,88,60,42,83,73,48,85}; //输出无序数组 System.out.println(Arrays.toString(arr)); //快速排序 quickSort(arr); //partition(arr,0,arr.length-1); //输出有序数组 System.out.println(Arrays.toString(arr)); } }
Python
def quicksort(list,p,r):
if p<r:
q=partion(list,p,r)
quicksort(list,p,q)
quicksort(list,q+1,r)
def partion(list,p,r):
i=p-1
for j in range(p,r):
if list[j]<=list[r]:
i+=1
list[i],list[j]=list[j],list[i]
list[i+1],list[r]=list[r],list[i+1]
return i
list1=[2,8,7,1,3,5,6,4]
quicksort(list1,0,len(list1)-1)
print (list1)
总结:没什么好总结的,写作业去了。
喜欢记得来一个
以上是关于每日一算法|快速排序---第三天的主要内容,如果未能解决你的问题,请参考以下文章