排序算法总结(C++)

这里对排序算法做一个总结,还未完结,后序还将加入希尔排序等排序方法。

文章目录

      • 1. 排序算法
      • 2. 选择排序
      • 3. 插入排序
      • 4. 快速排序
      • 5. 合并排序
      • 6 堆排序

1. 排序算法

将每一个数依次与其后面的数做对比,如果前后两个数逆序,则交换,然后进行下一步对比,经过每一个交换,最大的数都会被换到数组尾部,然后使数组总长度减一,这里为了节省时间,可以设置一个标志位,在每一次循环的开始都设为 true,如果在遍历过程中发生交换,则同时置为 false,经过一次完整循环以后没有发生过一次交换,则标志位一直为 true 视为数组已经有序,直接结束。

void bubbleSort(vector &A)
{
	int n = A.size();
	bool sorted = false;  // flag to save time
	while (!sorted)
	{
		sorted = true;
		for (int i = 0; i < n-1; i++)
		{
			if (A[i]>A[i+1])
			{
				swap(A[i], A[i + 1]);
				sorted=false;
			}
		}
		n--;
	}
}

2. 选择排序

每一次迭代都找到从出发位置开始后面数组中的最小数字,然后让其与当前位置的值互换,需要借助两个中间遍历来记录最小值的位置与数值。

void selectionSort(vector &A)
{
	int k=0; int temp=0;
	for (int i = 0; i < A.size(); i++)
	{
		k = i;
		temp = A[i];
		for (int j = i; j < A.size(); j++)
		{
			if (temp > A[j])
			{
				k = j;
				temp = A[j];
			}
		}
		A[k] = A[i];
		A[i] = temp;
	}
}

3. 插入排序

当数组中只有一个数时数组肯定有序,这里假设数组前半部分是有序的,则只要从数组的后半部分每次取一个数,查找到这个待插入的数在前半部分的位置,让后将其加入,直到后半部分数组长度为0,整个数组即有序。

void insertSort(vector& A) {

	for (int i = 1; i < A.size(); i++)
	{
		for (int j = 0; j < i; j++) {
			if (A[j] > A[i])
			{
				swap(A[j],A[i])
			}
		}
	}
}

4. 快速排序

这里首先找到一个中心旋转点,一般是数组 A 的第一个A[0]/最后一个元素A[A.size()-1],这里以 A[0] 为旋转点为例,设置两个哨兵i,j 分辨去找大于 A[0] 和 大于 A[0] 的点,哨兵 i 从左向右遍历,当满足 i <= j,并且A[i] > A[0]时,i停下,同理 j 从右向左找小于A[0] 的值,当满足 i<=j,且 A[j] < A[0]时,j 停下,交换 A[i] 和 A[j],然后继续向前寻找,直到 i> j 时,以 A[0] 为中间点的,然后对 A[0] 的左、右分辨重复上面的过程。

int partition(vector& a, int left, int right) {
	int i = left;
	int j = right;
	int temp = a[right];
	while (i =temp)
		{
			j--;
		}
		if (i < j)
			swap(a[i], a[j]);
	}
	swap(a[j], a[right]);
	return j;
}

void quickSort(vector a, int left, int right) {
	if (left >= right)
	{
		return;
	}
	int j = partition(a, left, right);
	quickSort(a, left, j - 1);
	quickSort(a, j + 1, right);
}

5. 合并排序

void merge(vector&s1, vector& s2, vector & result)
{
	int i = 0, j = 0;
	for (; i < s1.size()&&j= s2[j])
		{
			result.push_back(s2[j]);
			j++;
		}
		else {
			result.push_back(s1[i]);
			i++;
		}
	}
	if (i < s1.size())
	{
		for(int k=i;k&nums)
{
	if (nums.size() <= 1)
		return;
	int i = 0, j = nums.size();
	int mid = (i + j) / 2;
	vector s1;
	vector s2;
	for (int k = 0; k < mid; k++)
		s1.push_back(nums[k]);
	for (int k = mid; k < j; k++)
		s2.push_back(nums[k]);
	mergeSort(s1);
	mergeSort(s2);
	nums.clear();
	merge(s1, s2, nums);
}

数组实现

void merge(vector& A, int lo, int mi, int hi) {
	int ll = mi - lo + 1; int lr = hi - mi;
	vector L(ll+1, 0);
	vector R(lr+1, 0);

	for (int i = 0; i < ll; i++) {
		L[i] = A[lo + i];
	}
	for (int j = 0; j < lr; j++) {
		R[j] = A[mi + j+ 1];
	}
	L[ll] = INT_MAX;
	R[lr] = INT_MAX;
	for (int i = 0, j = 0, k = lo; k <= hi; k++)
	{
		if (L[i] <= R[j])
			A[k] = L[i++];
		else
			A[k] = R[j++];
	}
}

void mergeSort(vector& A, int lo, int hi)
{
	// 若两数组默认有序,则直接 hi-lo<2 ,就可以 return,这里还需要换一下
	if (hi - lo == 1)
	{
		if (A[lo] > A[hi]) {
			swap(A[lo], A[hi]);
			return;
		}
	}
	if (hi - lo<1)
	{
		return;
	}
	int mi = (hi + lo) >> 1;
	mergeSort(A, lo, mi);
	mergeSort(A, mi + 1, hi);
	merge(A, lo, mi, hi);
}

6 堆排序

void adjust(vector &arr, int len, int index)
{
	int left = 2 * index + 1; // index的左子节点
	int right = 2 * index + 2;// index的右子节点

	int maxIdx = index;
	if (left arr[maxIdx])     maxIdx = left;
	if (right arr[maxIdx])     maxIdx = right;

	if (maxIdx != index)
	{
		swap(arr[maxIdx], arr[index]);
		adjust(arr, len, maxIdx);
	}

}

// 堆排序
void heapSort(vector &arr, int size)
{
	// 构建大根堆(从最后一个非叶子节点向上)
	for (int i = size / 2 - 1; i >= 0; i--)
	{
		adjust(arr, size, i);
	}

	// 调整大根堆
	for (int i = size - 1; i >= 1; i--)
	{
		swap(arr[0], arr[i]);           // 将当前最大的放置到数组末尾
		adjust(arr, i, 0);              // 将未完成排序的部分继续进行堆排序
	}
}

你可能感兴趣的:(C++,数据结构)