需要熟悉各种排序算法 或者 直接使用sort()函数。本文使用快速排序完成排序
2.1 题目来源:PTA / 拼题A
2.2 题目地址: 统计工龄
排序算法基础练习题
8 //员工人数
10 2 0 5 7 2 5 2 //每个员工的工龄
0:1 //员工工龄:对应的人数
2:3
5:2
......
通过数组存储每个员工的工龄,然后使用快速排序对员工工龄进行排序,最后按要求输出即可
快速排序实现难度比较大,容易出错。还是sort()省心省力鸭
使用数组存储员工工龄数据
typedef int ElementType;
#define max 100010
ElementType A[max];
程序伪码描述
int main()
{
1.存储工龄数据
2.排序
3.按要求打印
}
2.3.1 QuickSort() 提供统一调用接口,本质是调用Qsort()函数
void QuickSort(ElementType A[], int N)
{
Qsort(A, 0, N - 1);
}
2.3.2 Qsort() 核心函数,AC的关键。快速排序的步骤如下:
(1)选择基准:示例中用的是从数组的头、中、尾中选取中间值作为基准(三数取中)
ElementType MedianThree(ElementType A[], int Left, int Right) //3数取中
{
int Center = (Left + Right) / 2;
if (A[Left] > A[Center])
Swap(&A[Left], &A[Center]); //&A[Left]表示数组元素A[Left]的地址
if (A[Left] > A[Right])
Swap(&A[Left], &A[Right]);
if (A[Center] > A[Right])
Swap(&A[Center], &A[Right]);
//经过上面的位置交换后,A[Left] < A[Center] < A[Right]
Swap(&A[Center], &A[Right-1]); /* 将基准Pivot放到右边,这样只需关心 Left+1 到 Right-2的数据了*/
return A[Right - 1]; /* 返回基准Pivot */
}
(2)从小到大排序,比基准小的移到基准左边,大的移到右边,重复上述操作,直到Low > High,即:此时达成了这样的效果,标志位Low前的数值都比基准小,位置Low及之后的数值比基准大。将标准为Low的元素与基准交换位置,这个位置就是基准元素的最终排序位置。这样说有点难以理解,请参考下面的画图和代码(示例中,5是第一次快速排序的基准)
Pivot = MedianThree(A, Left, Right); /* Pivot就是选定的基准 */
Low = Left;
High = Right - 1;
while (1) /*将序列中比基准小的移到基准左边,大的移到右边*/
{
while (A[++Low] < Pivot) {}
while (A[--High] > Pivot) {}
if (Low < High) //Low=High时的情况? 想象下 2 2 2 2的快排过程
Swap(&A[Low], &A[High]);
else break;
}
Swap(&A[Low], &A[Right - 1]); //交换之后,就找到了基准的最终排序位置了
(3)通过递归分别解决基准的左边 和 右边,由于用到了递归,当元素数量不多时,直接使用简单排序进行处理(比如快速排序)
void Qsort(ElementType A[], int Left, int Right)
{
int Pivot, Low, High;
if (Right - Left >= 100) //待排序数据不小于100时,使用快速排序
{
找到基准最终位置的代码见(2) //找到基准的最终位置后(Low就是最终位置),通过递归进行处理
Qsort(A, Left, Low - 1); /* 递归解决左边 */
Qsort(A, Low + 1, Right); /* 递归解决右边 */
}
else
Insert_Sort(A + Left, Right - Left + 1); /* 为提高效率,元素小于100时用插入排序 */
}
2.3.3 PrintResult() 按要求进行打印
void PrintResult(ElementType A[], int n)
{
int count = 1;
for (int i = 0; i < n; )
{
while (i <= n - 2 && A[i] == A[i + 1])
{
count++;
i++;
}
cout << A[i] << ":" << count << endl;
i++; count = 1;
}
}
如有建议或问题,欢迎留言
#include
#include
using namespace std;
typedef int ElementType;
#define max 100010
#define Cutoff 100
void Insert_Sort(ElementType A[], int n);
ElementType MedianThree(ElementType A[], int Left, int Right);
void Swap(ElementType* a, ElementType* b);
void Quick_Sort(ElementType A[], int N);
void Qsort(ElementType A[], int Left, int Right);
void PrintResult(ElementType A[], int n);
int main()
{
int n; ElementType A[max];
cin >> n;
for (int i = 0; i < n; i++)
cin >> A[i];
Quick_Sort(A, n);
PrintResult(A, n);
}
void PrintResult(ElementType A[], int n)
{
int count = 1;
for (int i = 0; i < n; )
{
while (i <= n - 2 && A[i] == A[i + 1])
{
count++;
i++;
}
cout << A[i] << ":" << count << endl;
i++; count = 1;
}
}
void Insert_Sort(ElementType A[], int n) // The similar as arrange the playing card
{
int P, i, tmp;
for (P = 1; P < n; P++)
{
tmp = A[P]; //draw a card
for (i = P; i > 0 && A[i - 1] > tmp; i--)
A[i] = A[i - 1]; //move the sorted card and find the position
A[i] = tmp; //insert the position
}
return;
}
ElementType MedianThree(ElementType A[], int Left, int Right) //3数取中
{
int Center = (Left + Right) / 2;
if (A[Left] > A[Center])
Swap(&A[Left], &A[Center]); //&A[Left]表示数组元素A[Left]的地址
if (A[Left] > A[Right])
Swap(&A[Left], &A[Right]);
if (A[Center] > A[Right])
Swap(&A[Center], &A[Right]);
Swap(&A[Center], &A[Right-1]); /* 将基准Pivot藏到右边,这样只需关心 Left+1 至 Right-2的数据了*/
return A[Right - 1]; /* 返回基准Pivot */
}
void Qsort(ElementType A[], int Left, int Right)
{
int Pivot, Low, High;
if (Right - Left >= Cutoff) //待排序数据不小于100时,使用快速排序
{
Pivot = MedianThree(A, Left, Right); /* 选基准 */
Low = Left;
High = Right - 1;
while (1) /*将序列中比基准小的移到基准左边,大的移到右边*/
{
while (A[++Low] < Pivot) {}
while (A[--High] > Pivot) {}
if (Low < High) //Low=High时的情况?
Swap(&A[Low], &A[High]);
else break;
}
Swap(&A[Low], &A[Right - 1]); /* 将基准换到正确的位置 */
Qsort(A, Left, Low - 1); /* 递归解决左边 */
Qsort(A, Low + 1, Right); /* 递归解决右边 */
}
else
Insert_Sort(A + Left, Right - Left + 1); /* 为提高效率,元素小于100时用插入排序 */
}
void Quick_Sort(ElementType A[], int N)
{
Qsort(A, 0, N - 1);
}
void Swap(ElementType* a, ElementType* b) //直接交换
{
int tmp=*a; *a = *b; *b = tmp;
}
浙江大学 陈越、何钦铭老师主讲的数据结构