重温数据结构写的几种常用排序方法,给新手参考

w0911h 2009-10-21 11:33:11
顺手写的,难免有些小错误,请不要介意,新手可以看看。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
#include <memory.h>
#include <time.h>

void print(int a[], int n)
{
int i = 1;
while(i<=n)
{
printf("%d,", a[i]);
i++;
}
printf("\n");

return;
}

//直接插入排序,时间复杂度O(n^2),空间复杂度O(1),稳定排序
//a[0]不参与排序,实际排序空间为a[1]~a[n]
void InsertSort(int a[], int n)
{
for(int i=2; i<=n; i++)
{
if(a[i]<a[i-1])
{
a[0] = a[i];
int j = i - 1;
//扫描有序空间,
while(a[0]<a[j])
{
a[j+1] = a[j];
j--;
}
a[j+1] = a[0];
}
}
printf("InsertSort : ");
print(a, n);

return;
}

//一次Shell排序过程
void ShellPass(int a[], int n, int increment)
{
for(int i=increment+1; i<=n; i++)
{
if(a[i]<a[i-increment])
{
a[0] = a[i];
int j=i-increment;
while(j>0 && a[0]<a[j])
{
a[j+increment] = a[j];
j -= increment;
}
a[j+increment] = a[0];
}
}

return;
}

//Shell排序,时间复杂度依赖于增量序列,应避免互为倍数的增量序列,
//目前较好时间复杂度为n^1.25~1.6n^1.25,空间复杂度为O(1),不稳定排序
void ShellSort(int a[], int n)
{
int increment = 20;
do
{
increment = increment/3 + 1;
ShellPass(a, n, increment);
}while(increment>1);

printf("ShellSort : ");
print(a, n);

return;
}

//冒泡排序,时间复杂度O(n^2),空间复杂度O(1),稳定排序
void BubbleSort(int a[], int n)
{
for(int i=1; i<n; )
{
int lastExchangePos = n;//记录一次排序中最后一次交换的位置,此位置之前的所有数据都已有序
for(int j=n-1; j>=i; j--)
{
if(a[j+1]<a[j])
{
a[0] = a[j+1];
a[j+1] = a[j];
a[j] = a[0];
lastExchangePos = j+1;
}
}
i = lastExchangePos;
}

printf("BubbleSort : ");
print(a, n);

return;
}

////快速排序,平均时间复杂度为O(nlgn),空间复杂度为O(lgn)~O(n),快速排序不稳定。
//C++中快速排序的实现,
void QuickSort(int a[], int low, int high)
{
srand(time(0));
a[0] = a[rand()%(high-low+1)+low];//随机选择基准,改善快排的性能

int tmp = 0;
int i = low, j = high;
while(i<=j)
{
while(i<high && a[i]<a[0])
i++;

while(j>low && a[j]>a[0])
j--;

if(i<=j)
{
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
}

if(j>low)
QuickSort(a, low, j);
if(i<high)
QuickSort(a, i, high);

return;
}

//快速排序的一次划分
int Partition(int a[], int low, int high)
{
srand(time(0));
int pos = rand()%(high-low+1)+low;
a[0] = a[pos];

a[pos] = a[low];

while(low<high)
{
while(low<high && a[0]<a[high])
high--;
if(low<high)
a[low++] = a[high];

while(low<high && a[0]>a[low])
low++;
if(low<high)
a[high--] = a[low];
}

a[low] = a[0];

return low;
}

//数据结构中标准的快速排序算法
void QSort(int a[], int low, int high)
{
if(low<high)
{
int p = Partition(a, low, high);
QSort(a, low, p-1);
QSort(a, p+1, high);
}

return;
}

//直接选择排序,时间复杂度为O(n^2),空间复杂度为O(1),不稳定排序
void SelectSort(int a[], int n)
{
for(int i=1; i<=n; i++)
{
int min = i;
for(int j=i+1; j<=n; j++)
{
if(a[j]<a[min])
min = j;
}
if(min!=i)
{
a[0] = a[i];
a[i] = a[min];
a[min] = a[0];
}
}

printf("SelectSort : ");
print(a, n);
return;
}

//调整堆
void Heapify(int a[], int s, int to)
{
/*
//Heapify方法的递归算法
a[0] = a[s];
int tmp = 2*s;
if(tmp+1<=to && a[tmp]<a[tmp+1])tmp++;

if(tmp<=to && a[0]<a[tmp])
{
a[s] = a[tmp];
a[tmp] = a[0];
Heapify(a, tmp, to);
}*/

//Heapify方法的递推算法
a[0] = a[s];
for(int j=2*s; j<=to; j*=2)
{
if(j+1<=to && a[j]<a[j+1])j++;

if(j<=to && a[0]>=a[j])
break;

a[s] = a[j];
// a[j] = a[0];
s = j;
}
a[s] = a[0];

return;
}

//堆排序,最坏时间复杂度nlgn,空间复杂度为O(1),不稳定排序,适合大量数据的排序
void HeapSort(int a[], int n)
{
for(int j=n/2; j>0; j--)
Heapify(a, j, n);

for(int j=n; j>1; j--)
{
a[0] = a[j];
a[j] = a[1];
a[1] = a[0];
Heapify(a, 1, j-1);
}

printf("HeapSort : ");
print(a, n);

return;
}

//归并排序的一次合并过程
void MergePass(int a[], int low, int mid, int high)
{
int *p = (int*)malloc(sizeof(int)*(high-low+1));
assert(p!=NULL);

int *pi = p;
int i = low, j = mid+1;
while(i<=mid && j<=high)
*(pi++) = (a[i]<=a[j])? a[i++] : a[j++];

while(i<=mid)
*(pi++) = a[i++];
while(j<=high)
*(pi++) = a[j++];

pi = p;
while(low<=high)
a[low++] = *(pi++);

free(p);

return;
}

//归并排序,时间复杂度O(nlgn),空间复杂度O(n),稳定排序
void MergeSort(int a[], int low, int high)
{
if(low<high)
{
int mid = (low+high)/2;
MergeSort(a, low, mid);
MergeSort(a, mid+1, high);
MergePass(a, low, mid, high);
}

return;
}
int main()
{
//source[0]不参与排序,做为辅助空间使用
int source[] = {0, 10, 8, 30, 55, 6, 0, 99, 87, -5, 32, 66, 54, 33, 21, 32, 96, 121, 70};
int n = sizeof(source)/sizeof(source[0])-1;

int a[sizeof(source)/sizeof(source[0])];
memcpy(a, source, sizeof(source));
InsertSort(a, n);

memcpy(a, source, sizeof(source));
ShellSort(a, n);

memcpy(a, source, sizeof(source));
BubbleSort(a, n);

memcpy(a, source, sizeof(source));
QuickSort(a, 1, n);
printf("QuickSort : ");
print(a, n);

memcpy(a, source, sizeof(source));
QSort(a, 1, n);
printf("QSort : ");
print(a, n);

memcpy(a, source, sizeof(source));
SelectSort(a, n);

memcpy(a, source, sizeof(source));
HeapSort(a, n);

memcpy(a, source, sizeof(source));
MergeSort(a, 1, n);
printf("MergeSort : ");
print(a, n);

return 0;
}
...全文
333 1 收藏 10
写回复
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
冻结 2009-10-21
非常很好,非常很强大。
回复
yunyun050924 2009-10-21
谢谢楼主,顺便接分
回复
ArmStronger 2009-10-21
温习一下,有些排序都生疏了
回复
whg01 2009-10-21
jf
回复
james_hw 2009-10-21
mark
回复
LAN_YT 2009-10-21
这个挺不错。。。
回复
xfate 2009-10-21
收藏,谢谢了
回复
企-鹅 2009-10-21
收藏。。。
回复
cyldf 2009-10-21
mark
回复
heis07w 2009-10-21
好,不错!
回复
发动态
发帖子
新手乐园
创建于2007-09-28

3.2w+

社区成员

C/C++ 新手乐园
申请成为版主
社区公告
暂无公告