排序算法

排序算法总结

注:本文中部分图解和思路参考博主dreamcatcher-cx:http://www.cnblogs.com/chengxiao/
sort

选择排序

void selectSort(int *a, int len)
{
	if (nullptr == a)
		return;
	int min;
	int index;
	for (int i = 0; i < len - 1; i++){
		//当前最小值与最小值对应的索引号
		min = a[i];
		index = i;
		for (int j = i + 1; j < len; j++)
			if (a[j] < min)
			{
				min = a[j];
				index = j;
			}
		//选出最小值,与a[i]交换
		int temp = a[i];
		a[i] = a[index];
		a[index] = temp;
	}
}

冒泡排序

void bubbleSort(int *a, int len)
{
	if (nullptr == a)
		return;
	for (int i = 0; i < len; i++){
		for (int j = 0; j < len - 1; j++){
			//冒泡过程
			//相邻两个数进行比较,较大的数向后移位,如此循len次
			if (a[j] > a[j + 1]){
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}

插入排序

void insertSort(int *a, int len)
{
	if (nullptr == a)
		return;
	for (int i = 1; i < len; i++){
		int j = i;
		while (j > 0 && a[j] < a[j-1])
		{
			int temp = a[j];
			a[j] = a[j - 1];
			a[j - 1] = temp;
			j--;
		}
	}
}

快速排序

//核心思想:选择一个key,通过遍历数组使得key左侧的数小于key,右侧的值大于key.然后分别对key的左侧和右侧进行快排
/*
1、选择最右侧的值为key,left=0;right=N-1;
2、从left向右走,直到找到大于key的数,使a[right]=a[left].
3、从right向前遍历,直到找到小于key的数,使a[left]=a[right].
4、重复2、3过程直到left与right相遇。
*/
int partSort(int *a, int left, int right)
{
	if (nullptr == a)
		return 0;
	int key = a[right];
	while (left < right)
	{
		while (left < right && a[left] <= key)
			left++;
		a[right] = a[left];
		while (left < right && a[right] >= key)
			right--;
		a[left] = a[right];
	}
	a[right] = key;
	return right;
}
void quickSort(int *a, int left, int right)
{
	if (nullptr == a)
		return;
	if (left >= right)
		return;
	int index = partSort(a, left, right);
	quickSort(a, left, index - 1);
	quickSort(a, index + 1, right);
}

归并排序

void mergeArray(int *arr, int l, int r, int *temp)
{
	//std::cout << "left:" << l << " " << "right:" << r << std::endl;
	if (l >= r)
		return;
	int mid = (l + r) / 2;
	mergeArray(arr, l, mid, temp);
	mergeArray(arr, mid + 1, r, temp);
	int *aux = new int[r - l + 1]; //这里弄一个要处理的数组副本 长度是 R-L+1 
	for (int i = l; i <= r; i++)    //副本数组从 L 开始,所以与原数组存在一个 L 的偏移量
		aux[i - l] = arr[i];
	int i = l, j = mid + 1;        //i记录左边元素的下标位置 j记录右边元素的下标位置
	for (int k = l; k <= r; k++){ //k记录 arr 的下标位置
		if (i >mid){
			arr[k] = aux[j - l];
			j++;
		}
		else if (j >r){
			arr[k] = aux[i - l];
			i++;
		}
		else if (aux[i - l] < aux[j - l]){
			arr[k] = aux[i - l];
			i++;
		}
		else{
			arr[k] = aux[j - l];
			j++;
		}
	}
}

void mergeSort(int *a, int len)
{
	if (nullptr == a)
		return;
	int *p = new int[len];
	if (nullptr == p)
		return;
	mergeArray(a, 0, len - 1, p);
	delete[] p;
}

堆排序

  • 将无序数组构建成大顶堆
  • 将堆顶元素与末尾元素交换
  • 重新调整堆,使其仍为大顶堆,反复执行交换和调整的步骤
void adjustHeap(int* arr, int i, int len){
	if (NULL == arr)
		return;
	int temp = arr[i];
	for (int k = 2 * i + 1; k < len; k = 2 * k + 1){
		if (k + 1 < len && arr[k] < arr[k + 1]){//左子节点小于右子节点
			k++;
		}
		if (arr[k] > temp){
			swap(arr[i], arr[k]);
			i = k;
		}
		else{
			break;
		}
	}
}

void heapSort(int* arr, int len){
	if (NULL == arr)
		return;
	//1.构建大顶堆
	for (int i = len / 2 - 1; i >= 0; i--){//从最后一个非叶子节点开始
		//调整大顶堆
		adjustHeap(arr, i, len);
	}
	//2.调整堆结构,交换堆顶元素与末尾元素
	for (int j = len - 1; j > 0; j--){
		swap(arr[0], arr[j]);
		//重新调整堆
		adjustHeap(arr, 0, j);
	}
}
posted @ 2018-09-17 19:42  Apotato  阅读(237)  评论(0)    收藏  举报