八大内部排序算法

6 篇文章 0 订阅
3 篇文章 0 订阅

八大内部排序包括:

插入排序:

直接插入排序

希尔排序(又称增量排序)

选择排序:

简单选择排序

堆排序

交换排序:

冒泡排序

快速排序

归并排序

基数排序(又称桶排序)

 

排序算法解析:

1、 直接插入排序与希尔排序

直接排序与希尔排序同属于插入排序,不一样的是,直接排序每次将tmp元素与前面所有的元素进行比较,直到到第一个元素或者当前元素不大于tmp;而希尔排序每次讲tmp元素与前面每隔增量个元素进行比较,直到第一个元素或者当前元素不大于tmp。

直接插入排序代码如下:

void InsertSort( elemtype *arr, int num )
{
	//判断传进来的参数是否满足条件
	if( arr == NULL )
		cerr << EMPTY_ARRAY;
	else if( num <= 0 )
		cerr << WRONG_ARRAY_CNT;

	if( num == 1 )//只有一个元素,直接返回
		return;

	elemtype tmp;
	for( int idx = 1; idx < num; idx++ )
	{
		tmp = arr[idx];
		int i;
		//判断并移动元素
		for( i = idx-1; i >=0 && tmp < arr[i] ; --i )
				arr[i+1] = arr[i];
		arr[i+1] = tmp;
	}
	
}

希尔排序代码如下:

void ShellPass( elemtype*, int, int );

void ShellSort( elemtype *arr, int num )
{
	int increment = 5 ;
	while( increment > 0 )
	{
		ShellPass( arr, num, increment );
		increment /= 2;
	}

}

void ShellPass( elemtype *arr, int num, int incre )
{
	elemtype tmp;

	for( int i = incre; i < num; i++ )
	{
		int j = i - incre;
		tmp = arr[i];
		while( j >= 0 && arr[j] > tmp )
		{
			arr[j + incre] = arr[j];
			j -= incre;
		}
		//if( j != i - incre )//存在比arr[i]小的数,这个实际上加不加都是可以的
			arr[j + incre] = tmp;
	}

}


2、 选择排序

选择排序每次选择剩下未排序的所有元素中最小的元素。

简单排序每次需要表里剩下的所有元素以获得最小元素,堆排序只需要构建一个最小堆,每次获得堆得根节点,并调整二叉堆即可。

具体简单选择排序代码如下:

int FindMin( elemtype *, int, int);

void ChooseSort( elemtype *arr, int num )
{
	//判断传进来的参数是否满足条件
	if( arr == NULL )
		cerr << EMPTY_ARRAY;
	else if( num <= 0 )
		cerr << WRONG_ARRAY_CNT;

	if( num == 1 )//只有一个元素,直接返回
		return;

	elemtype tmp;
	for( int i = 0; i < num-1; ++i )
	{
		int min_elem_pos = FindMin( arr, i, num );

		tmp = arr[min_elem_pos];
		arr[min_elem_pos] = arr[i];
		arr[i] = tmp;
	}

}

int FindMin( elemtype *arr, int start, int end )
{
	if( start > end )
		cerr << "Parameter error";

	int min_pos = start;
	elemtype min = arr[start];
	for( int i = start + 1; i < end; ++ i )
	{
		if( min > arr[i] )
		{
			min = arr[i];
			min_pos = i;
		}
	}
	return min_pos;
}


堆排序算法(暂定)

 

3、 交换排序

交换排序包括冒泡排序与快速排序。

冒泡排序可以设置一个哨兵判断一个交换过程是否发生交换,如果没有发生交换,说明剩下的数据已经排好序了。

快速排序最重要的是Partition过程,该过程中的i位置表示第i个位置之前的所有元素都小于tmp, j表示遍历到的位置。

冒泡排序代码如下:

void BubbleSort( elemtype *arr, int num )
{
	//判断传进来的参数是否满足条件
	if( arr == NULL )
		cerr << EMPTY_ARRAY;
	else if( num <= 0 )
		cerr << WRONG_ARRAY_CNT;

	if( num == 1 )//只有一个元素,直接返回
		return;
	
	elemtype tmp;
	bool flag = TRUE;//作为旗帜,判断某一轮是否有交换,如果没有交换,那么排序结束
	for( int cnt = 1; cnt < num && flag; ++cnt )//只要排列前面num-1个元素即可
	{
		flag = FALSE;
		for( int j = num-1; j >= cnt; j-- )
		{
			if( arr[j-1] > arr[j] )//发生交换
			{
				tmp = arr[j-1];
				arr[j-1] = arr[j];
				arr[j] = tmp;
				flag = TRUE;
			}
		}

	}
}

快速排序代码如下:

int Partition( elemtype *, int, int );
//void Exchange(elemtype *, elemtype * );

//在pre < end的前提下进行排序的
void QuickSort( elemtype *arr, int pre,int end )
{
	if( pre < end )
	{
		int i = Partition( arr, pre, end );

		QuickSort( arr, pre, i-1 );
		QuickSort( arr, i+1, end );
	}


}


//快排最重要的部分, i表示最后一个比tmp小的元素的方位, j表示遍历方位
int Partition( elemtype *arr, int begin, int end)
{
	elemtype tmp = arr[end];
	int i = begin-1;
	for( int j = begin; j < end; ++j )
	{
		if( arr[j] <= tmp )
		{
			++i;
			elemtype t;
			t = arr[i];
			arr[i] = arr[j];
			arr[j] = t;

		}
	}
	elemtype t;
	t = arr[i+1];
	arr[i+1] = arr[end];
	arr[end] = t;
	return i+1;
}


4、 归并排序

归并排序是典型的二分法(分治法)排序算法,首先将两个子序列分别排好序,然后合并上述已经排好序的两个子序列,在这里需要开辟一个数组,以便在合并两个排好序的子序列的时候排序,接着把排好序的元素复制到原始数组中。

归并排序代码如下:

elemtype tmparr[MAX_SIZE];//申请一个全局数组,保存交换后的数据

void Merge( elemtype*, int , int, int );//合并数组

void MergeSort( elemtype *arr, int first, int  end )
{
	if( first == end )//临界条件,数组中是剩下一个元素
		return;
	int mid = ( first + end ) / 2;
	MergeSort( arr, first, mid );
	MergeSort( arr, mid + 1, end );
	Merge( arr, first, mid, end );
}

void Merge( elemtype *arr, int first, int mid, int end )
{
	int i = first;
	int j = mid + 1;
	int t = first;
	while( i <= mid && j <= end )
	{
		if( arr[i] <= arr[j] )
		{
			tmparr[t++] = arr[i++];
		}
		else
		{
			tmparr[t++] = arr[j++];
		}
	}
	
	while( i <= mid )
		tmparr[t++] = arr[i++];
	while( j <= end )
		tmparr[t++] = arr[j++];

	for( int k = first; k <=end; ++k )
		arr[k] = tmparr[k];
}


5、 基数排序(暂定)

 

         

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值