二分查找,快速排序,归并排序,堆排序

1. 二分查找的递归版本。

int  BinarySearchRecur(vector<int> &v1, int searchNum, int sIdx, int eIdx)
{
	int ret = -1;
	int midIdx = sIdx + ( (eIdx - sIdx) >> 1 );

	if (sIdx <= eIdx)  // 一定要加上,不然如果找不到就会陷入死循环。
	{
		if (v1[midIdx] < searchNum)
		{
			ret = BinarySearchRecur(v1, searchNum, midIdx+1, eIdx);
		}
		else if(v1[midIdx] > searchNum)
		{
			ret = BinarySearchRecur(v1, searchNum, sIdx, midIdx -1 );
		}
		else
			ret = midIdx;
	}

	return ret;
}

2. 二分查找非递归。

int BinarySearch(vector<int> &v1, int searchNum)
{
	int sIdx = 0, eIdx = v1.size()-1;

	while (sIdx <= eIdx)
	{
		int midIdx = sIdx + ( (eIdx - sIdx) >> 1 );

		if (v1[midIdx] > searchNum)
			eIdx = midIdx - 1;
		else if (v1[midIdx] < searchNum)
			sIdx = midIdx + 1;
		else
			return midIdx;
	}

	return -1;
}

3. 快速排序。

template<typename T>
void Swap(T *a, T *b)
{
	T tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}
template<typename T, typename U>
U Partition(T * arr, U sIdx, U eIdx)
{
	if (arr==nullptr || sIdx<0 )
	{
		cout << "Error occurred in Partition.";
		return -1;
	}

	T  pivot = arr[sIdx], tmp;
	U ii = sIdx, jj = sIdx+1;

	for (; jj<=eIdx; ++jj)
	{
		if (arr[jj] < pivot)
		{
			++ii;
			Swap(&arr[ii], &arr[jj]);
		}
	}

	Swap(&arr[sIdx], &arr[ii]);

	return ii;
}
template int Partition(float * arr, int sIdx, int eIdx);
template<typename T, typename U>
void QuickSort(T * arr, U len, U sIdx, U eIdx)
{
	if (arr==nullptr || len<=0 || sIdx<0 || eIdx>=len)
	{
		printf ("error");
		return ;
	}

	U midIdx = (sIdx + eIdx) / 2;
	if(sIdx < midIdx)
	{
		midIdx = Partition(arr, sIdx, eIdx);   
		QuickSort(arr, len, sIdx, midIdx);
		QuickSort(arr, len, midIdx+1, eIdx);  //arr所有的元素都已经被放到了指定的位置,所以不需要有递归的终止条件。
	}
}
template void QuickSort(float * arr, int len, int sIdx, int eIdx);

4. 归并排序。

template<typename T, typename X>
void Merge(T* arr, X sIdx, X midIdx, X eIdx)
{
	T *tmp = new T[eIdx-sIdx+1];
	
	X ii = sIdx, jj = midIdx + 1, kk = 0;
	while (ii != midIdx+1 && jj != eIdx+1)
	{
		if(arr[ii] > arr[jj])
		{
			tmp[kk++] = arr[jj++];
		}
		else
		{
			tmp[kk++] = arr[ii++];
		}
	}

	while (ii != midIdx + 1)
		tmp[kk++] = arr[ii++];
	while (jj != eIdx + 1)
		tmp[kk++] = arr[jj++];

	for (X ii=0; ii<kk; ++ii)
		arr[ii+sIdx] = tmp[ii];

	delete [] tmp;

}
void Merge(float* arr, int sIdx, int midIdx, int eIdx);
template<typename T, typename X>
void MergeSort(T* arr, X len, X sIdx, X eIdx)
{
	if (arr == nullptr ||len<=0 || sIdx<0 || eIdx>=len)
	{
		cout << "Invalid input.";
		return ;
	}

	X midIdx = (sIdx + eIdx) / 2;
	if (sIdx < eIdx)
	{
		MergeSort(arr, len, sIdx, midIdx);
		MergeSort(arr, len, midIdx+1, eIdx);
		Merge(arr, sIdx, midIdx, eIdx);
	}
}
void MergeSort(float* arr, int len, int sIdx, int eIdx);

5、堆排序。(180412)

#define leftChild(i) (2 * (i))

void percDown(vector<int> &array, int length, int i)
{
    int tmp;
    int greaterChild;

    for(tmp = array[i]; leftChild(i) < length; i = greaterChild)
    {
        greaterChild = leftChild(i);
        //找出较大的那个儿子
        if(greaterChild + 1 < length && array[greaterChild] < array[greaterChild + 1])
            ++greaterChild;
        if(tmp < array[greaterChild])
        {
            array[i] = array[greaterChild];
        }
        else
        {
            break;
        }
    }
    array[i] = tmp;
}
//堆排序
void heapSort(vector<int> &array, int length)
{
    //建立堆
    for(int i = (length - 1)/ 2; i >= 1; --i)
        percDown(array, length, i);

    // 执行N-1次删除操作
    for(int i = length - 1; i > 1; --i)
    {
        swap(array[i], array[1]);      //将存放在堆顶的最大元素交换到堆的末尾
        percDown(array, i, 1);
    }
}

附上:常见排序算法动图

猜你喜欢

转载自blog.csdn.net/weixin_38984102/article/details/79691004