快速排序(殷人昆版)

快速排序的基本思想:任取待排序元素序列中的某个元素(例如取第一个元素)作为基准,按照该元素的排序码大小,将整个元素序列划分为左右两个子序列;左侧子序列中元素的排序码都小于基准元素的排序码,右侧子序列中的元素的排序码都大于基准元素的排序码。然后在左右序列中重复这种操作。


void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

int Partition(int V[], int low, int high)
{
	int privotpos = low;
	int privot = V[low];
	for(int i = low+1; i < high+1; ++i)
	{
		if(V[i] < privot)
		{
			privotpos++;
			if(privotpos != i)
			{
				Swap(V[privotpos],V[i]);
			}
		}
	}
	V[low] = V[privotpos];
	V[privotpos] = privot;

	return privotpos;
}

void QuickSort(int V[], const int left, const int right)
{
	if(left < right)
	{
		int privotpos = Partition(V, left, right);
		QuickSort(V,left, privotpos-1);
		QuickSort(V,privotpos+1, right);
	}
}


快速排序的改进算法:当序列长度M取值为5~25时,采用直接插入排序比全部使用快速排序快10%

#define M 5

void QuickSort_insertSort(int V[], const int left, const int right)
{
	if(right-left <= M)
	{
		InsertSort(V, left, right);
	}
	if(left < right)
	{
		int privotpos = Partition(V, left, right);
		QuickSort(V,left, privotpos-1);
		QuickSort(V,privotpos+1, right);
	}
}


void QuickSort(int V[], const int left, const int right)
{
	if(left < right)
	{
		int privotpos = Partition(V, left, right);
		QuickSort(V,left, privotpos-1);
		QuickSort(V,privotpos+1, right);
	}
}

void InsertSort(int V[], const int left, const int right)
{
	int i, j;
	for(i = left+1; i < right+1; ++i)
	{
		if(V[i] < V[i-1])
		{
			int tmp = V[i];
			j = i-1;
			do
			{
				V[j+1] = V[j];
				j--;
			}while(j >= left && tmp < V[j]);
			//向后移位
			V[j+1] = tmp;
		}
	}
}


快速—直接插入混合排序算法

void NewQuickSort(int V[], const int left, const int right)
{
	if(right-left <= M)
	{
		return;
	}
	if(left < right)
	{
		int privotpos = Partition(V, left, right);
		NewQuickSort(V,left, privotpos-1);
		NewQuickSort(V,privotpos+1, right);
	}
}

void HybirdSort(int V[], const int left, const int right)
{
	NewQuickSort(V, left, right);
	InsertSort(V, left, right);
}


三者中取中算法来实现快速排序基准位

int median3(int V[], int left, int right)
{
	int mid = (left+right)/2;
	int k = left;
	if(V[mid] < V[k])
	{
		k = mid;
	}
	if(V[right] < V[k])
	{
		k = right;//k指向三者中最小值
	}
	if(k != left)
	{
		Swap(V[k], V[left]);
	}
	if(mid != right && V[mid] < V[right])
	{
		Swap(V[mid], V[right]);
	}
	return V[right];
}
//一趟划分算法的实现
int Partition_3(int V[], int left, int right)
{
	int i = left, j = right-1;
	if(left < right)
	{
		int privot = median3(V, left, right);
		while(1)
		{
			while(i<j && V[i] < privot)
			//正向,小于privot的留在左侧,一旦大于等于privot停步
			{
				i++;
			}
			while(i<j && privot < V[j])
			//反向,大于privot的留在右侧,一旦小于等于privot停步
			{
				j--;
			}
			if(i < j)
			//比privot小的交换到左侧,比privot大的交换到右侧
			{
				Swap(V[i], V[j]);
				i++;
				j--;
			}
			else
			//i=j表明一趟检测完成,终止循环
			{
				break;
			}
		}
		if(V[i] > privot)
		//privot移到它排序后应该在的位置
		{
			V[right] = V[i];
			V[i] = privot;
		}
	}
	return i;
}

void NewQuickSort_3(int V[], const int left, const int right)
//三者中取中值放在最右端
{
	if(right-left <= M)
	{
		return;
	}
	if(left < right)
	{
		int privotpos = Partition_3(V, left, right);
		QuickSort(V,left, privotpos-1);
		QuickSort(V,privotpos+1, right);
	}
}

void HybirdSort_3(int V[], const int left, const int right)
{
	NewQuickSort(V, left, right);
	InsertSort(V, left, right);
}


三路划分的快速排序算法

void QuickSortNew(int V[], int left, int right)
{
	int i, j, k, p, q;
	int privot = V[right];
	if(right <= left)
	{
		return;
	}
	i = left-1;
	j = right;
	p = left-1;
	q = right;
	while(1)
	{
		while(V[++i] < privot)
		{
			if(i == j)
			{
				break;
			}
		}
		while(privot < V[--j])
		{
			if(j == i)
			{
				break;
			}
		}
		if(i >= j)
		{
			break;
		}
		Swap(V[i], V[j]);
		if(V[i] == privot)
		{
			p++;
			Swap(V[p], V[i]);
		}
		if(privot == V[j])
		{
			q--;
			Swap(V[q], V[j]);
		}
	}
	if(V[i] > V[right])
	{
		Swap(V[i], V[right]);
		k = right-1;
	}
	else
	{
		k = right;
	}
	j--;
	i++;
	while(k >= q)
	{
		Swap(V[k], V[i]);
		k--;
		i++;
	}
	for(k = left; k < p+1; k++, j--)
	{
		Swap(V[k], V[j]);
	}
	QuickSortNew(V, left, j);
	QuickSortNew(V, i, right);
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值