#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//内排序--排序整个过程中,待排的所有记录都被放置在内存中
//外排序--排序的记录个数太多,不能同时存放在内存,整个排序过程需要在内外存之间多次交换数据才能进行
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 交换排序类 ---改进冒泡 O(n)顺序 O(n^2)逆序 O(n)
**************************************************************/
void BubbleSort(int *arr,int len)
{
int i;
int j;
int tmp;
bool flag=true;
for(i=0;i<len-1&&flag;i++)
{
flag=false;
for(j=0;j<len-i-1;j++)
{
if(arr[j]>arr[j+1])
{
tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
flag=true;
}
}
}
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 交换排序类 ---快速排序 O(nlogn) O(n^2) O(logn)
**************************************************************/
int Partition(int *arr,int low,int high)
{
int tmp=arr[low];
while(low<high)
{
while((low<high)&&(tmp<=arr[high])){ --high; }
arr[low]=arr[high];
while((low<high)&&(tmp>=arr[low])){ ++low; }
arr[high]=arr[low];
}
arr[low]=tmp;
return low;
}
void Quick(int *arr,int low,int high)
{
if(low<high)
{
int par=Partition(arr,low,high);
Quick(arr,low,par-1);
Quick(arr,par+1,high);
}
}
void QuickSort(int *arr,int len)
{
Quick(arr,0,len-1);
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 选择排序类 ---简单选择 O(n^2) O(n^2) O(1)
* 特点---交换移动数据的时候相当少
**************************************************************/
void SelectSort(int* arr,int len)
{
int tmp,i,j;
int minIndex;
for(i=0;i<len-1;i++)
{
minIndex=i;
for(j=i;j<len;j++)
{
if(arr[j]<arr[minIndex])
{
minIndex=j;
}
}
if(i!=minIndex)
{
tmp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=tmp;
}
}
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 选择排序类 ---堆排序
**************************************************************/
void AdjustHeap(int *arr,int start,int end)
{
int i=0;
int tmp=arr[start];
for(i=2*start+1;i<=end;i=(i*2+1))
{
if((i<end)&&(arr[i]<arr[i+1]))
{
++i;
}
if(tmp<arr[i])
{
arr[start]=arr[i];
start=i;
}
else
{
break;
}
}
arr[start]=tmp;
}
void HeapSort(int* arr,int n)
{
int tmp;
int i;
for(i=(n-1-1)/2;i>=0;i--)
{
AdjustHeap(arr,i,n-1);
}
for(i=n-1;i>0;--i)
{
tmp=arr[0];
arr[0]=arr[i];
arr[i]=tmp;
AdjustHeap(arr,0,i-1);
}
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 插入排序类 ---直接插入 O(n) O(n^2) O(1)
* 特点:有序数少极棒!!!
**************************************************************/
void InsertSort(int* arr,int len)
{
int i;
int j;
int tmp;
for(i=1;i<len;i++)
{
tmp=arr[i];
for(j=i-1;j>=0;j--)
{
if(tmp>=arr[j])
{
break;
}
arr[j+1]=arr[j];
}
arr[j+1]=tmp;
}
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 插入排序类 ---希尔排序 O(n^1.3) O(n^2) O(1)
**************************************************************/
void ShellInsert(int *arr,int len,int gap)
{
int i;
int j;
int tmp;
for(i=gap;i<len;i++)
{
tmp=arr[i];
for(j=i-gap;j>=0;j-=gap)
{
if(tmp>=arr[j])
{
break;
}
arr[j+gap]=arr[j];
}
arr[j+gap]=tmp;
}
}
void ShellSort(int *arr,int len)
{
int gapArr[] = {3,1};
for(int i=0;i<sizeof(gapArr)/sizeof(gapArr[0]);i++)
{
ShellInsert(arr,len,gapArr[i]);
}
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* 归并排序类 ---归并排序 O(nlogn)
**************************************************************/
void Merge(int *arr,int*brr,int len,int gap)
{
int low1=0;
int high1=low1+gap-1;
int low2=high1+1;
int high2=((low2+gap)<=len)? (low2+gap-1):(len-1);
int i=0;
while(low2<len)//保证有两个归并段
{
while((low1<=high1)&&(low2<=high2))
{
if(arr[low1]<=arr[low2])
{
brr[i++]=arr[low1++];
}
else
{
brr[i++]=arr[low2++];
}
}
while(low1<=high1)
{
brr[i++]=arr[low1++];
}
while(low2<=high2)
{
brr[i++]=arr[low2++];
}
low1=high2+1;
high1=low1+gap-1;
low2=high1+1;
high2=((low2+gap)<=len)?(low2+gap-1):(len-1);
}
while(low1<len)
{
brr[i++]=arr[low1++];
}
}
void MergeSort(int* arr,int len)
{
int *brr = (int *)malloc(sizeof(int)*len);
assert(brr != NULL);
for(int i=1;i<len;i*=2)
{
Merge(arr,brr,len,i);
for(int j=0;j<len;j++)
{
arr[j] = brr[j];
}
}
free(brr);
}
/**************************************************************
* 主要操作 排序方法 最好时间 最坏时间 空间复杂度
* ---基数排序
**************************************************************/
typedef struct Node
{
int data;
struct Node *next;
}Node,*List;
static Node *BuyNode(int val)
{
Node* p=(Node*)malloc(sizeof(Node));
assert(p!=NULL);
p->data=val;
p->next=NULL;
return p;
}
bool Insert_Tail(Node *phead,int val)
{
Node *p=phead;
Node *ptmp=BuyNode(val);
while(p->next!=NULL)
{
p=p->next;
}
p->next=ptmp;
return true;
}
//获取第一个数据节点的值,并删除该节点
bool GetTop(Node* phead,int *rtVal)
{
assert(phead != NULL);
if(phead->next == NULL)
{
return false;
}
Node *p = phead->next;
*rtVal = p->data;
phead->next = p->next;
free(p);
return true;
}
//获取十进制val的第digit位的值,
//digit从右往左计数,从0开始
int GetValByDigit(int val,int digit)//123,
{
while(digit--)
{
val/=10;
}
return val%10;
}
int Max(int *arr,int len)
{
int max=arr[0];
for(int i=0;i<len;i++)
{
if(max<arr[i])
{
max=arr[i];
}
}
return max;
}
//获取十进制数val的位数
int GetDigit(int val)
{
int count = 0;
if(val == 0)
{
return 1;
}
while(val != 0)
{
count++;
val /= 10;
}
return count;
}
void RadixSort(int *arr, int len)
{
Node head[10] = {{0,NULL}};
int i,j,k=0,index;
int digit = GetDigit(Max(arr,len));
for(i=0;i<digit;i++)//d
{
for(j=0;j<len;j++)
{
index = GetValByDigit(arr[j],i);
Insert_Tail(&head[index],arr[j]);
}
for(index=0;index<10;index++)//取所有桶的数据
{
while(GetTop(&head[index],&arr[k]))//取一个桶的全部数据
{
k++;
}
}
}
}
/*****************************************************
* 打印函数
*****************************************************/
void Show(int *arr,int len)
{
for(int i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void main()
{
int arr[]={9,8,7,6,5,4,3,2,1};
InsertSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","InsertSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
ShellSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","ShellSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
BubbleSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","BubbleSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
SelectSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","SelectSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
QuickSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","QuickSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
HeapSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","HeapSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
MergeSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","MergeSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
RadixSort(arr,sizeof(arr)/sizeof(arr[0]));
printf("%-12s","RadixSort:");
Show(arr,sizeof(arr)/sizeof(arr[0]));
}