此处以数据2的排序为例,用i从左到右遍历到下标为5的位置,发现此处的值2小于前一位的值5
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 1 | 3 | 4 | 5 | 2 | 6 | |
遍历位置 | i |
将2放到缓存0的位置,然后数据5后移,j从i的前两位即下标3开始遍历
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 3 | 4 | 5 | 5 | 6 |
遍历位置 | j | i |
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 3 | 4 | 4 | 5 | 6 |
遍历位置 | j | i |
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 3 | 3 | 4 | 5 | 6 |
遍历位置 | j | i |
a[0]>a[j],a[j+1]=a[0]
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 2 | 3 | 4 | 5 | 6 |
遍历位置 | j | i |
此时就完成了数据2的排序
说明:本博客的代码实现贴近数据结构(C语言版) 课本代码风格,使用抽象数据类型。
#pragma once
#include
#include
#include
#define TRUE 1 //真
#define FALSE 0 //假
#define YES 1 //是
#define NO 0 //否
#define OK 1 //通过
#define ERROR 0 //错误
#define SUCCESS 1 //成功
#define INFEASIBLE -1 //不可行
//#define OVERFLOW -2 //堆栈上溢
//#define UNDERFLOW -3 //堆栈下溢
#define PAUSE system("pause") //暂停
typedef int Status; //函数类型,其值为状态码
typedef int DataType; //抽象数据类型
DataType max(int num1, ...);//求一组数中的最大值
DataType min(int num1, ...);//求一组数中的最小值
#include"status.h"
/************************************
* 函数名称: max
* 函数说明:求一组数最大值
* 编写人员:Zipay Yu
* 编写日期:2019/08/02
* 返回类型: DataType 输入数据个数
* 函数参数: int n 输入数据个数
* 函数参数: ...
*************************************/
DataType max(int n, ...)
{
int i = 0;
DataType maxNumber = 0;
va_list arg;
va_start(arg, n);
for (i = 0; i < n; i++)
{
int val = va_arg(arg, DataType);
if (i == 0) maxNumber = val;
if(maxNumber < val ) maxNumber = val;
}
va_end(arg);
return maxNumber;
}
/************************************
* 函数名称: min
* 函数说明:求一组数最小值
* 编写人员:Zipay Yu
* 编写日期:2019/08/02
* 返回类型: DataType
* 函数参数: int n 输入数据个数
* 函数参数: ...
*************************************/
DataType min(int n, ...)
{
int i = 0;
DataType minNumber = 0;
va_list arg;
va_start(arg, n);
for (i = 0; i < n; i++)
{
int val = va_arg(arg, DataType);
if (i == 0) minNumber = val;
if (minNumber < val) minNumber = val;
}
va_end(arg);
return minNumber;
}
#pragma once
#include "status.h"
#define MAXSIZE 20 //顺序表最大长度
typedef int KeyType; //定义关键字类型为int
typedef int InfoType; //定义其他数据项为int
typedef struct {
KeyType key; //关键字项
InfoType otherinfo; //其他数据项
}RedType; //记录类型
typedef struct {
RedType r[MAXSIZE + 1]; //r[0]闲置或用作缓存单元
int length; //顺序表长度
}SqList; //顺序表类型
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#include "SequenceListType.h"
#pragma warning(disable : 4996)
/************************************
* 函数名称: CreateSortList
* 函数说明: 读取文件初始化顺序表
* 编写人员: Zipay Yu
* 编写日期: 2019/08/02
* 返回类型: Status
* 函数参数: SqList & L
*************************************/
Status CreateSortList(SqList &L) {
FILE *fpRead = fopen("data.txt", "r");
if (fpRead == NULL)
{
return ERROR;
}
fscanf(fpRead, "%d", &L.length); //读取数据个数
if (L.length > MAXSIZE) return ERROR;
for (int i = 1; i <= L.length; i++)
{
fscanf(fpRead, "%d", &L.r[i].key);//将待排序数据存入顺序表
}
fclose(fpRead);
return OK;
}
/************************************
* 函数名称: Print
* 函数说明: 打印输出结构体
* 编写人员: Zipay Yu
* 编写日期: 2019/08/02
* 返回类型: void
* 函数参数: SqList & L
*************************************/
void Print(SqList &L) {
printf("[length:%d key:", L.length);
for (int i = 1; i <= L.length; i++)
{
printf("%d ", L.r[i].key);
}
printf("]\n");
}
/************************************
* 函数名称: Swap
* 函数说明: 交换顺序表L的两个元素
* 编写人员: Zipay Yu
* 编写日期: 2019/08/11
* 返回类型: void
* 函数参数: SqList & L 顺序表
* 函数参数: int index1 下标1
* 函数参数: int index2 下标2
*************************************/
void Swap(SqList &L, int index1, int index2) {
RcdType temp = L.r[index1];
L.r[index1] = L.r[index2];
L.r[index2] = temp;
}
本部分以课本给出的代码进行实现
/************************************
* 函数名称: InsertSort
* 函数说明: 直接插入排序
* 编写人员: Zipay Yu
* 编写日期: 2019/08/02
* 返回类型: void
* 函数参数: SqList & L
*************************************/
void InsertSort(SqList &L) {
int i, j;
for (i = 2; i <= L.length; i++)
{
if (LT(L.r[i].key, L.r[i - 1].key)) { //比较相邻元素大小,后者小于前者则继续
L.r[0] = L.r[i]; //小者存入缓存
L.r[i] = L.r[i - 1]; //大者后移
for (j = i - 2; LT(L.r[0].key, L.r[j].key); --j)//比较a[i]小于a[i-2],
{
L.r[j + 1] = L.r[j]; //a[i-2]后移到a[i-1]
}
L.r[j + 1] = L.r[0];
}
}
}
此部分针对方式一的代码进行了一些简化,使用while循环实现时更容易理解操作过程
void InsertSort(SqList &L) {
int i, j;
for (i = 2; i <= L.length; i++)
{
L.r[0] = L.r[i];
j = i - 1;
while (L.r[0].key < L.r[j].key) {
L.r[j + 1] = L.r[j];
j--;
}
L.r[j + 1] = L.r[0];
}
}
第一个数表示顺序表数据个数,后面的数据为实际的待排序数据
8 49 38 65 97 76 13 27 49
int main() {
SqList L;
CreateSortList(L); //初始化数据
Print(L); //输出初始数据
InsertSort(L); //执行排序
Print(L); //输出排序后数据
system("pause");
return 0;
}