起因
在泡CSDN,无意间刷到了一个看上去很有趣的东西,叫张仰彪排序法,看了看感觉还行,就写一篇笔记吧。
基本思路
思路十分新颖,总体来说就是排座位:找到自己的排名再移过去。
具体步骤如下:
-
初始数组:{ \({\color{red}4}\), 5, 2, 4, 1, 3,0,2, 2,0 }
-
第1步:
排位置0上的数"4", 有7个比它小的数, 它的排名为7,
由于排名7大于位置0,
所以将它与位置7上的数"2"交换。数组现在变为:
{ \({\color{red}2}\), 5, 2, 4, 1, 3,0,4, 2,0 }
-
第2步:
排位置0上的数"2", 有3个比它小的数, 它的排名为3,
由于排名3大于位置0,
所以将它与位置3上的数"4"交换。数组现在变为:
{ \({\color{red}4}\), 5, 2, 2, 1, 3,0,4, 2,0 }
-
第3步:
排位置0上的数"4", 有7个比它小的数, 它的排名为7,
由于排名7大于位置0,
所以将它与位置7上的数"4"交换。
由于将要交换的两个数相等 。
所以延后一个位置,将它与位置8上的数"2"交换,数组现在变为:
{ \({\color{red}2}\), 5, 2, 2, 1, 3,0,4, 4,0 }
-
第4步:
排位置0上的数"2", 有3个比它小的数, 它的排名为3,
由于排名3大于位置0,
所以将它与位置3上的数"2"交换。
由于将要交换的两个数相等,
所以延后一个位置,将它与位置4上的数"1"交换数组现在变为:
{ \({\color{red}1}\), 5, 2, 2, 2, 3,0,4, 4,0 }
-
第5步:
排位置0上的数"1", 有2个比它小的数, 它的排名为2,
由于排名2大于位置0,
所以将它与位置2上的数"2"交换。数组现在变为:
{ \({\color{red}2}\), 5, 1, 2, 2, 3,0,4, 4,0 }
-
第6步:
排位置0上的数"2", 有3个比它小的数, 它的排名为3,
由于排名3大于位置0,
所以将它与位置3上的数"2"交换。
由于将要交换的两个数相等,
所以延后一个位置,将它与位置4上的数"2"交换
由于将要交换的两个数相等,
所以延后一个位置,将它与位置5上的数"3"交换数组现在变为:
{ \({\color{red}3}\), 5, 1, 2, 2, 2,0,4, 4,0 }
-
第7步:
排位置0上的数"3", 有6个比它小的数, 它的排名为6,
由于排名6大于位置0,
所以将它与位置6上的数"0"交换。数组现在变为:
{ \({\color{red}0}\), 5, 1, 2, 2, 2,3,4, 4,0 }
-
第8步:
排位置0上的数"0", 有0个比它小的数, 它的排名为0,
由于排名0不大于位置0,
所以不进行交换,开始排下一个位置上的数。数组现在变为:
{ \({\color{red}0}\),5,1, 2, 2, 2,3,4,4,0 }
-
第9步:
排位置1上的数"5", 有9个比它小的数, 它的排名为9,
由于排名9大于位置1,
所以将它与位置9上的数"0"交换。数组现在变为:
{ \({\color{red}0}\), 0, 1, 2, 2, 2,3,4, 4,5 }
- 第10步: 已进行了9次排序,排序的次数正好比数组的长度小1,排序结束。
代码
思路明晰后代码就很好懂了:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[10];
int j = 0;/* 记录当前排序的位置 */
int temp;/* 数据交换时的存储中介 */
int order;/* 记录数据在数组里的大小排名,从小向大算 */
// printf(" Input 10 numbers:\n");
for (int i = 0; i < 10; i++)scanf("%d", &a[i]);
// printf("\n");
for (int i = 0; i < 9; i++)/* 排序的总次数比待排序数组的长度小1 */
{
order = j;/* 数据的排名从当前位置开始向后计算 */
for (int x = j + 1; x < 10; x++)/* 计算当前数据在数组里的排名 */
{
if (a[x] < a[j])order++;
}
if (order > j)/* 如果当前数据的排名大于它现在的位置 */
{
while(a[j] == a[order])order++;/* 处理数组里的重复数据 */
temp = a[order];/* 将这个数据交换到正确的位置上 */
a[order] = a[j];
a[j] = temp;
}
else j++;/* 如果当前数据的排名等于(不可能小于)它现在的位置 */
/* 开始排下一个位置上的数据 */
}
// printf("The sorted numbers is:\n");
for (i = 0; i < 10; i++ )printf(" %d", a[i]);
return 0;
}
总结
这个排序算法虽说并不是一个复杂度很优秀的算法,但毕竟是一个全新的算法,还是值得学习的(更何况是我们中国人发明的)。似乎比冒泡好一些