快速排序算法

void qsort(int s[], int l, int r)
{
    int i, j, x;
    if (l < r)
    {
        i = l;
        j = r;
        x = s[i];
        while (i < j)
        {
            while(i < j && s[j] > x) j--; /* 从右向左找第一个小于x的数 */
            if(i < j) s[i++] = s[j];
            while(i < j && s[i] < x) i++; /* 从左向右找第一个大于x的数 */
            if(i < j) s[j--] = s[i];
        }
        s[i] = x;
        qsort(s, l, i-1); /* 递归调用 */
        qsort(s, i+1, r);
    }
}

算法步骤:
在序列中选择一个关键元素做为轴;
对序列进行重新排序,将比轴小的元素移到轴的前边,比轴大的元素移动到轴的后面。在进行划分之后,轴便在它最终的位置上;
递归地对两个子序列进行重新排序:含有较小元素的子序列和含有较大元素的子序列。
算法复杂度:
快速排序(QuickSort)的最坏时间复杂度应为0(n2),最好时间复杂度为O(nlgn),平均时间复杂度为O(nlgn)。快速排序(QuickSort)在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为O(lgn),故递归后需栈空间为O(lgn)。最坏情况下,递归树的高度为O(n),所需的栈空间为O(n)。

----------------------------------------------------------------

/********************************************************************************************
								平方阶(O(n2))排序
				一般称为简单排序,例如直接插入、直接选择和冒泡排序
	
 ********************************************************************************************/

/*插入排序*/
extern int InsertSort(int source[], int array_size)
{
	int index = 1; //插入排序
	int i, j;
	for (i = 1; i < array_size; i++)
	{
		index = source[i];
		j = i;
		while ((j > 0) && (source[j - 1] > index))
		{
			source[j] = source[j - 1];
			j--;
		}
		source[j] = index;
	}
	return 1;
}

/*冒泡排序*/
extern int BubbleSort(int source[], int array_size)
{
	int i, j;
	int temp;
	for (i = 0; i < array_size; i++)
	{
		for (j = 0; j < array_size - i - 1; j++)
			if (source[j] > source[j + 1])
			{
				temp = source[j];
				source[j] = source[j + 1];
				source[j + 1] = temp;
			}
	}
	return 1;
}

/*选择排序*/
extern int SelectSort(int source[], int array_size)
{
	int temp, min;
	int i, j;
	for (i = 0; i < array_size; i++)
	{
		min = i;//先假设最小下标为i
		for (j = i + 1; j < array_size; j++)
			if (source[j] < source[min])
				min = j;//把i之后的最小值附给min
			if (min != i)
			{
				temp = source[i];
				source[i] = source[min];
				source[min] = temp;
			}//判断min与i是否相等,若相等则说明原假设正确,反之:交换数值
	}
	return 1;
}


/*********************************************************************************************	
								线性对数阶(O(nlgn))排序
							如快速、堆和归并排序
	
 ********************************************************************************************/

/*快速排序接口*/
static int Partition(int source[], int left, int right)
{
	int x = source[left];
	while (left < right)
	{
		while (left < right && x <= source[right])
			right--;
		source[left] = source[right];
		while (left < right && x >= source[left])
			left++;
		source[right] = source[left];
	}
	source[left] = x;
	return left;
}

extern int QuickSort(int source[], int left, int right)
{
	int iPos;
	if (left >= right)
		return 1;
	iPos = Partition(source, left, right);
	QuickSort(source, left, iPos - 1); //   左边划分
	QuickSort(source, iPos + 1, right); //   右边划分
	return 1;
}


/*堆排序*/
static void HeapAdjust(int source[], int root, int node)/*root根节点, node节点总数*/
{
	//已知source[root..node]中除source[root]之外均满足堆的定义,本函数调整source[root]
	//使source[root..node]成为一个大顶堆
	int j, rc;
	rc = source[root];
	for (j = 2 * root; j <= node; j *= 2) //沿关键字叫大的结点向下筛选
	{
		if (j < node && source[j] < source[j + 1])
			++j; //j为关键字较大的记录的下标
		if (rc >= source[j])
			break; //rc应插入在位置root上
		source[root] = source[j];
		root = j;
	}
	source[root] = rc; //插入
}
extern int HeapSort(int source[], int array_size)
{
	int i, t;
	for (i = array_size / 2; i > 0; --i)
		//把a[1..L.length]建成大顶堆
		HeapAdjust(source, i, array_size);
	for (i = array_size; i > 1; --i)
	{
		t = source[1]; //将堆顶记录和当前未经排序子序列a[1..i]
		source[1] = source[i]; //中的最后一个记录相互交换
		source[i] = t;
		HeapAdjust(source, 1, i - 1); //将r[1..i-1]重新调整为大顶堆
	}
	return 1;
}

/**********************************************************************************************
									O(n1+£)阶排序
						£是介于0和1之间的常数,即0<£<1,如希尔排序

 ********************************************************************************************/

/*希儿排序*/
extern int ShellSort(int source[], int array_size)
{
	int increament;
	int e, i, j;
	
	/*初始步长设为n/2*/
	for (increament = array_size / 2; increament > 0; increament = increament / 2)
		for (j = increament; j < array_size; j++)
		{
			if (source[j] < source[j - increament])
			{
				e = source[j];
				for (i = j - increament; i >= 0 && source[i] > e; i = i - increament)
					source[i + increament] = source[i];
				source[i + increament] = e;
				
			}
		}
        return 1;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值