数据结构(C语言版) 直接插入排序

直接插入排序示例:

此处以数据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

a[0]

下标 0 1 2 3 4 5 6
数据 2 1 3 4 4 5 6
遍历位置 j i

a[0]

下标 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语言版) 课本代码风格,使用抽象数据类型。

项目结构

在这里插入图片描述

status.h

#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, ...);//求一组数中的最小值

ststus.cpp

#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;
}

SequenceListType.h

#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))

SequenceListType.cpp

#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];
	}
}

data.txt

第一个数表示顺序表数据个数,后面的数据为实际的待排序数据

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;
}

数据结构(C语言版) 直接插入排序_第1张图片

你可能感兴趣的:(数据结构C语言版)