编程中的排序方法:冒泡、选择、插入、快速排序、哈希、shell等
一、冒泡排序
/*********************冒泡排序********************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<math.h>
#include<sys/types.h>
void maopao(int *a,int n)
{
int i,j,temp;
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
if(a[j]>a[j+1])
{
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
void show(int *a,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%-3d",a[i]);
}
printf("\n");
}
int main (void)
{
int a[10] = {12,23,10,14,8,22,43,1,3,0};
maopao(a,10);
show(a,10);
return 0;
}
二、选择排序
/***********************************选择排序***********************************/
void choise(int *a,int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
void show(int *a,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%-3d",a[i]);
}
printf("\n");
}
int main (void)
{
int a[10] = {10,14,8,22,94,95,4,5,6,1};
choise(a,10);
show(a,10);
return 0;
}
三、插入排序
插入法:
插入法是一种比较直观的排序方法;
它首先把数组头两个元素排好序,
再依次把后面的元素插入适当的位置,
把数组元素插完也就完成了排序。
/***********************插入排序***************************/
/**
** 插入法:
** 插入法是一种比较直观的排序方法。
** 它首先把数组头两个元素排好序,
** 再依次把后面的元素插入适当的位置。
** 把数组元素插完也就完成了排序。
**/
void insert(int *a,int n)
{
int i,j,temp;
for(i=1;i<n;i++)
{
temp = a[i];/*temp为要插入的元素*/
j = i - 1;
/*从a[i-1]开始找比a[i]小的数,同时把数组元素向后移*/
while(j>=0 && temp<a[j])
{
a[j+1] = a[j];
j--;
}
a[j+1] = temp;/*插入*/
}
}
void show(int *a,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%-3d",a[i]);
}
printf("\n");
}
int main (void)
{
int a[10] = {12,2,4,67,32,45,22,11,90,15};
insert(a,10);
show(a,10);
return 0;
}
四、快速排序
快速法定义了三个参数(数组首地址*a,要排序数组起始元素下标i,要排序数组结束元素下标j)
它首先选一个数组元素(一般为a[(i+j)/2],即中间元素)作为参照,
把比它小的元素放到它的左边,比它大的放在右边。
然后运用递归,在将它左,右两个子数组排序,
最后完成整个数组的排序。
/**********快速排序*********************/
/**
** 快速法定义了三个参数,
**(数组首地址*a,要排序数组起始元素下标i,要排序数组结束元素下标j)
** 它首先选一个数组元素(一般为a[(i+j)/2],即中间元素)作为参照,
** 把比它小的元素放到它的左边,比它大的放在右边。
** 然后运用递归,在将它左,右两个子数组排序,
** 最后完成整个数组的排序。
**/
void quick(int *a,int i,int j)
{
int m,n,temp;
int k;
m=i;
n=j;
k=a[(i+j)/2]; /*选取的参照*/
while(m<=n)
{
while(a[m]<k&&m<j) m++; /* 从左到右找比k大的元素*/
while(a[n]>k&&n>i) n--; /* 从右到左找比k小的元素*/
if(m<=n) { /*若找到且满足条件,则交换*/
temp=a[m];
a[m]=a[n];
a[n]=temp;
m++;
n--;
}
}
if(m<j) quick(a,m,j); /*运用递归*/
if(n>i) quick(a,i,n);
}
int show(int *a,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%-3d",a[i]);
}
printf("\n");
return 0;
}
int main (void)
{
int a[10] = {23,13,1,4,2,56,78,22,10,3};
quick(a,0,9);
show(a,10);
return 0;
}
五、shell排序
shell法:
shell法是一个叫 shell 的美国人与1969年发明的。
它首先把相距k(k>=1)的那几个元素排好序,再缩小k值(一般取其一半)
再排序,直到k=1时完成排序。下面让我们来分析其代码
/******************shell排序**********************/
/**
**shell法是一个叫 shell 的美国人与1969年发明的。
**它首先把相距k(k>=1)的那几个元素排好序,再缩小k值(一般取其一半)
**再排序,直到k=1时完成排序。下面让我们来分析其代码
**/
void shell(int *a,int n)
{
int i,j,k,temp;
k = n/2;
while(k>=1)
{
for(i=k;i<n;i++) {
temp = a[i];
j=i-k;
while(j>=0 && temp<a[j]) {
a[j+k]=a[j];
j-=k;
}
a[j+k]=temp;
}
k/=2; /*缩小间距值*/
}
}
void show(int *a,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%-3d",a[i]);
}
printf("\n");
}
int main (void)
{
int a[10] = {12,19,95,94,10,14,8,22,1,4};
shell(a,10);
show(a,10);
return 0;
}
折半查找(二分查找)
折半查找需要数据为有序数据
代码如下:
#include <stdio.h>
int Binary_search(int *a,int n,int obj)
{
int low,hight,mid;
low = 0;
hight = n;
mid = (low+hight)/2;
while(low<=hight)
{
mid = (low+hight)/2;
if(obj < a[mid])
hight = mid - 1;
else if(obj > a[mid])
{
low = mid + 1;
}
else
return mid;
}
return 0;
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int temp = Binary_search(a,10,5);
printf("temp = %d\n",temp);
return 0;
}
插值查找
插值查找比折半查找更快
折半查找循环中的 mid = (low+hight)/2 = low + 1/2(hight - low);
也就是mid等于最低下标low加上最高下标hight与low的差的一半.算法工程师考虑的就是将这个1/2进行改进,改进为下的计算方案:
mid = low + (obj - a[low])/(a[hight] - a[low])*(hight - low);
插值查找代码如下:
int Binary_search(int *a,int n,int obj)
{
int low,hight,mid;
low = 0;
hight = n;
mid = (low+hight)/2;
while(low<=hight)
{
mid = low + (obj - a[low])/(a[hight] - a[low])*(hight - low);
if(obj < a[mid])
hight = mid - 1;
else if(obj > a[mid])
{
low = mid + 1;
}
else
return mid;
}
return 0;
}