常见的八种排序

#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]));
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值