王道C语言督学营(数据结构) 第八部分

8.2 插入排序

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<string.h>
typedef int ElemType;
typedef struct {
	ElemType* elem;//整型指针
	int TableLen;
}SSTable;

void ST_Init(SSTable& ST, int len)
{
	ST.TableLen = len + 1;//实际申请11个元素的空间
	ST.elem = (ElemType*)malloc(sizeof(ElemType) * ST.TableLen);
	int i;
	srand(time(NULL));
	for (i = 0; i < ST.TableLen; i++)
	{
		ST.elem[i] = rand() % 100;//随机了11个数,但是第一个元素是没有用到的
	}
}
void ST_print(SSTable ST)
{
	for (int i = 0; i < ST.TableLen; i++)
	{
		printf("%3d", ST.elem[i]);
	}
	printf("\n");
}
//插入排序,从小到大排序,升序
void InsertSort(ElemType A[], int n)
{
	int i, j;
	//24 66 94  2 15 74 28 51 22 18  2
	for (i = 2; i <= n; i++)//第零个元素是哨兵,从第二个元素开始拿,往前面插入
	{
		if (A[i] < A[i - 1])
		{
			A[0] = A[i];//放到暂存位置,A[0]即是暂存,也是哨兵
			for (j = i - 1; A[0] < A[j]; --j)//移动元素,内层循环控制有序序列中的每一个元素和要插入的元素比较
				A[j + 1] = A[j];
			A[j + 1] = A[0];//把暂存元素插入到对应位置
		}
	}
}
//折半查找 插入排序
void MidInsertSort(ElemType A[], int n)
{
	int i, j, low, high, mid;
	for (i = 2; i <= n; i++)
	{
		A[0] = A[i];
		low = 1; high = i - 1;//low有序序列的开始,high有序序列的最后
		while (low <= high)//先通过二分查找找到待插入位置
		{
			mid = (low + high) / 2;
			if (A[mid] > A[0])
				high = mid - 1;
			else
				low = mid + 1;
		}
		for (j = i - 1; j >= high + 1; --j)
			A[j + 1] = A[j];
		A[high + 1] = A[0];
	}
}
//希尔排序  
//多轮插入排序,考的概率很低,因为编写起来复杂,同时效率并不如快排,堆排
void ShellSort(ElemType A[], int n)
{
	int dk, i, j;
	// 73 29 74 51 29 90 37 48 72 54 83
	for (dk = n / 2; dk >= 1; dk = dk / 2)//步长变化小题
	{
		for (i = dk + 1; i <= n; ++i)//以dk为步长进行插入排序 有哨兵的操作
		{
			if (A[i] < A[i - dk])
			{
				A[0] = A[i];
				for (j = i - dk; j > 0 && A[0] < A[j]; j = j - dk)
					A[j + dk] = A[j];
				A[j + dk] = A[0];
			}
		}
	}
}

int main()
{
	SSTable ST;
	ElemType A[10] = { 64,94,95,79,69,84,18,22,12,78 };
	ST_Init(ST, 10);//实际申请了11个元素空间
	memcpy(ST.elem+1, A, sizeof(A));
	ST_print(ST);
	InsertSort(ST.elem, 10);
	//MidInsertSort(ST.elem,10);
	//ShellSort(ST.elem,10);
	ST_print(ST);
	return 0;
}

8.3 交换排序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include<string.h>
typedef int ElemType;
typedef struct {
	ElemType* elem;//存储元素的起始地址
	int TableLen;//元素个数
}SSTable;
void ST_Init(SSTable& ST, int len)
{
	ST.TableLen = len;
	ST.elem = (ElemType*)malloc(sizeof(ElemType) * ST.TableLen);
	int i;
	srand(time(NULL));//随机数生成,每一次执行代码就会得到随机的10个数
	for (i = 0; i < ST.TableLen; i++)
	{
		ST.elem[i] = rand() % 100;//生成的范围是0-99
	}
}
void ST_print(SSTable ST)
{
	for (int i = 0; i < ST.TableLen; i++)
	{
		printf("%3d", ST.elem[i]);
	}
	printf("\n");
}
void swap(ElemType& a, ElemType& b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
void BubbleSort(ElemType A[], int n)
{
	int i,j,flag;
	for (i = 0; i < n - 1; i++)
	{	 flag=0;
		for (j = n-1; j >i; j--)
		{
			if (A[j - 1] > A[j])
			{
				swap(A[j-1], A[j ]);
				flag = 1;
			}
		}
		if (0 == flag)
			break;
	}
}
// 64 94 95 79 69 84 18 22 12 78
// 挖坑法
//比64小的放在左边,比64大的放在右边
//int Partition(ElemType A[],int low,int high)
//{
//	ElemType pivot=A[low];//把最左边的值暂存起来
//	while(low<high)
//	{
//		while(low<high&&A[high]>=pivot)
//			--high;
//		A[low]=A[high];
//		while(low<high&&A[low]<=pivot)
//			++low;
//		A[high]=A[low];
//	}
//	A[low]=pivot;
//	return low;
//}
//交换法
int Partition(int *arr,int left,int right)
{
	int k, i;//k记录要放入比分割值小的数据的位置
	for (k = i = left; i < right; i++)
	{
		if (arr[i] < arr[right])
		{
			swap(arr[i], arr[k]);
			k++;
		}
	}
	swap(arr[k], arr[right]);
	return k;
}
void QuickSort(ElemType A[], int low, int high)
{
	if (low < high)
	{
		int pivotpos = Partition(A, low, high);//分割点左边的元素都比分割点要小,右边的比分割点
		QuickSort(A, low, pivotpos - 1);
		QuickSort(A, pivotpos + 1, high);
	}
}

//折半查找 插入排序,考的很少
void MidInsertSort(ElemType A[],int n)
{
	int i,j,low,high,mid;
	for(i=2;i<=n;i++)
	{
		A[0]=A[i];
		low=1;high=i-1;//low有序序列的开始,high有序序列的最后
		while(low<=high)//先通过二分查找找到待插入位置
		{
			mid=(low+high)/2;
			if(A[mid]>A[0])
				high=mid-1;
			else
				low=mid+1;
		}
		for(j=i-1;j>=high+1;--j)
			A[j+1]=A[j];
		A[high+1]=A[0];
	}
}

int main()
{
	SSTable ST;
	ElemType A[10] = { 64,78,43,21,56,88,76,54,32,12 };
	ST_Init(ST, 10);//初始化
	//memcyp可以降低测试难度,让数据固定下来,排序算法写好后,注释memcpy对应代码即可
	//memcpy(ST.elem, A, sizeof(A));//内存copy接口,当你copy整型数组,或者浮点型时,要用memcpy
	ST_print(ST);
	//BubbleSort(ST.elem, 10);
	QuickSort(ST.elem, 0, 9);
	ST_print(ST);
	return 0;
}

8.4 选择类排序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include<string.h>
typedef int ElemType;
typedef struct {
	ElemType* elem;//存储元素的起始地址
	int TableLen;//元素个数
}SSTable;
void ST_Init(SSTable& ST, int len)
{
	ST.TableLen = len;
	ST.elem = (ElemType*)malloc(sizeof(ElemType) * ST.TableLen);
	int i;
	srand(time(NULL));//随机数生成,每一次执行代码就会得到随机的10个数
	for (i = 0; i < ST.TableLen; i++)
	{
		ST.elem[i] = rand() % 100;//生成的范围是0-99
	}
}
void ST_print(SSTable ST)
{
	for (int i = 0; i < ST.TableLen; i++)
	{
		printf("%3d", ST.elem[i]);
	}
	printf("\n");
}
void swap(ElemType& a, ElemType& b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
void BubbleSort(ElemType A[], int n)
{
	int i,j,flag;
	for (i = 0; i < n - 1; i++)
	{	 flag=0;
		for (j = n-1; j >i; j--)
		{
			if (A[j - 1] > A[j])
			{
				swap(A[j-1], A[j ]);
				flag = 1;
			}
		}
		if (0 == flag)
			break;
	}
}
// 64 94 95 79 69 84 18 22 12 78
// 挖坑法
//比64小的放在左边,比64大的放在右边
//int Partition(ElemType A[],int low,int high)
//{
//	ElemType pivot=A[low];//把最左边的值暂存起来
//	while(low<high)
//	{
//		while(low<high&&A[high]>=pivot)
//			--high;
//		A[low]=A[high];
//		while(low<high&&A[low]<=pivot)
//			++low;
//		A[high]=A[low];
//	}
//	A[low]=pivot;
//	return low;
//}
//交换法
int Partition(int *arr,int left,int right)
{
	int k, i;//k记录要放入比分割值小的数据的位置
	for (k = i = left; i < right; i++)
	{
		if (arr[i] < arr[right])
		{
			swap(arr[i], arr[k]);
			k++;
		}
	}
	swap(arr[k], arr[right]);
	return k;
}
void QuickSort(ElemType A[], int low, int high)
{
	if (low < high)
	{
		int pivotpos = Partition(A, low, high);//分割点左边的元素都比分割点要小,右边的比分割点
		QuickSort(A, low, pivotpos - 1);
		QuickSort(A, pivotpos + 1, high);
	}
}

//折半查找 插入排序,考的很少
void MidInsertSort(ElemType A[],int n)
{
	int i,j,low,high,mid;
	for(i=2;i<=n;i++)
	{
		A[0]=A[i];
		low=1;high=i-1;//low有序序列的开始,high有序序列的最后
		while(low<=high)//先通过二分查找找到待插入位置
		{
			mid=(low+high)/2;
			if(A[mid]>A[0])
				high=mid-1;
			else
				low=mid+1;
		}
		for(j=i-1;j>=high+1;--j)
			A[j+1]=A[j];
		A[high+1]=A[0];
	}
}

int main()
{
	SSTable ST;
	ElemType A[10] = { 64,78,43,21,56,88,76,54,32,12 };
	ST_Init(ST, 10);//初始化
	//memcyp可以降低测试难度,让数据固定下来,排序算法写好后,注释memcpy对应代码即可
	//memcpy(ST.elem, A, sizeof(A));//内存copy接口,当你copy整型数组,或者浮点型时,要用memcpy
	ST_print(ST);
	//BubbleSort(ST.elem, 10);
	QuickSort(ST.elem, 0, 9);
	ST_print(ST);
	return 0;
}

8.5 归并排序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include<string.h>
#define N 7
typedef  int ElemType;
void Merge(ElemType A[], int low, int mid, int high)
{
	int B[N];//为了降低操作次数
	int i, j, k;
	for (i = 0; i < N; i++)
		B[i] = A[i];
	//合并两个有序数组
	for (i = low, j = mid + 1, k =i; i <= mid && j <= high;k++)
	{
		if (B[i] <= B[j])
			A[k] = B[i++];
		else
			A[k] = B[j++];
	}
	//如果有剩余元素,接着放入
	while (i <= mid)
		A[k++] = B[i++];
	while (j <= high)
		A[k++] = B[j++];
}
//归并排序不限制是两两归并,还是多个归并
//1 3 5 7 9
//2 4
//1 2 3 4 5 7 9主要的代码逻辑
void MergeSort(ElemType A[],int low,int high)
{
	if (low < high)
	{
		int mid = (low + high) / 2;
		MergeSort(A, low, mid);
		MergeSort(A, mid + 1, high);
		Merge(A, low, mid, high);
	}
}
void print(int* a)
{
	for (int i = 0; i < N; i++)
	{
		printf("%3d", a[i]);
	}
	printf("\n");
}
int main()
{
	int A[7] = { 49,38,65,97,76,13,27 };
	MergeSort(A, 0, 6);//传下标
	print(A);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值