排序算法

算法复杂度和稳定性
在这里插入图片描述

插入排序

//一.直接插入排序
void  insertionSort(int *arr, int size)
{
	//声明有序组最后一个元素 end, 无序组第一个元素 key
	int end, key;
	for (int i = 1; i < size; i++)
	{
		key = arr[i];
		end = i - 1;
		while (end >= 0 && key < arr[end])
		{
			arr[end + 1] = arr[end];
			end--;
		}
		arr[end + 1] = key;
	}
}

//一.(2)折半插入排序
void binaryInsertionSort(int *arr, int size)
{
	int left, right, key, end;
	for (int i = 1; i < size; i++)
	{
		left = 0;	 //有序数组第一个元素
		right = i - 1;   //有序数组最后一个元素
		end = i - 1;	//有序数组最后一个元素
		key = arr[i];
		while (left <= right)
		{
			int mid = left + (right - left) / 2;
			if (key > arr[mid])
			{
				left = mid + 1;
			}
			else
			{
				right = mid - 1;
			}
		}

		while (end >= left)
		{
			arr[end+1] = arr[end];
			end--;
		}
		arr[end+1] = key;
	}
}

//二.希尔排序 
void shellSort(int *arr, int size)
{
	//初始化增量
	int gap = 1;
	while (gap <= size/3)
	{
		gap = 3 * gap + 1;
	}
	//声明有序组最后一个元素 end, 无序组第一个元素 key
	int end, key;

	for (; gap > 0; gap = (gap - 1) / 3)
	{
		for (int i = gap; i < size; i += gap)
		{
			key = arr[i];
			end = i - gap;
			while (end >= 0 && key < arr[end])
			{
				arr[end + gap] = arr[end];
				end = end - gap;
			}
			arr[end + gap] = key;
		}
	}
}

选择排序

//一.选择排序
void selectionSort(int *arr, int size)
{
	int minIndex;		//最小元素索引 
	for (int i = 0; i < size - 1; i++)//最后一个元素一定是最大(或最小),不需要排序
	{
		minIndex = i;
		for (int j = i+1; j < size; j++)
		{
			if (arr[j] < arr[minIndex])
			{
				minIndex = j;
			}
		}
		int tmp = arr[i];
		arr[i] = arr[minIndex];
		arr[minIndex] = tmp;
	}
}

//二.堆排序
void heapify(int *arr, int parent, int size)
{
#if 0
	//递归版本
	int lChild = 2 * parent + 1;
	int rChild = 2 * parent + 2;
	int currentMax = parent;
	if (lChild < size && arr[lChild] > arr[currentMax])
	{
		currentMax = lChild;
	}
	if (rChild < size && arr[rChild] > arr[currentMax])
	{
		currentMax = rChild;
	}
	if (currentMax != parent)
	{
		swap(arr[parent], arr[currentMax]);
		heapify(arr, currentMax, size);
	}

#else
	//非递归版本
	for (int k = 2 * parent + 1; k < size; k = 2 * k + 1)
	{
		//让 k 指向孩子节点中最大的节点
		if (k+1<size && arr[k] < arr[k+1])
		{
			k++;
		}
		if (arr[k] > arr[parent])
		{
			swap(arr[k], arr[parent]);
			parent = k;
		}
		//孩子节点均小于父节点, 跳出循环
		else
		{
			break;
		}
	}
#endif
}

void heapSort(int *arr, int size)
{
	//从最后一个非叶子节点开始构建堆
	for (int i = size / 2 - 1; i >= 0; i--)
	{
		heapify(arr, i, size);
	}

	//开始堆排序
	for (int j = size - 1; j >= 0; j--)
	{
		swap(arr[0], arr[j]);
		heapify(arr, 0, j);
	}
}

交换排序

//一.冒泡排序
void bubbleSort(int *arr, int size)
{
	for (int round = 0; round < size - 1; round++)
	{
		int flag = 0;
		for (int i = 0; i < (size - 1) - round; i++)
		{
			if (arr[i] > arr[i + 1])
			{
				flag = 1;
				int tmp = arr[i];
				arr[i] = arr[i + 1];
				arr[i + 1] = tmp;
			}
		}
		if (0 == flag)
		{
			break;
		}
	}
}

//二.快速排序
void quickSort(int *arr, int left, int right)
{
	//递归跳出条件
	if (left >= right)
	{
		return;
	}

	int lIndex = left;
	int rIndex = right;

	int baseValue = arr[left];		//设置基准值
	//用基准值划分两部分
	while (lIndex < rIndex)
	{
		while (arr[rIndex] >= baseValue && lIndex < rIndex)
		{
			rIndex--;
		}
		while (arr[lIndex] <= baseValue && lIndex < rIndex)
		{
			lIndex++;
		}
		if (lIndex < rIndex)
		{
			swap(arr[lIndex], arr[rIndex]);
		}
	}
	//将基准值放置到 两部分 中间
	arr[left] = arr[lIndex];
	arr[lIndex] = baseValue;

	quickSort(arr, left, lIndex - 1);
	quickSort(arr, lIndex+1, right);
}

归并排序

//归并排序
void merge(int *arr, int left, int mid, int right);

void mergeSort(int *arr, int left, int right)
{
	if (left >= right)   //只有一个元素时返回,跳出递归
	{
		return;
	}
	
	int mid = left + (right - left) / 2;
	mergeSort(arr, left, mid);
	mergeSort(arr, mid+1, right);
	merge(arr, left, mid, right);
}

void merge(int *arr, int left, int mid, int right)
{
	//将数组arr看作两部分, 左半边为leftArr, 右半边为rightArr
	int lLen = mid - left + 1;
	int rLen = right - (mid + 1) + 1;

	int *leftArr = new int[lLen];
	int *rightArr = new int[rLen];

	//向leftArr 和 rightArr 赋值
	for (int i = 0; i < lLen; i++)
	{
		leftArr[i] = arr[left + i];
	}
	for (int i = 0; i < rLen; i++)
	{
		rightArr[i] = arr[mid + 1 + i];
	}

	//将leftArr 和 rightArr 中的元素比较重新排列到 arr 中
	int lIndex = 0;
	int rIndex = 0;
	while (lLen != 0 && rLen != 0)
	{
		if (leftArr[lIndex] < rightArr[rIndex])
		{
			arr[left++] = leftArr[lIndex++];
			lLen--;
		}
		else
		{
			arr[left++] = rightArr[rIndex++];
			rLen--;
		}
	}
	//将剩下元素插入 arr
	if (lLen != 0)
	{
		while (lLen--)
		{
			arr[left++] = leftArr[lIndex++];
		}
	}
	else
	{
		while (rLen--)
		{
			arr[left++] = rightArr[rIndex++];
		}
	}
	delete[]leftArr;
	delete[]rightArr;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值