排序算法学习总结

一.冒泡排序
简单来说就是两两比较,把大的数换到后面,小的数换到前面,一轮比较后,最大的数就排到了最后面,
总共要比较n-1轮,冒泡排序是一种稳定排序算法,即使两个数相等,也不会破坏它们原有位置。
二.快速排序
简单来说就是选定一个基准值,一般选取最后一个数为基准值,然后定义两个参数start,end,
start从第一位开始扫描,end从最后一位开始扫描(包括基准值),如果start找到比基准值大的数,end找到比基准值小的数,就把两个位置交换一下,直到start与end相等,把start位置上的数与基准值相交换,这样左边的数都比基准值小,右边的数都比基准值大,然后递归(0,start-1),(start+1,end)。
三.选择排序
从第一位开始扫描一轮数组,找到最小值的位置,把最小值和第一位位置互换,然后从第二位开始扫描一轮数组,同样找到最小值,然后和第二位互换…可以看出这是一个递归,递归终止条件就是当扫描开始的位置start等于end。
四.插入排序
简单来说就是把第一位看成已经排好的有序数组,从第二位开始,每一次都把即将进入有序数组的数和前面的有序数组进行比较,找到insert place,比如(data[],start,end),data表示要排序的数组,在这个数组里面,data[0]到data[start-1]都是排好的,data[start]到data[end]都是未排好顺序的。那么insert place就属于0到start,找到后,把data[start]插入insert place 处,后面的数依次向后移动一个位置。熟悉递归的应该也能看出这个也可以用递归实现,递归终止条件就是start>end。
五.归并排序
归并排序就是讲求一个先“”分“,后“合”,每次都把数组分成两部分,一次次分下去直到,各个部分只有一个元素,再两两合并排序,所以“分”的思想就是divide(data[],first,last)---->Merge(data[],first,mid),Merge(data[],mid+1,last).“合”的思想combine(int data[],int first,int mid,int last)
分别扫描左半部分和右半部分:first->mid mid+1->last,两两比较,把小的数放到一个新的数组中去。中间必然会出现两部分之间会有一部分正好分配完毕(也就是没有元素了),那么这时候就把剩下部分整个打包粘贴到新数组后面。
六.全排列
总的来说非常简单的一个思路,(char* str,int first ,int last),first也就是第一个元素,last也就是最后一个元素,然后举个例子123,首先确定第一个位置的元素就是1,2,3这三种可能,怎么实现的呢?就是把第一个字母依次和第一,第二,第三个元素换一下位置,你肯定会疑问为什么要和自己互换呢?这不是多此一举吗?其实关键在于下一步的递归,我们传进去的是(str,first+1,last),所以如果没有那个和自己互换的话,那么23子串永远也不可能会进入递归,记得递归完,要恢复原状.然后递归终止条件就是当first==last,那么就可以直接输出str啦。
七.代码

#include <stdlib.h>
#include <stdio.h>
#include<string.h>
void quicksort(int data[], int start, int end);//快排
void choosesort(int data[], int start, int end);//选择排序
void insertsort(int data[], int start, int end);//插入排序
void Merge(int data[], int first, int mid, int last);
void Mergesort(int data[], unsigned int first, unsigned last);//归并排序
void Allarrange(char* str,int,int);
void swap(int&a, int&b)//交换两个数
{
	int temp = a;
	a = b;
	b = temp;
}
int main() 
{
	int nums[10] = { 8,8,8,8,8,8,8,8,8,8 };
	Mergesort(nums, 0, 9);//测试各个排序算法,直接改名字就够了
	for (int i = 0; i < 10; ++i)
		printf("%d ", nums[i]);
    /*char str[] = "abcd";
	Allarrange(str,0,3);*/
	return 0;
}
void quicksort(int data[], int start, int end)
{
	while (start>end)//递归终止条件
	{
		return;
	}
	int pivor = end;
	while (start<end)
	{
		while (data[start] <= data[pivor] && start < end)//必须要有start<end,假如没有,举一个例子1,1,1,1,1,1,1这样的输入序列会造成start越界
		{
			++start;
		}
		while (data[end] >= data[pivor] && start < end)
		{
			--end;
		}
		if (start < end)
		{
			swap(data[start], data[end]);
		}
	}
	swap(data[start], data[pivor]);
	quicksort(data, 0, start - 1);//递归左半部分
	quicksort(data, start + 1, pivor);//递归右半部分
}
void choosesort(int data[], int start, int end)
{
	if (start == end)//递归终止条件
		return;
	int min_index = start;
	for (int i = start;i <= end; ++i)
	{
		if (data[i] < data[min_index])
			min_index = i;//找出最小数的下标
	}
	swap(data[start], data[min_index]);
	choosesort(data, start + 1, end);//把排好的数除外,继续递归排序
}
void insertsort(int data[], int start, int end)//start和end表示无序序列,0->start-1表示有序
{
	if (start>end)//递归终止条件
		return;
	int index = data[start];//要插入的数
	int insertplace = start;//要插入的位置,如果这个数最大,直接就可以放在start位置上
	for (int i = 0; i <=start-1; ++i)
	{
		if (index < data[i])
		{
			insertplace = i;
			break;
		}
	}
	if (insertplace != start)//有位置可以放入,先把前面的都向后移动一格,空出位置放进去
	{
		for (int j = start - 1; j >= insertplace; --j)
		{
			data[j + 1] = data[j];
		}
		data[insertplace] = index;
	}
	++start;//必须要有,不然下面递归会出错
	insertsort(data, start, end);
}
void Merge(int data[], int first, int mid, int last)
{
	int i,k ;
	int*tmp = (int*)malloc((last - first + 1) * sizeof(int));//申请了一个新的数组
	int left_low = first;
	int left_high = mid;
	int right_low = mid + 1;
	int right_high = last;
	for ( i = 0; left_low <= left_high && right_low <= right_high; ++i)//合的思想
	{
		if (data[left_low] < data[right_low])
		{
			tmp[i] = data[left_low++];
		}
		else
			tmp[i] = data[right_low++];
	}
	if (left_low <= left_high)
	{
		for (k= left_low; k<= left_high; ++k)
			tmp[i++] = data[k];
	}
	if (right_low <= right_high)
	{
		for (k = right_low; k<= right_high; ++k)
			tmp[i++] = data[k];
	}
	for (k = 0; k <= last-first; ++k)
		data[first+k] = tmp[k];
	free(tmp);//释放内存,要注意
	return;

}
void Mergesort(int data[], unsigned int first, unsigned last)
{
	if (first >= last)
		return;
	unsigned int mid = (first + last)/2;
	Mergesort(data, first, mid);//分成小部分
	Mergesort(data, mid + 1, last);
	Merge(data, first, mid, last);//分好后在排序,合起来
	return;
}
void Allarrange(char* str,int first,int last)
{
	if (first == last)
	{
		printf("%s\n", str);
		
	}
	else
	{
		for (int i = first; i <=last; i++)
		{
			int temp = str[first];
			str[first] = str[i];
			str[i] = temp;
			//printf("%c", str[first]);
			Allarrange(str,first+1, last);
			temp = str[first];
			str[first] = str[i];
			str[i] = temp;
		}
	}
	return;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值