您的位置:首页 > 编程语言

六种基本排序算法思想及C代码

2014-07-17 13:21 260 查看
描述:给定关键字k[0],k[1],key[2],...,key[n-1],对其进行排序(从小到大)

1、 直接插入排序(Straight Insert Sort)

思想:把关键字k[i]与有序区的关键字进行比较,找到应该插入的位置,然后将其插入。给定待排序列k[0]~k[n-1],则初始有序区为k[0],直接插入排序可从k=1开始。

代码:

// 1. StraightInsertion Sort,2014/7/3
void StraightInsertionSort(int key
)
{
inti,j ;
for(i = 1;i <N; i++ )
{
inttemp =key[i] ;// it would beoverlaid.
if(key[i] <key[i-1])
{
j= i -1 ;
while(temp <key[j])
{
key[j+1] =key[j] ;
j -- ;
}
key[j+1] =temp ;
}
}
}


2、 希尔排序(Shell’s Sort)

思想:又称“缩小增量排序”,是一种改进的插入排序算法。其需要设置m个增量且有(d[0] > d[1] > …> d[m])。增量的设置准则为d[0] < N, d[m] = 1,增量需要保证除了1之外没有公因子;具体有不同的设置方法,且不同的增量会导致算法的效率不同。对于第k趟排序,所有相隔d[k-1]的序列排列为有序,e.g. 排序之前key[0],key[d[k-1]],key[2*d[k-1]]…,这些为无序的,经过第k趟排序,这些序列变成有序的。其本质是:直接进行多次(m次)直接插入排序。

代码:

// 2. ShellSort,2014/7/3
void ShellSort(int key
,int *d,int m) //m is the length of d
{
inti,j,k ;
for(k = 0;k <m;k++)
{
for(i =d[k];i < N;i++)
{
inttemp =key[i] ;
if(temp <key[i-d[k]])
{
j = i - d[k] ;

while (temp <key[j])
{
key[j+d[k]] =key[j] ;
j -= d[k] ;
if (j < 0)
{
break;
}
}
key[j+d[k]] =temp ;
}
}
}
}

3、 冒泡排序(BubbleSort)

思想:冒泡排序是每次从底部(尾部)开始向上扫描,一趟扫描将最小的上浮至有序区,则第k次扫描的上界为i-1,下界为N-1。可以设置一个标志位(swap= 0,表示有交换),当无交换时将swap设为1,break,表示排序完成。该方法有种改进方法,双向冒泡等

代码:

// 3. Bubble Sort,2014/7/3
int BubbleSort(intkey
)//return the run ofsort
{
inti,j ;
inttemp ;
intrun = 0 ;
intswap ;
for(i = 0;i <N;i ++)
{
swap= 0 ;
for (j =N-1;j >i; j --)
{
if (key[j] <key[j-1])
{
temp = key[j] ;
key[j] =key[j-1] ;
key[j-1] =temp ;
swap = 1 ;
}
}
if(0 == swap)
{
break;
}
run++ ;
}
return run ;
}

4、 快速排序(QuickSort)

思想:该算法是对冒泡排序的改进,其基本思想是:通过一趟排序,将key
分成两个子序列,然后子序列通过递归执行相同操作,直到完成。

实现:分割——通过设置一个low和一个high指针,以及一个pivot基准值,通过左右交替移动,将基准值放到其最终所处位置,而其左边全小于等于基准值,右边全大于等于基准值。

快速排序—对上述的分割进行递归调用。

代码:

int Partition(intkey[],int low, int high)//返回值为low == high
{
intpivot =key[low] ;
while(low <high)
{
while(low <high&&key[high]>=pivot)
{
high-- ;
}
if(low <high)
{
key[low] =key[high] ;
low++ ;
}
while(low <high&&key[low]<=pivot)
{
low++ ;
}
if(low <high)
{
key[high] =key[low] ;
high-- ;
}
}
key[low] =pivot ;
returnlow ;
}
void QuickSort(int key
,intlow,inthigh)
{
inti ;
if(low <high)
{
i= Partition(key,low,high) ;//分割
QuickSort(key,low,i-1) ;//左边
QuickSort(key,i+1,high) ;//右边
}
}


5、 直接选择排序(Select Sort)
思想:每一次从待排序的序列中选出一个最小的放到有序区的末尾,初始有序区为key[0]。

代码:

// 6. Select Sort,2014/7/3
void SelectSort(int key
)
{
inti,j;
inttemp ;
for(i = 0;i <N; i ++)
{
intk =i ;
for(j =i+1;j<N;j++)
{
if(key[j] <key[k])
{
k = j ;
}
}
if(k !=i)
{
temp= key[k] ;
key[k] =key[i] ;
key[i] =temp ;
}
}
}

6、 归并排序(MergeSort)

思想:将两个或者两个以上的有序表合并成一个新的有序表。其基本思路是:

假设初始表含有n个值,则可以看成n个有序的子表,每个有序的子表的长度为1,然后两两归并,得到Ceil(n/2)个长度为2或者1(最后一个)个有序表,再两两归并,如此重复,直至得到一个长度为n的有序表。

代码:

// 7. Merge Sort,2014/7/3
void Merge(int key[],intlow,intmid,int high)
{
//mergekey[low]-key[mid] and key[mid+1]-key[high] into one key1[low]- key1[high]
inti,j,k ;
i =low ;
j =mid + 1;
k =0 ;
int*key1 ;
key1= (int *)malloc((high -low + 1)*sizeof(int)) ;
if(!key1)
{
puts("Malloc Error !\n") ;
exit(0);
}

while(i <=mid&&j <= high)
{
if(key[i] <=key[j])
{
key1[k] =key[i] ;
k++ ;
i++ ;
}
else
{
key1[k] =key[j] ;
k++ ;
j++ ;
}
}
while( i <= mid)
{
key1[k] =key[i] ;
k++ ;
i++ ;
}
while(j <=high)
{
key1[k] =key[j] ;
k++ ;
j++ ;
}

for(k = 0,i =low; i <= high; k++,i++)
{
key[i] =key1[k] ;
}
}

void MergePass(int key[],intlength,intn)
{
inti = 0 ;
//int j ;

while(i +length*2 - 1 <n)
{
Merge(key,i,i+length-1,i+2*length-1) ;
i+= 2*length ;
}
if(i +length - 1<n)
{
Merge(key,i,i+length-1,n-1) ;
}
}

void MergeSort(int key
)
{
intlength ;
for(length = 1;length<N; length*= 2)
{
MergePass(key,length,N) ;
}
}


参考文献:
[1] 软件技术基础,西电出版社
[2] C与指针

以上所有程序在VS2010上亲测可以运行,欢迎大家来探讨。可以直接去如下地址下载,内容相同。
http://download.csdn.net/detail/ai552368625/7646395
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: