8.2 插入排序
#include
#include
#include
#include
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
#include
#include
#include
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=pivot)
// --high;
// A[low]=A[high];
// while(lowA[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
#include
#include
#include
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=pivot)
// --high;
// A[low]=A[high];
// while(lowA[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
#include
#include
#include
#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;
}