数据结构---排序

数据结构—排序

    最近看了一个讲数据结构的视频(https://www.bilibili.com/read/cv3285768), 
觉很不错。完成了一些代码,在vs2017上运行通过(用自己写的输入),应该
还存在许多bug。(代码在下面,其中是直接交换的key(关键字的值),没有将数
据整体交换)

下面想写一些自己的理解。

  • 1直接插入排序
    在这里插入图片描述

  • 2折半插入排序
    在这里插入图片描述

  • 3希尔排序
    Hiooard增量序列:(2^k)-1
    在这里插入图片描述

  • 4冒泡排序(带检测哨兵bi)
    在这里插入图片描述

  • 5快速排序
    在这里插入图片描述

  • 6选择排序
    在这里插入图片描述

  • 7堆排序
    在这里插入图片描述

  • 8归并排序
    在这里插入图片描述

  • 9基数排序
    在这里插入图片描述
    . 以下是头文件(没有归并排序和基数排序)

#ifndef SORT_H
#define SORT_H

#include<cmath>

//定义
#define MAXSIZE 20
typedef int keyType;
typedef long InfoType;
typedef struct {
	keyType key;
	InfoType otherinfo;
}RedType;
typedef struct SqList {
	RedType r[MAXSIZE + 1];//r[0]作为哨兵或缓冲区
	int length= MAXSIZE + 1;
}SqList;

//直接插入排序
void InserSort(SqList& L,int L_length){
	for (int i = 2; i < L_length; ++i) {
		if (L.r[i].key< L.r[i-1].key) {//判断是否移动元素
			L.r[0].key = L.r[i].key;
			int j = i;
			for (j = i; L.r[j-1].key > L.r[0].key; --j) {
				L.r[j].key = L.r[j-1].key;
			}
			L.r[j].key = L.r[0].key;//将最后一位赋值
		}
		else;
	}
}

//折半插入排序
void BlnsertSort(SqList& L, int L_length) {
	for (int i = 2; i < L_length; ++i) {
		if (L.r[i].key < L.r[i-1].key) {
			L.r[0].key = L.r[i].key;
			int low = 1, high = i - 1, mid = (low + high) / 2;
			while (low <= high) {//用于找到小于等于下标i/0的下标mid
				mid = (low + high) / 2;
				if (L.r[mid].key <= L.r[0].key)
					low = mid + 1;
				else
					high = mid - 1;
			}
			for (int j = i; j > high; --j) {//移动
				L.r[j].key = L.r[j - 1].key;
			}
			L.r[high + 1].key = L.r[0].key;
		}
		else;//无需移动元素的情况
	}
}

//希尔排序
void ShellSort(SqList& L, int L_length) {
	//建立递增序列---dlta[]
	int i = 1;
	while (pow(2, i) - 1 < L_length-1) {
		++i;
	}
	--i;
	int* dlta=new int[i];
	for (int j = 0; j < i; ++j) {
		dlta[j] = pow(2, i - j) - 1;
	}
	//开始排序
	for (int j = 0; j < i; ++j) {//dlta中的元素都尝试一遍
		for (int k = 1 + dlta[j]; k < L_length; ++k) {
			if (L.r[k].key < L.r[k - dlta[j]].key) {
				L.r[0].key = L.r[k].key;
				int ii = k;
				for ( ii = k; (L.r[0].key < L.r[ii - dlta[j]].key)&&(ii-dlta[j]>0); ii -= dlta[j]) {//
					L.r[ii].key = L.r[ii - dlta[j]].key;
				}
				L.r[ii].key = L.r[0].key;
			}
			else;//无需进行移动
		}
	}
	delete dlta;//清除递增序列
}

//冒泡排序(带检测哨兵bi)
void bubble_Sort(SqList& L,int L_length) {
	int bi = 1;
	for (int i = L_length - 1;i>1&&bi==1; --i) {
		bi = 0;
		for (int j = 1;j<i; ++j) {
			if (L.r[j].key > L.r[j + 1].key) {//交换
				bi = 1;
				int t = L.r[j].key;
				L.r[j].key = L.r[j + 1].key;
				L.r[j + 1].key = t;
			}
		}
	}
}
//快速排序
//具体操作
int Partition(SqList& L, int low, int high) {
	int cen = L.r[low].key;
	L.r[0].key = cen;
	while (low < high) {
		while (L.r[high].key >= cen && low < high)
			--high;
		L.r[low].key = L.r[high].key;//其实不是只交换key,而是整体交换
		while (L.r[low].key < cen&&low < high)
			++low;
		L.r[high].key = L.r[low].key;//如果low==high 就是自己交换自己	
	}
	L.r[low].key = L.r[0].key;
	return low;
}
//总体结构
void QSort(SqList& L, int low, int high) {
	if (low < high) {//要有出口,不能写成while
		int cen = Partition(L, low, high);
		QSort(L, low, cen - 1);
		QSort(L, cen + 1, high);
	}
}

//选择排序
void SelectSort(SqList& L, int L_length) {
	for (int i = 1; i < L_length - 1; ++i) {
		int min = i;//用于记录这一趟最小的值
		for (int j = i; j < L_length; ++j) {
			if (L.r[j].key < L.r[min].key)
				min = j;
		}
		L.r[0].key = L.r[min].key;
		L.r[min].key = L.r[i].key;
		L.r[i].key = L.r[0].key;
	}
}
//堆排序
//筛选
void HeapAdjust(SqList& L, int s, int m) {
	//s为需要下移的结点的下标,
	//m为最后一个元素的结点的下标
	L.r[0].key = L.r[s].key;//保存上终极移动点
	int i = s * 2;
	int bi = 0;//用于检测是否发成了移动
	for (i = s * 2; i <= m; i *= 2) {
		if (L.r[i].key < L.r[0].key || (L.r[i + 1].key < L.r[0].key && i + 1 <= m)) {
			bi = 1;
			int j = 0;
			if (i + 1 > m) {
				if (L.r[i].key >= L.r[0].key)//不需要下移的情况
					break;
				else
					L.r[i / 2].key = L.r[i].key;
			}
			else if (L.r[i].key < L.r[i + 1].key) {
				L.r[i / 2].key = L.r[i].key;
			}
			else {//可以加条件“=”if
				L.r[i / 2].key = L.r[i + 1].key;
				i += 1;
			}
		}
		else//这是一个容易忘掉的地方
			break;
	}
	if (bi)
		L.r[i/2].key = L.r[0].key;
}
//堆排序(开始)
void HeapSort(SqList& L, int heap_length) {
	//建立堆(整理成堆)
	for (int i = heap_length / 2; i > 0; --i) {
		HeapAdjust(L, i, heap_length);
	}
	//整理
	for (int i = heap_length; i > 1; --i) {
		int t = L.r[1].key;
		L.r[1].key = L.r[i].key;
		L.r[i].key = t;
		HeapAdjust(L, 1, i - 1);
	}
}
#endif //SORT_H
  • 以下是源文件
#include"排序.h"

using namespace std;

int main() {
	SqList A;
	int A_length = sizeof(A.r)/sizeof(A.r[0]);
	//写入A
	A.r[1].key = 100;
	A.r[2].key = 55;
	A.r[3].key = 30;
	A.r[4].key = 16;
	A.r[5].key = 7;
	A.r[6].key = 32;
	A.r[7].key = 19;
	A.r[8].key = 23;
	A.r[9].key = 54;
	A.r[10].key = 29;
	A.r[11].key = 96;
	A.r[12].key = 44;
	A.r[13].key = 75;
	A.r[14].key = 8;
	A.r[15].key = 9;
	A.r[16].key = 10;
	A.r[17].key = 99;
	A.r[18].key = 33;
	A.r[19].key = 2;
	A.r[20].key = 91;
	//直接插入排序
	//InserSort(A,A_length);
	//折半插入排序
	//BlnsertSort(A, A_length);
	//希尔排序
	//ShellSort(A, A_length);
	//冒泡排序
	//bubble_Sort(A, A_length);
	//快速排序
	//QSort(A, 1, A_length-1);
	//简单选择排序
	//SelectSort(A, A_length);
	//堆排序
	//HeapSort(A,20);

	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值