数据结构|内部排序详细代码与深度解析

 

  • 内部排序分类

  • 插入类排序

    基本思想:在已排好序列的子集的基础上,将下一个待排记录插入到已排好序列的记录子集,直到将所有待排记录全部插入为止。

 

    直接插入排序:将每一个待排元素i插入到前i-1个排序好的序列中。将前i-1个元素依次比较,如果i小于则向后搬移,直到插入到i大于的位置。

void InSort(int* arr, int len)//未设立监视哨
{
	for(int i = 1; i < len; ++i)
	{
		int x = arr[i];
		int j = i-1;
		for(; j >= 0 && arr[j] > x; --j)
		{
			arr[j+1] = arr[j];
		}
		arr[j+1] = x;
	}
}

    折半插入排序基于直接插入排序,在对前i-1个元素中,使用折半查找,性能提高。

void BinSort(int arr[], int len)
{
	for(int i = 1; i < len; ++i)
	{
		int low = 0;
		int high = i-1;
		int x = arr[i];
		while(low <= high)
		{
			int mid = (high+low)>>1;
			if(x < arr[mid])
			{
				high = mid -1;
			}
			else
			{
				low = mid + 1;
			}
		}
		for(int j = i-1; j >= low; j--)
		{
			arr[j+1] = arr[j];
		}
		arr[low] = x;
	}
}

    希尔排序(缩小增量排序法):利用直接插入的最佳性质,将待排序列分为若干小段,对子序列进行直接插入排序。

void ShellInsert(int r[], int len, int delta)
{
	for(int i = delta; i < len; ++i)
	{
		int x = r[i];
		if(x < r[i-delta])
		{
			int j = i - delta;
			for(; j >= 0 && r[j] > x; j-=delta)
			{
				r[j+delta] = r[j];
			}
			r[j+delta] = x;
		}
	}
}
  • 交换类排序

基本思想:通过一系列交换逆元素进行排序的方法。

冒泡排序:通过相邻元素进行比较(升序:每一趟将最大元素换到每一趟末尾)逐步形成有序序列。

void BubbleSort(int *a, int len)
{
	for(int i = 0; i <len; ++i)
	{
		for(int j = 0; j < len-i-1; ++j)
		{
			if(a[j] > a[j+1])
			{
				int tmp = a[j];
				a[j] = a[j+1];
				a[j+1] = tmp;
			}
		}
	}
}

快速排序:在待排序列中选择一个记录,然后将大于该记录放右边,小于放左边,然后一次排左右两个待排序列,逐步成为一个有序序列。

int QuickSort(int *arr, int left, int right)
{
	int val = arr[left];
	for(int i = left; i < right; ++i)
	{
		while(left< right && arr[right] >= val)
			right--;
		if(left<right)
		{
			arr[left] = arr[right];
			left++;
		}
		while(left< right && arr[left] < val)
			left++;
		if(left<right)
		{
			arr[right] = arr[left];
			right--;
		}

	}
	arr[left] = val;
	return left;
}
void _QuickSort(int arr[], int left, int right)
{
	if(left >= right)
		return;
	int pos = QuickSort(arr, left, right);
	_QuickSort(arr, left, pos-1);
	_QuickSort(arr, pos+1,right);
}

 

  • 选择排序

基本思想:每一趟在n-i-1个记录中选择最小的记录放在i位置处。

简单选择排序:每一趟在n-i-1个记录中选择最小的记录放在i位置处。

void SelectSort(int arr[], int len)
{
	for(int i = 0; i < len; ++i)
	{
		int x = i;
		for(int j = i+1; j < len; j++)
		{
			if(arr[j] < arr[x])
			{
				x = j;
			}
		}
		swap(arr[i], arr[x]);
	}
}

树形选择排序(锦标赛排序):首先取得n个元素的关键码,进行两两比较,得到n/2(上取整)个比较的优胜者,作为
第一步比较的结果保留下来。然后对这n/2(上取整)个元素再进行关键码的两两比较,…,如此
重复,直到选出一个关键码最小的元素为止。

 

 

堆排序:

 a、把堆顶array[0]元素和当前最堆的最后一个元素交换;
 b、最大堆元素个数减1
 c、由于第1步后根节点不再满足最堆定义,向下调整跟结点。

 

  • 归并排序:

思想:将有序序列合并成新的有序序列,需要借助辅助空间。

 

void Merge(int arr[], int low, int mid, int high, int tmp[])
{
	int i = low, j = mid+1, k = low;
	while((i<mid)&&(j<high))
	{
		if(arr[i] < arr[j])
		{
			tmp[k++] = arr[i++];
		}
		else
		{
			tmp[k++] = arr[j++];
		}
	}
	while(i<=mid)
	{
		tmp[k++] = arr[i++];
	}
	while(j<=high)
	{
		tmp[k++] = arr[j++];
	}
}

void Msort(int arr[], int low, int high, int tmp[])
{
	int* a = (int*)malloc(4*(high-low+1));
	if(a == NULL)
		return;
	if(low == high)
	{
		tmp[low] = arr[low];
	}
	else
	{
		int mid = (low+high)/2;
		Msort(arr, low, mid, a);
		Msort(arr, mid+1, high, a);
		Merge(a, low, mid,high, tmp);
	}
	free(a);
}

 

 

 

最后:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BugGuys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值