排序(全)

非比较排序:计数排序,基数排序


直接插入排序

“test.cpp”

#include<iostream>
using namespace std;
#include<assert.h>

void InsertSort(int* arr,size_t size)
{
	assert(arr);

	for(int i = 0;i < size-1;i++)
	{
		int j = i;
		int tmp = arr[i+1];

		while(j >= 0 && arr[j] > tmp)
		{
			arr[j+1] = arr[j];
			j--;
		}

		arr[j+1] = tmp;
	}
}

void test()
{
	int arr[] = {3,7,1,0,2,6,8,5,9,4};
	size_t size = sizeof(arr)/sizeof(arr[0]);
	InsertSort(arr,size);

	for(size_t i = 0;i < size;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}


希尔排序

“test.cpp”

#include<iostream>
using namespace std;
#include<assert.h>

void ShellSort(int* arr,size_t size)
{
	assert(arr);
	int gap = size;

	while(gap > 1)
	{
		gap = gap / 3 + 1;
		for(int i = 0;i < size - gap;i++)
		{
			int j = i;
			int tmp = arr[i+gap];

			while(j >= 0 && arr[j] > tmp)
			{
				arr[j + gap] = arr[j];
				j -= gap;
			}

			arr[j + gap] = tmp;
		}
	}
}

void test()
{
	int arr[] = {3,4,1,2,8,9,5,6,0,7};
	size_t size = sizeof(arr)/sizeof(arr[0]);
	ShellSort(arr,size);

	for(size_t i = 0;i < size;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}




选择排序

“test.cpp”

#include<iostream>
using namespace std;

void SelectSort(int* arr,int size)
{
	//最小的放在左边,最大的放在右边
	int left = 0;
	int right = size - 1;

	while(left < right)
	{
		int min = left;
		int max = left;

		for(int i = left;i <= right;i++)
		{
			if(arr[i] < arr[min])
				min = i;
			if(arr[i] > arr[max])
				max = i;
		}

		swap(arr[left],arr[min]);

		//处理最大的数字在最左边,最小的数字在最右边的情况(图解)
		if(max == left)
		{
			max = min;
		}

		swap(arr[right],arr[max]);
		left++;
		right--;
	}
}
void test()
{
	//int arr[] = {2,5,4,9,3,6,8,7,1,0};
	int arr[] = {9,5,4,2,3,6,8,7,1,0};
	int size = sizeof(arr)/sizeof(arr[0]);

	SelectSort(arr,size);

	for(int i = 0;i < size;++i)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}


堆排序

“test.cpp”

#include<iostream>
using namespace std;

//向下调整
void AdjustDown(int* arr,size_t size,int parent)
{
	int child = 2 * parent + 1;

	while(child < size)
	{
		if(child + 1 < size && arr[child + 1] > arr[child])
			++child;

		if(arr[child] > arr[parent])
			swap(arr[child],arr[parent]);
		else
			break;

		parent = child;
		child = 2 * parent + 1;
	}
}

void HeapSort(int* arr,size_t size)
{
	//建堆,从第一个非叶子节点开始向下调整
	for(int i = (size-2) / 2;i >= 0; --i)
	{
		AdjustDown(arr,size,i);
	}

	//升序,每次取堆顶的数据和最后一个数据进行交换
	//再对堆顶进行向下调整
	int end = size - 1;
	while(end > 0)
	{
		swap(arr[0],arr[end]);
		
		//size的范围逐渐缩小,用end来控制size的大小
		AdjustDown(arr,end,0);

		--end;
	}
}

void test()
{
	int arr[] = {2,5,4,9,3,6,8,7,1,0};
	int size = sizeof(arr)/sizeof(arr[0]);

	HeapSort(arr,size);

	for(int i = 0;i < size;++i)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}

冒泡排序

“test.cpp”

#include<iostream>
using namespace std;

void BubbleSort(int* arr,size_t size)
{
	for(int i = 0;i < size - 1;i++)//趟数
	{
		bool flag = false;
		for(int j = 0;j < size - 1 - i;j++)//比较个数
		{
			if(arr[j + 1] < arr[j])
			{
				swap(arr[j+1],arr[j]);
				flag = true;
			}
		}

		if(flag == false)
			break;
	}
}
void test()
{
	int arr[] = {2,6,4,9,0,1,7,3,8,5};
	int size = sizeof(arr)/sizeof(arr[0]);

	BubbleSort(arr,size);

	for(int i = 0;i < size;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}

快速排序

“test.cpp”

#include<iostream>
using namespace std;
#include<stack>

//前后指针法
int ParkSort3(int* arr,int begin,int end)
{
	int key = arr[end];
	int cur = begin;
	int prev = begin - 1;

	while(cur < end)
	{
		if((arr[cur] < key) && (++prev != 

cur))
			swap(arr[cur],arr[prev]);

		++cur;
	}

	swap(arr[++prev],arr[end]);//记住每次交换前

prev都要++
	return prev;
}

//三数取中法——解决时间复杂度最坏的情况(O(N^2))
int GetMidNum(int* arr,int begin,int end)
{
	int mid = begin + (end - begin)/2;

	if(arr[begin] > arr[mid])
	{
		if(arr[end] < arr[mid])//arr[mid]是中

间值
			return mid;
		else//arr[end] > arr[mid]
		{
			//此时,arr[mid]是最小的值,中

间值在arr[begin],arr[end]中选择
			if(arr[end] > arr[begin])
				return begin;
			else//arr[end] < arr[begin]
				return end;
		}
	}
	else//arr[begin] < arr[mid]
	{
		if(arr[end] > arr[mid])
			return mid;
		else//arr[end] < arr[mid]
		{
			if(arr[end] > arr[begin])
				return end;
			else //arr[end] < arr[begin]
				return begin;
		}
	}
}

//挖坑法
int ParkSort2(int* arr,int begin,int end)
{

	int tmp = GetMidNum(arr,begin,end);
	swap(arr[end],arr[tmp]);
	int key = arr[end];
	
	int left = begin;
	int right = end;

	while(left < right)
	{
		while(left < right && arr[left] <= 

key)
			++left;

		arr[right] = arr[left];

		while(left < right && arr[right] >= 

key)
			--right;

		arr[left] = arr[right];
	}
	arr[left] = key;
	return left;

}

//单趟排序
int ParkSort1(int* arr,int begin,int end)
{
	int left = begin;
	int right = end - 1;

	int tmp = GetMidNum(arr,begin,end);
	swap(arr[end],arr[tmp]);
	int key = arr[end];

	while(left < right)
	{
		//left所指的值要比arr[end](key值)大
		while(left < right && arr[left] <= 

key)
			++left;

		//right所指的值要比arr[end](key值)小
		while(left < right && arr[right] >= 

key)
			--right;
		
		if(left < right)
			swap(arr[left],arr[right]);
	}

	//出了循环以后,此时left和right指向同一个位置,

此时
	//将arr[left](arr[right])的值和arr[end](key值)

交换
	if(arr[left] > key)
	{
		swap(arr[left],arr[end]);
		return left;
	}
	else 
		return end;
}
void QuickSort(int* arr,int begin,int end)
{
	if(begin >= end)
		return;

	//int div = ParkSort1(arr,begin,end);
	//int div = ParkSort2(arr,begin,end);
	int div = ParkSort3(arr,begin,end);
	
	QuickSort(arr,begin,div-1);
	QuickSort(arr,div+1,end);
}

//非递归实现快速排序
void QuickSortNonR(int* arr,int begin,int end)
{
	stack<int> s;
	s.push(end);
	s.push(begin);

	while(!s.empty())
	{
		int left = s.top();
		s.pop();

		int right = s.top();
		s.pop();

		int div = ParkSort1(arr,left,right);

		if(left < div - 1)
		{
			s.push(div-1);
			s.push(left);
		}

		if(div + 1 < right)
		{
			s.push(right);
			s.push(div+1);
		}
	}
}

void test()
{
	int arr[] = {5,2,9,0,1,8,3,6,4,7};
	//int arr[] = {5,2,9};
	int size = sizeof(arr)/sizeof(arr[0]);

	//QuickSort(arr,0,size-1);
	QuickSortNonR(arr,0,size-1);

	for(int i = 0;i < size;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}



归并排序

“test.cpp”

#include<iostream>
using namespace std;
void Sort(int* arr,int* tmp,int begin,int mid,int end)
{
	int index = 0;
	int left = begin;
	int right = mid + 1;

	while(left <= mid && right <= end)
	{
		if(arr[left] < arr[right])
			tmp[index++] = arr[left++];
		else
			tmp[index++] = arr[right++];
	}

	while(left <= mid)
		tmp[index++] = arr[left++];
	while(right <= end)
		tmp[index++] = arr[right++];
	
	index = 0;
	for(int i = begin;i <= end;++i)
	{
		arr[i] = tmp[index++];
	}
}

void _MergeSort(int* arr,int* tmp,int begin,int end)
{
	if(begin >= end)
		return;
	
	int mid = begin + (end - begin)/2;

	_MergeSort(arr,tmp,begin,mid);
	_MergeSort(arr,tmp,mid+1,end);

	Sort(arr,tmp,begin,mid,end);
}

void MergeSort(int* arr,size_t size)
{
	int* tmp = new int[size];

	_MergeSort(arr,tmp,0,size-1);

	delete[] tmp;
}

void test()
{
	int arr[] = {3,8,2,0,7,6,1,5,9,4};
	//int arr[] = {3,8,2};
	int size = sizeof(arr)/sizeof(arr[0]);

	
	MergeSort(arr,size);

	for(size_t i = 0;i < size;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}

非比较排序

计数排序

“test.cpp”

#include<iostream>
using namespace std;

void CountSort(int* arr,int size)
{
	int min = arr[0];
	int max = arr[0];

	for(int i = 1;i < size;++i)
	{
		if(arr[i] < min)
			min = arr[i];
		if(arr[i] > max)
			max = arr[i];
	}

	int range = max - min + 1;
	int* count = new int[range];

	for(int i = 0;i < size;++i)
	{
		count[arr[i] - min]++;
	}

	int index = 0;
	for(int i = 0;i < range;i++)
	{
		while(count[i] != 0)
		{
			arr[index++] = i + min;
			count[i]--;
		}
	}
}

void test()
{
	int arr[] = {5,2,9,6,1,8,7,0,4,3};
	//int arr[] = {5,2,9};
	int size = sizeof(arr)/sizeof(arr[0]);

	CountSort(arr,size);

	for(int i = 0;i < size;++i)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}

基数排序

“test.cpp”

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

//求数中最大数的位数
int GetMaxDigit(int* arr,int size)
{
	int base = 10;
	int digit = 1;
	for(int i = 0;i < size;++i)
	{
		while(arr[i] >= base)
		{
			base *= 10;
			++digit;
		}
	}

	return digit;
}

void NewCountSort(int* arr,int size)
{
	int digit = GetMaxDigit(arr,size);
	int base = 1;
	int* tmp = new int[size];

	while(digit--)
	{
		vector<int> count(10);//0-9
		for(int i = 0;i < size;++i)
		{
			int num = (arr[i] / base) % 10;
			count[num]++;
		}

		vector<int> start(10);
		for(int i = 1;i < 10;++i)
			start[i] = start[i-1] + count[i-1];
		
		for(int i = 0;i < size;++i)
		{
			int num = (arr[i] / base) % 10;
			//对各个数字进行排序(快速转置的方法)
			tmp[start[num]++] = arr[i];
		}
		//拷贝数值回数组里
		for(int i = 0;i < size;++i)
		{
			arr[i] = tmp[i];
		}
		//由低位向高位排序
		base *= 10;
	}
	delete[] tmp;
}
void test()
{
	int arr[] = {4,7,2,0,9,3,6,1,8,5};
	int size = sizeof(arr)/sizeof(arr[0]);

	NewCountSort(arr,size);

	for(int i = 0;i < size;++i)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	test();
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值