6种排序算法——C++

排序算法6种:

  1. 简单选择排序
  2. 冒泡排序
  3. 插入排序
  4. 归并排序
  5. 快速排序
  6. 堆排序

简单选择排序:

template <typename T>
void select_sort(T* arr, int len)
{
	int count1 = 0, count2 = 0;
	for (int i=0; i<len-1; i++)
	{
		for (int j=i+1; j<len; j++)
		{
			count1++;
			if (arr[j] < arr[i])
			{
				std::swap(arr[j], arr[i]);
				count2++;
			}
		}
	}

	printf("count1:%u count2:%u\n", count1, count2);
	//count1:45 count2:15
}

简单选择排序2:

template <typename T>
void select_sort2(T* arr, int len)
{
	int count1 = 0, count2 = 0;
	int minIndex;
	for (int i=0; i<len-1; i++)
	{
		minIndex = i;
		for (int j=i+1; j<len; j++)
		{
			count1++;
			if (arr[j] < arr[minIndex])
			{
				minIndex = j;
			}
		}
		if (i != minIndex)
		{
			std::swap(arr[i], arr[minIndex]);
			count2++;
		}
	}

	printf("count1:%u count2:%u\n", count1, count2);
	//count1:45 count2:7
}

冒泡排序:

template <typename T>
void bubble_sort(T* arr, int len)
{
	int count1=0, count2=0;
	for (int i=len-1; i>0; i--)
	{
		bool bHaveSwap = false;

		for (int j=1; j<=i; j++)
		{
			count1++;
			if (arr[j-1] > arr[j])
			{
				std::swap(arr[j], arr[j-1]);
				count2++;
				bHaveSwap = true;
			}
		}
		if (!bHaveSwap)
			break;
	}
	printf("count1:%u count2:%u\n", count1, count2);
	//count1:35 count2:15
}

插入排序:

template <typename T>
void insert_sort(T* arr, int len)
{
	int count1=0, count2=0;
	for (int i=1; i<len; i++)
	{
		for (int j=i; j>0; j--)
		{
			count1++;
			if (arr[j] < arr[j-1])
			{
				std::swap(arr[j], arr[j-1]);
				count2++;
			}
			else
				break;
		}
	}
	printf("count1:%u count2:%u\n", count1, count2);
	//count1:23 count2:15
}

归并排序:

template <typename T>
void merge(T* arr, int l, int mid, int r, T* temp)
{
	int tempIndex = 0;
	int i=l, j=mid+1;
	while (1)
	{
		gcount1++;

		if (i <= mid)
		{
			if (j<=r)
			{
				if (arr[i] <= arr[j])
					temp[tempIndex++] = arr[i++];
				else
					temp[tempIndex++] = arr[j++];
			}
			else
				temp[tempIndex++] = arr[i++];
		}
		else if (j <= r)
		{
			temp[tempIndex++] = arr[j++];
		}
		else
			break;

		gcount2++;
	}

	tempIndex = 0;
	for (int i=l; i<=r; i++)
	{
		arr[i] = temp[tempIndex++];
	}
}
template <typename T>
void merge_sort_recursion(T* arr, int l, int r, T* temp)
{
	if (r <= l)
		return;
	int mid = (l+r)/2;

	merge_sort_recursion(arr, l, mid, temp);
	merge_sort_recursion(arr, mid+1, r, temp);
	merge(arr, l, (l+r)/2, r, temp);
}
template <typename T>
void merge_sort(T* arr, int len)
{
	T* temp = new T[len];

	merge_sort_recursion(arr, 0, len-1, temp);

	delete[] temp;

	printf("gcount1=%u,gcount2=%u\n", gcount1, gcount2);
	//gcount1=43,gcount2=34
}

快速排序:

template <typename T>
int quick_fill(T* arr, int l, int r)
{
	// WARNING:所有=tmid的数据移动到左边最后
	T tmid = arr[(l+r)/2];
	cout << "tmid:" << tmid;
	puts("");
	int i=l, j=r;
	bool bNeedSwapTmidBefore = false;
	while (1)
	{
		gcount1++;
		for (; i<j && arr[i]<=tmid; i++)
		{
			if (arr[i] == tmid)
				bNeedSwapTmidBefore = true;
		}
		while (j>i && arr[j]>tmid)
			j--;
		if (i >= j)
			break;

		std::swap(arr[i], arr[j]);
		gcount2++;
	}
	if (arr[i] > tmid)
		i--;

	if (bNeedSwapTmidBefore)
	{
		int nl=l, nr=i;
		for (; nl<nr; )
		{
			gcount1++;
			if (arr[nl] != tmid)
			{
				nl++;
				continue;
			}
			if (arr[nr] == tmid)
			{
				nr--;
				continue;
			}
			std::swap(arr[nl], arr[nr]);
			gcount2++;
		}
	}
	return i;
}
template <typename T>
void quick_sort_recursion(T* arr, int l, int r)
{
	if (r <= l)
		return;
	int mid = quick_fill(arr, l, r);
//	int mid = quick_fill2(arr, l, r);
	for (int i=l; i<=mid; i++)
		cout << arr[i] << " ";
	cout << " | ";
	for (int i=mid+1; i<=r; i++)
		cout << arr[i] << " ";
	puts("");

	int leftr = mid-1;
	if (leftr > l && arr[leftr-1] == arr[mid-1])
	{
		leftr--;
		while (leftr > l && arr[leftr] == arr[mid-1])
			leftr--;
	}
	quick_sort_recursion(arr, l, leftr);
	quick_sort_recursion(arr, mid+1, r);
}
template <typename T>
void quick_sort(T* arr, int len)
{
	quick_sort_recursion(arr, 0, len-1);

	printf("gcount1=%u,gcount2=%u\n", gcount1, gcount2);
	//gcount1=44,gcount2=13
}

快速排序——填坑法:


template <typename T>
int quick_fill2(T s[], int l, int r) //返回调整后基准数的位置
{
    int i = l, j = r;
    T x = s[l]; //s[l]即s[i]就是第一个坑
    while (i < j)
    {
        // 从右向左找小于x的数来填s[i]
        while(i < j && s[j] >= x)
            j--;
        if(i < j)
        {
            s[i] = s[j]; //将s[j]填到s[i]中,s[j]就形成了一个新的坑
            i++;
        }

        // 从左向右找大于或等于x的数来填s[j]
        while(i < j && s[i] < x)
            i++;
        if(i < j)
        {
            s[j] = s[i]; //将s[i]填到s[j]中,s[i]就形成了一个新的坑
            j--;
        }
    }
    //退出时,i等于j。将x填到这个坑中。
    s[i] = x;

    return i;
}

 

其他代码:

#include <stdio.h>
#include <iostream>

using namespace std;

int gcount1=0,gcount2=0;

template <typename T>
void printarr(const T* arr, int len)
{
	for (int i=0; i<len; i++)
	{
		cout << arr[i] << " ";
	}
	printf("\n");
}

int main()
{
	int arr[] = {1,5,4,4,0,7,9,9,0,9,2,3,2,2,4,6,8,4,7};
	int len = sizeof(arr)/sizeof(arr[0]);
	printarr(arr, len);

	quick_sort(arr, len);
	printarr(arr, len);
}

代码参照:https://blog.51cto.com/whish/2079951

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值