算法技术手册 – 排序 – 划分

划分是求Kth、快速排序等的基础。

目标:一个数组array,给定一个pivotIndex,要求将array[pivotIndex]的对象至于storeIndex位置,使得[left,storeIndex)的元素都小于array[pivotIndex],而使得大于[storeIndex,right]的元素都大于等于array[pivotIndex]。

算法步骤:
1、交换array[pivotIndex]和array[right],记前者为pivot
2、用store表示pivotIndex“潜在”可能的存储位置,初始为left。
3、i从left到right依次扫描,每当遇到比pivot小的元素,则放入store,并store++。
4、重复上述2-3直到i扫描完最右侧
5、交换array[store]和array[right](切忌忘记right里存得可是pivot)。

#include <stdio.h>

typedef int TYPE;

//Compare function
int cmp(TYPE a, TYPE b)
{
	return a - b;
}

//Partion, devide the arr into 2 parts
//arr[pivotIndex] store in arr[store]
//And:
//(1)All elems in [left,store) < arr[store]
//(2)All elems in [store,right] > arr[store]
int partition(TYPE* arr, int left, int right, int pivotIndex, int (*cmp)(TYPE, TYPE))
{
	TYPE pivot, tmp;
	int i, store;

	//First, swap the arr[pivotIndex] and arr[right]
	pivot = arr[pivotIndex];
	arr[pivotIndex] = arr[right];
	arr[right] = pivot;

	//Scan from left to right
	i = store = left;
	while(i<right)
	{
		if(cmp(arr[i],pivot)<=0)
		{
			tmp = arr[store];
			arr[store] = arr[i];
			arr[i] = tmp;
			store++;
		}
		i++;
	}

	//Final, swap the arr[right] and arr[store]
	arr[right] = arr[store];
	arr[store] = pivot;
	return store;
}

int main()
{
	int arr[16] = {15, 9, 8, 1, 4, 11, 7, 12, 13, 6, 5, 3, 16, 2, 10, 14};
	int len = sizeof(arr)/sizeof(TYPE);
	int storeIndex;

	//partition
	storeIndex = partition(arr, 0, len - 1, 9, cmp );
	printf("storeIndex\t%d\n", storeIndex);

	//print
	int i;
	for(i=0; i<len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

Leave a Reply

Your email address will not be published.