冒泡法
/*
1.冒泡排序:遍历一遍,将相临的两个元素进行比较,并将较大/小值放到一边,一直沿着序列进行重复操作,就像一个泡泡一样冒到最左/右边
循环法:
*/
int bubble_sort(int *buf,int n)
{
if(n<2)
return -1;
int i=0,j=0,temp=0;
for(i=n-1;i>0;i--)//一共对比n-1轮
{
for(j=0;j<i;j++)//每一轮都有
{
if(buf[j]>buf[j+1])
{
temp = buf[j+1];
buf[j+1] = buf[j];
buf[j] = temp;
}
}
}
}
/*
1.冒泡排序:
递归法
*/
int bubble_sort2(int *buf,int n)
{
if(n<2)
return -1;
int i=0,j=0,temp=0;
for(j=0;j<n-1;j++)//每一轮都有
{
if(buf[j]>buf[j+1])
{
temp = buf[j+1];
buf[j+1] = buf[j];
buf[j] = temp;
}
}
bubble_sort2(buf,--n);
}
选择排序法
/*
1.选择排序:遍历一遍,找到最值,依次放到左\右侧
*/
int select_sort(int *buf,int n)
{
if(n<2)
return -1;
int i=0,j=0,minpos=0;
for(i=0;i<n-1;i++)//一共对比n-1轮
{
minpos = i;
for(j=i+1;j<n;j++)//每一轮都有
{
if(buf[j]<buf[minpos])
{
minpos = j;
}
}
if(minpos != i)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
{
swap(&buf[i],&buf[minpos]);
}
}
}
/*
1.选择排序:
递归法
*/
int select_sort2(int *buf,int n)
{
if(n<2)
return -1;
int i=0,j=0,minpos=0;
for(j=0;j<n;j++)//每一轮都有
{
if(buf[j]<buf[minpos])
{
minpos = j;
}
}
if(minpos != 0)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
{
swap(&buf[i],&buf[minpos]);
}
select_sort2(buf+1,--n);
}
使用最大最小值来优化,空间换时间
int select_sort(int *buf,int n)
{
if(n<2)
return -1;
int i=0,j=0,left,right,maxpos,minpos=0;
left = 0;
right = n-1;
while(left<right)
{
minpos = maxpos = left;
for(j=left;j<=right;j++)//每一轮都有
{
if(buf[j]<buf[minpos])
{
minpos = j;
}
if(buf[j]>buf[maxpos])
{
maxpos = j;
}
}
if(minpos != left)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
{
swap(&buf[left],&buf[minpos]);
}
if(minpos != right)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
{
swap(&buf[right],&buf[maxpos]);
}
left++;
right--;
}
插入排序
/*
1.选择排序:遍历一遍,找到最值,依次放到左\右侧
*/
int insert_sort(int *buf,int n)
{
if(n<2)
return -1;
int i=0,j=0,min=0,minpos=0;
for(i=1;i<n;i++)
{
min = buf[i];
for(j=i-1;j>=0;j--)
{
if(buf[j]<=min)
{break;}
buf[j+1]=buf[j];
}
buf[j+1] = min;
}
}
插入排序的缺陷:
1.要寻找插入的合适位置
2.要移动元素
优化方案:
1.对于已经排好序的序列,采用二分法查找
2.一次携带多个元素进行查找,找到合适的就插入一个
3.数据链表化
4.希尔排序
希尔排序
希尔排序是插入排序的一种,它是将一列数据,每次取长度的一半,规划为多个小组,然后小组内进行一次插入排序。然后重复执行步骤直到一个小组内只有一个元素。最后进行一次插入排序。它的优点是,可以快速让大量数列整体大致排列有序,减少查找次数,减少元素移动次数。
代码
/*对一个小组的数据进行插入排序*/
int group_sort(int *buf,int n,int pos,int step)
{
if(n<2)
return -1;
int i=0,j=0,min=0,minpos=0;
for(i=pos+step;i<n;i=i+step)
{
min = buf[i];
for(j=i-step;j>=0;j-=step)
{
if(buf[j]<=min)
{break;}
buf[j+step]=buf[j];
}
buf[j+step] = min;
}
}
/*按组划分,依次将步长、位置传输过去,进行一个小组的插入排序*/
void shell_sort(int *buf,int n)
{
int step=0,i=0;
for(step=(n/2);step>0;step/=2)
{
for(i=0;i<step;i++)
{
group_sort(buf,n,i,step);
}
}
}
快速排序
/*快速排序算法
第一种思路:抽空插入算法,就是先将一个数据提取出来作为标准,然后将找到的比它的小放到左边,大的放到右边。
取出一个值作为标准,取最左边为左下标,最右边为右下标,先移动右下标,找到第一个比它小的值放到空槽,然后再以这个取出来的值的空位,再起左右下标,移动左下标
找到第一个比它大的值放到空槽,一直重复到左右下标重合。
*/
int quicksort(int *buf,int n)
{
if(n<2)
return -1;
int temp = buf[0];
int left = 0;
int right = n-1;
int moving = 2;
while(left<right)
{
//buf[left];
if(moving==1)//移动的是左下标
{
if(buf[left]<=temp)
{
left++;
continue;
}
buf[right] = buf[left];
right--;
moving = 2;
continue;
}
if(moving==2)//移动的是右下标
{
if(buf[right]>=temp)
{
right--;
continue;
}
buf[left] = buf[right];
left++;
moving = 1;
continue;
}
}
/*当左右坐标值重合时,循环结束,就需要将中心轴的值填进去*/
buf[left] = temp;
quicksort(buf,left);
quicksort(buf+left+1,n-left-1);
}
第二种思路:
将最左一个作为标准,然后依次往后查看,如果小于标准值就换到左边来,大于它就逐渐挤在一块排到右边去了。然后再找下一位作为标准。
归并排序
/*归并排序:本质上是,先以二分形式,依次将它们分成一半一半的,最后分成一个为一组,再进行组合,
每次组合进行比较,比较后再重新放入暂存的数组中去。最后将暂存数组的数据导出到原数组中。*/
void mergesort(int *buf,int *temp_buf,int start,int end)
{
if(start>=end)
return -1;
int mid = (start + end)/2;
//递归部分
mergesort(buf,temp_buf,start,mid);//将中心轴左边的拆分
mergesort(buf,temp_buf,mid + 1,end);//将中心轴右边的拆分
int left = start;
int right = mid + 1;
int temp = left;
//把对比后的放入暂时存放的数组中
while(left<=mid&&end>=right)
{
if(buf[left]>buf[right])
temp_buf[temp++] = buf[right++];
else
temp[temp++] = buf[left++];
}
while(right<=end)
{
temp_buf[temp++] = buf[right++];
}
while(left<=mid)
{
temp_buf[temp++] = buf[left++];
}
while(left<=right)
{
buf[left] = temp_buf[left];
left++;
}
}
堆排序
本质上是将数据以完全二叉树的形式,做成大顶堆,然后再依次以最后一个节点与最顶端的父节点交换,交换完之后,与自己最大的子节点对比是否比它小,如果小就与调换顺序,当子节点再和之前的孙子节点对比。。。
//start:节点下标,end:最后一个元素的下标
void heapify(int *buf,int start,int end)
{
int dad = start;
int son = dad * 2 + 1;//公式得出
//遍历完所有元素
while(son<=end)
{
//子节点与另一个节点对比,找到最大的一个
if((son+1<=end)&&(buf[son]<buf[son+1]))
son++;
//如果父节点比最大子节点都大,就不需要继续找下去了
if(buf[dad]>buf[son])
return ;
//如果父节点比最大子节点小,就交换,然后还需要父节点继续作为子节点与孙子节点比较
swap(&buf[dad],&buf[son]);
dad = son;
son = dad*2+1;
}
}
void heapsort(int *buf,int len)
{
int i = 0;
//取最后一个父节点,重新规划
for(i=(len-1)/2;i>;i--)
heapify(buf,i,len-1);
for(i=len-1;i>0;i--)
{
swap(&buf[0],&buf[i]);
heapify(buf,0,i-1);
}
}