您的位置:首页 > 理论基础 > 数据结构算法

数据结构---排序

2020-02-06 07:27 357 查看

数据结构—排序

最近看了一个讲数据结构的视频(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;
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
derma63 发布了4 篇原创文章 · 获赞 0 · 访问量 128 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: