经典排序算法-快速排序(挖坑法、前后指针法)、基数排序

来源:互联网 发布:ubuntu wine是什么 编辑:程序博客网 时间:2024/06/05 19:16

快速排序在实际应用中是比较表现好的排序算法。快速排序我用两种方法实现它。

第一种为方法,形象的称为:挖坑法

基本思路:1、寻找pos位,然后将其分为两段数组,然后对这两段数组递归排序;

                    2、指定一个基数temp(三数取中法),定义两个指针begin一个指向起始位置,end一个指向最后一个元素的位置。begin寻找比基数(temp)大的数字,找到 后将begin的数据赋给end,begin成为一个坑,然后end寻找比基数(temp)小的数字,找到将end的数据赋给begin,end成为一个新坑,循环这个过程,直到begin指针与end指针相遇,然后将temp的数据返回给那个坑,然后进行递归操作。



 代码实现为:

int PastSort1(int *arr, int left, int right)  //挖坑法{int begin = left;int end = right;int temp = arr[mid(arr,left,right)];while (begin < end){while (begin < end && arr[begin] <= temp)begin++;if (begin < end)arr[end] = arr[begin];//begin成为新坑while (begin < end && arr[end] >= temp)end--;if (begin < end)arr[begin] = arr[end];  //end成为新坑}arr[begin] = temp;  //将temp填补进去return begin;}void QuickSort(int *arr,int left,int right){if (arr == NULL || left > right)return;int pos = PastSort1(arr, left, right);QuickSort(arr, left, pos - 1);QuickSort(arr, pos + 1, right);}
前后指针法:

定义两个指针,一前一后,前面指针找比基数小的数,后面指针找比基数大的数,前面的指针找到后,将前后指针所指向的数据交换,当前面的指针遍历完整个数组时,将基数值与后指针的后一个位置的数据进行交换,然后以后指针的后一个位置作为分界,然后将数组分开,进行递归排序。


代码实现:

int PastSort2(int* arr, int left, int right)  //前后指针法{int cur = left;  //找小int ptr = left-1;//找大int temp = arr[mid(arr, left, right)];while (cur < right){if (arr[cur] < temp){swap(arr[cur], arr[++ptr]);}cur++;}swap(arr[++ptr], arr[right]);return ptr;}void QuickSort(int *arr,int left,int right){if (arr == NULL || left > right)return;int pos = PastSort2(arr, left, right);QuickSort(arr, left, pos - 1);QuickSort(arr, pos + 1, right);}


基数排序:

基本原理是:



代码实现为:

int getbit(int* arr,int size)  //获得最大位数{int bits = 1;int rang = 10;for (int i = 0; i < size; ++i){while (arr[i] >= rang){++bits;rang *= 10;}}return bits;}void BucketSort(int* arr, int size){int bits = getbit(arr, size);int radix = 1;int count[10];for (int bit = 1; bit <= bits;bit++)  //循环最大位数次{memset(count, 0, sizeof(int)* 10);for (int i = 0; i < size; ++i)//统计数字位数的数量{int index = (arr[i] / radix) % 10;count[index]++;}for (int j = 1; j < 10; j++)  //固定数值排序的位置{count[j] = count[j] + count[j - 1];}int *str = new int[size];memset(str, 0, sizeof(int)*size);for (int i = size-1; i >=0; i--)//按照固定的位置将数据写入辅助数组{int index = (arr[i] / radix) % 10;str[count[index]-1] = arr[i];count[index]--;}radix = radix * 10;for (int i = 0; i < size; i++) //将辅助数组中的数拷贝回原数组{arr[i] = str[i];}delete[] str;}}
前面我用了三篇文章来写几种常见的排序方法,我用一个图简单分析一下他们的最好最坏平均时间复杂度,以及空间复杂度,与稳定性分析。



阅读全文
7 0
原创粉丝点击