常见的排序算法总结

#include<cstdio>
/*算法只是比较了元素为整数的内容.大部分的排序只是做了简单的测试.仅供参考.*/

void swap(int *a , int *b)
{
    int temp = *b;
    *b = *a;
    *a = temp;
}




bool less(int a, int b)
{
    if(a < b)
	return true;
    else 
	return false;
}


//对内部中的元素先找到k值,然后分两块
int partition(int *R, int lo, int hi)
{
    int i =lo, j = hi;
    int temp = R[lo]; //这里的temp就是需要的空间?
    if(i<j){ 
	while(i != j)
	{
	    while(j>i && R[j] > temp) j--;	//扫描右边
	    if(j>i)	    //交换一部分元素
	    {
		R[i] = R[j];
		i++;


	    }
	    while(j>i &&R[i]<temp)i++;   //扫描左边交换元素.
	    if(j>i)
	    {
		R[j] = R[i];
		j--;
	    }
	}
	R[i] = temp;
    }
    return i;
}




//1.快速排序,也是把数组分成两个数组,当两个数组有序的时候,整个数组的有序
void quickSort(int *R, int lo, int hi)
{
    if(lo>=hi)
	return;
    int mid = partition(R, lo, hi);
    quickSort(R, lo, mid-1);
    quickSort(R, mid+1, hi);
}




//快速排序测试
void testquicksort()
{
    int  unorder[] = {44,1,3,22,3,13,45,23,55};
    int len = sizeof(unorder)/sizeof(int);
    quickSort(unorder,  0, len-1);
    for(int i =0 ;i< len;i++)
	printf("%d ", unorder[i]);


}
//2.冒泡本质上是一种交换排序
void buble_sort(int *R, int n)
{   int i,j,flag =0;
    for(i = n; i>=2; i--)
    {
	for(j = 2; j<=i; j++)
	{
	    if(R[j-1]>R[j])
	    {
		swap(&R[j-1],&R[j]);
		flag = 1;
	    }	
	}
	if(flag == 0)
	    return ;
    }
}
//二路归并,
void merge(int *R,int *ch, int lo,int mid, int hi)
{
    for(int i =lo; i <= hi; i++)
    {
	ch[i] = R[i];
    }
    int i =lo; int j = mid+1;
    printf("start %d, start %d \n",i,j);
    for(int k = lo; k <= hi; k++)
    {
	printf("ri is %d rj is %d",R[i],R[j]);
	if(i>mid) 
	    R[k] = ch[j++];
	else if(j>hi) 
	    R[k] = ch[i++];
	else if(less(ch[i],ch[j])) //比较的是ch
	    R[k] = ch[i++];
	else 
	    R[k] = ch[j++];
	printf("cur R[%d] is %d ch is %d\n",k,R[k],ch[k]);
    }
}


/*
 * 3.二路归并排序
 * 把整个数组分成子数组,对子数组排序后,将有序的子数组归并已将整个数组排序
 * */
void mergersort(int *R,int *temparray ,int lo, int hi)
{
    if(lo>=hi)return ;
    int mid = (lo+hi)/2;
    mergersort(R,temparray ,lo, mid);
    mergersort(R,temparray, mid+1, hi);
    merge(R, temparray,lo, mid, hi);


}


void testmergesort()
{
    int  unorder[] = {44,1,3,22};
    //5,41,3,9,44,21,65,
    int len = sizeof(unorder)/sizeof(int);
    int *temparray = new int(len);
    mergersort(unorder, temparray, 0, len-1);
    for(int i =0 ;i< len;i++)
	printf("%d ", unorder[i]);
    delete []temparray;
}




//基于插入排序的快速排序算法
/*4.shell排序是不稳定的,增量要求没有除1外的公因子.
 * */
void shellsort(int *R, int n)
{
    int h = 1;
    int j ,i;
    int temp;
    while(h < n/3) //以1, 4, 13, ,40,
	h = h*3 +1;
    while(h >=1)    //当前h为1
    {
	for(i = h; i<n;i++)//假设前面h项都是有序
	{
	    //temp = R[i];
	    //j = i - 1;
	    temp = R[i];
	    j = i -h;	//假设有序
	    while(j >= 0 && R[j]>temp)
	    {	R[j+h] = R[j];
		j = j-h;
	    }
	    R[j+h] = temp;
	}
	h = h/3;
    }
}






//5.选择排序
void selectsort(int *R, int n)
{
    if(R == NULL||n<=0)
	return;
    int min;
    for(int i = 0; i < n; i++)
    {
	min = i;
	for(int j=i; j<n; j++)
	{
	    if(less(R[j], R[min]))min = j;


	}
	swap(&R[i],&R[min]);
    }
}


//6.插入排序:每次较大元素都向右移动,当然也可以每次交换两个.
void InsertSort(int *R, int n)
{
    int i,j;
    int temp = 0;
    for( i =1; i<n;i++)
    {
	temp = R[i];	//当前需要排序的元素
	j = i-1;	//前面有序的元素个数
	while(j>=0 && R[j]>temp)    //当比前面的元素小的时候
	{
	    R[j+1] = R[j];	    //往后移
	    --j;			    
	}
	R[j+1] = temp;		    //放在当前位置
    }


}


/*
   class SortCompare
   {
   public:
   SortCompare(){}
   void Random
   }*/ 


//测试插入排序
void testinsert()
{
    int R[]  = {5,4,2,3,7,1};
    int n = sizeof(R)/sizeof(int);
    InsertSort(R, n);
    for(int i =0 ;i<n;i++)
    {
	printf("%d,",R[i]);
    }
}


void testSelectSort()
{
    int R[]  = {5,4,2,3,7,1};
    int n = sizeof(R)/sizeof(int);
    selectsort(R, n);
    for(int i =0 ;i<n;i++)
    {
	printf("%d,",R[i]);
    }
}




void testShell()
{
    int R[]  = {5,4,2,3,7,1};
    int n = sizeof(R)/sizeof(int);
    shellsort(R, n);
    for(int i =0 ;i<n;i++)
    {
	printf("%d,",R[i]);
    }
}














//优先队列:支持两种操作删除最大元素和插入元素.
/*
 *可以使用堆是有序的完全二叉树,完全二叉树是满二叉从下往上,从右往左删除元素后得到的.因为它的结构,所以可以直接放到里面
 * */
void shift(int R[], int low, int high)
{
    int temp = R[low];
    int i = low;
    int j = 2*i;//i的子节点
    while(j <= high)
    {
	if(j < high && R[j] < R[j+1])
	{
	    j++;
	}
	if(temp < R[j])
	{
	    R[i] = R[j];
	    i =j;
	    j = 2*i;
	}else
	    break;
    }
    R[i] = temp;
}


/*7.堆排序函数*/
void heapSort(int R[], int n)
{
    int temp =0;
    /*从底部开始建立大根堆*/
    for(int i = n/2; i>=1; i--)
    {
	shift(R, i , n);
    }
    //进行排序
    for(int j = n; j>=2; j--)
    {
	temp = R[1];
	R[1] = R[j];
	R[j] = temp;
	shift(R, 1, j-1);
    }
}


void testheapSort()
{
    int R[]  = {5,4,2,3,7,1};
    int n = sizeof(R)/sizeof(int);
    heapSort(R, 6);
    for(int i =0 ;i<n;i++)
    {
	printf("%d,",R[i]);
    }
}


//8.计数排序
//9.基数排序:桶排序每次以0-9排序,从个位到最高位
//10.折半插入排序:对一个有序的序列进行折半查找然后插入


//时间复杂度:快排,希尔排序,归并排序和堆排序,是nlog(n) (快些以nlog(n) 归队)
//而空间复杂度:快速排序是O(log(n)), 归并排序是O(n), 基数排序是O(r_d),其他都是O(1);// 当然直接插入容易变成O(n),而冒泡最好是O(n).以上两个是"容易插","起的好"
//其他细节:1.经过一趟排序可以达到最后位置:交换类(冒泡,快速), 选择类(堆排序, 简单选择排序).
//	   2.排序方法的元素次数和原始序列无关-----简单选择排序和折半插入排序
//	   3.排序方法与排序趟数和原始序列有关-----交换类排序(冒泡,快速)
//稳定性来说:快速排序, 希尔排序, 选择排序, 堆排序是不稳定的,其他稳定.(心情不稳定,快些选堆朋友聊天)
int main(int argc, char **argv)
{
    //testinsert();
    //testSelectSort();
    //testShell();
    //   testmergesort();
    //testquicksort();
    testheapSort();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值