冒泡排序
每次对相邻的两个数进行比较,类似于密码爆破一个个比对。显然比较浪费时间,且比较笨。
快速排序
冒泡排序的一种改进,也可以理解为多线程的冒泡排序
工作原理
在一串乱序数据中随机取一个值(一般代码实现都是取第一个值),然后对该数列进行分类,比随机值小的在随机值的左边,反之在右边
例子
对[0x10, 0x37, 0x4f, 0x39, 0x3e ,0x39 ,0x13 ,0x2b ,0x4f ,0x8]
进行排序,其中“●”表示取的随机值,“<”表示向左移动,“>”表示向右移动 “pivot”就是这个中间值,“left”表示当前排序的数据范围的始位置,“right”表示当前排序的数据范围的末位置
下面pivot=0x10 right=9 left=0
即表示中间值为0x10
,对该数据的0-9的索引值进行排序,以下为实现过程的部分数据
● <
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x10 right=9 left=0
数值 0x10 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x8
---------------------------------------------------------------
● >
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x10 right=9 left=1
数值 0x8 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
//完成一次左边和右边的置换后,第二次while循环
●
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x10 right=8 left=1
数值 0x8 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
●
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x10 right=7 left=1
数值 0x8 0x37 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
● //....right : 7 -> 1
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x10 right=1 left=1
数值 0x8 0x10 0x4f 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37 // array[left] = pivot
---------------------------------------------------------------
//完成第一次递归函数 得到最小值0x8
● <
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x4f right=9 left=2
数值 0x8 0x10 0x37 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
●
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x4f right=9 left=3
数值 0x8 0x10 0x37 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x37
---------------------------------------------------------------
● //.....left : 3 -> 9
索引 0 1 2 3 4 5 6 7 8 9 pivot=0x4f right=9 left=9
数值 0x8 0x10 0x37 0x39 0x3e 0x39 0x13 0x2b 0x4f 0x4f
---------------------------------------------------------------//得到最大值0x4f
//pivot=0x4f right=8 left=2,同样的方法对2-8中进行排序找到最大值
完整算法流程图
注意下面每个分支不代表一次while循环,这里简化为每次数列发生排序的结果
算法代码
//假设要对数组的0-10位进行排序 L : 0 , R : 10
void info(int *array , int L , int R){
if(L >= R) return;
int left = L;
int right = R;
int pivot = array[left];
while(left < right){
while(right > left && array[right] >= pivot) right--;
array[left] = array[right];
while(left < right && array[left] <= pivot) left++;
array[right] = array[left];
if(left == right) array[left] = pivot; //完成左右指针合并
}
//上面就完成了对中间点的左右大小的分类
info(array,L,left- 1);
info(array,right+ 1,R);
}
测试代码
int main(){
int array[10] = {0};
int len = sizeof array / sizeof (int);
srand(time(NULL));
for (int i =0 ; i < len ; i++){
¦ array[i] = rand() % 100 ;
}
/*
int array[10] = {0x10 ,0x37 ,0x4f ,0x39 ,0x3e ,0x39 , 0x13 ,0x2b ,0x4f,0x8};
int len = sizeof array / sizeof (int);
*/
printf("start->\n");
for (int i =0 ; i < len ; i++){
¦ ¦printf("%d,",array[i]);
}
info(array,0, len-1);
printf("\nend->\n");
int tmp = 0;
for (int i =0 ; i < len ; i++){
if(array[i] >= tmp)
tmp = array[i];
else{
printf("排序失败"); break;
}
printf("%d,",tmp);
if(len-1 == i)
printf("\n完成排序\n");
}
return 0;
}
运行结果
start->
34,37,27,10,66,87,11,46,66,45,
end->
10,11,27,34,37,45,46,66,66,87,
完成排序