二分法查找和排序 示例:数组
#include <stdio.h>
/*
二分法查找和排序示例
20190626
*/
int main()
{
int data[10] = {7,1,11,67,5,3,89,4,5,33};
for(int i=1;i<10;i++) //大循环 从数组第2个元素开始,前面的第一个元素构成一个有序数组(此时数组里只有一个元素,固然是"有序"的了) , 在大循环的第一次循环中,把第2个元素经过二分查找方法,插入前面的有序数组(只有一个元素)中, 这样头两个元素就构成一个新的有序数组. 依次类推, 下次循环把第三个元素插入前面的有序数组中... 不断循环下去, 整个数组就排序了.
{
int mid=0; //二分位置
int left=0; //左边界位置
int right=i-1; // 右边界位置
int tmp=data[i];
while(left<=right) //若是左右边界重合了, 即left==right了, 但此时插入元素可能比重合处的元素小,也可能比重合处的元素大,所以,还要循环一次,进一步与重合处位置处的元素比较 ,因此这里的循环条件必须是 (left<=right)
{
mid=(left+right)/2; //求中间元素数组坐标 (~~当左右边界重合时, 中间元素就是自身)
if(tmp<data[mid]){ //把待插入数与二分位置处元素比较, 若是比二分元素小,则右边界right移到二分元素以前的位置
right=mid-1;
}else{ //若是大于等于二分元素,则左边界left移动到二分元素以后的位置
left=mid+1;
}
printf("mid=%d,left=%d,right=%d\n",mid,left,right);
}
//循环结束时, 插入位置就是left所指向的位置.
for(int j=i-1;j>=left;j--) //循环的做用是把有序数组中元素从left位置向后平移一次,把left位置腾出来
{
data[j+1]=data[j];
}
data[left]=tmp; //腾出的left位置放入要插入元素
}
for (int i = 0; i <10 ; i++)
{
printf("%d ",data[i]);
}
return 0;
}排序
输出结果: mid=0,left=0,right=-1
mid=0,left=1,right=1
mid=1,left=2,right=1
mid=1,left=2,right=2
mid=2,left=3,right=2
mid=1,left=0,right=0
mid=0,left=1,right=0
mid=2,left=0,right=1
mid=0,left=1,right=1
mid=1,left=1,right=0
mid=2,left=3,right=5
mid=4,left=5,right=5
mid=5,left=6,right=5
mid=3,left=0,right=2
mid=1,left=2,right=2
mid=2,left=2,right=1
mid=3,left=4,right=7
mid=5,left=4,right=4
mid=4,left=4,right=3
mid=4,left=5,right=8
mid=6,left=7,right=8
mid=7,left=7,right=6
1 3 4 5 5 7 11 33 67 89 io