我要好offer之 排序算法大总结
1. 插入排序
(1) 直接插入排序
void StraightInsertionSort(std::vector<int>& num) {
    if (num.size() ==  || num.size() == ) return;
    for (int i = ; i < num.size(); ++i) {
        int tmp = num.at(i);
        int j = i - ;
        for (; j >=  && num.at(j) > tmp; --j) {
            num.at(j + ) = num.at(j);
        }
        num.at(j + ) = tmp;
    }
}
(2) 折半插入排序
void BinaryInsertionSort(std::vector<int>& num) {
    if (num.size() ==  || num.size() == ) return;
    for (int i = ; i < num.size(); ++i) {
        int tmp = num.at(i);
        int first = ;   // 最终的first值即为插入位置
        int last = i - ;
        while (first <= last) {
            int mid = first + (last - first) / ;
            if (num.at(mid) < tmp) {
                first = mid + ;
            } else if (num.at(mid) > tmp) {
                last = mid - ;
            } else {
                first = mid;
                break;
            }
        }
        for (int t = i - ; t >= first; --t) {
            num.at(t + ) = num.at(t);
        }
        num.at(first) = tmp;
    }
}
2. 希尔排序
void ShellSort(std::vector<int>& num) {
    if (num.size() ==  || num.size() == ) return;
    for (int gap = num.size() / ; gap > ; gap /= ) {
        for (int i = gap; i < num.size(); ++i) {
            for (int j = i - gap; j >=  && num.at(j) > num.at(j + gap); j -= gap) {
                std::swap(num.at(j), num.at(j + gap));
            }
        }
    }
}
3. 冒泡排序
void BubbleSort(std::vector<int>& num) {
    if (num.size() ==  || num.size() == ) return;
    for (int i = ; i < num.size(); ++i) {
        for (int j = ; j < num.size() - i - ; ++j) {
            if (num.at(j) > num.at(j + )) {
                std::swap(num.at(j), num.at(j + ));
            }
        }
    }
}
4. 快速排序
(1) 递归版
// 划分
int Partition(std::vector<int>& num, int first, int last) {
assert(first >= && first < num.size() && last >= && last < num.size() && first <= last);
int mid = first + (last - first) / ;
std::swap(num.at(first), num.at(mid));
int pos = first;
for (int i = first; i <= last; ++i) {
if (num.at(i) < num.at(first)) {
std::swap(num.at(++pos), num.at(i));
}
}
std::swap(num.at(first), num.at(pos));
return pos;
} // 快速排序
void quickSort(std::vector<int>& num, int first, int last) {
if (first < last) {
int pivotPos = Partition(num, first, last);
quickSort(num, first, pivotPos - );
quickSort(num, pivotPos + , last);
}
} void QuickSort(std::vector<int>& num) {
quickSort(num, , num.size() - );
}
(2) 非递归版
int Partition(std::vector<int>& num, int first, int last) {
    assert(first >=  && first < num.size() && last >=  && last < num.size() && first <= last);
    int mid = first + (last - first) / ;
    std::swap(num.at(first), num.at(mid));
    int pos = first;
    for (int i = first; i <= last; ++i) {
        if (num.at(i) < num.at(first)) {
            std::swap(num.at(++pos), num.at(i));
        }
    }
    std::swap(num.at(first), num.at(pos));
    return pos;
}
void QuickSort(std::vector<int>& num, int first, int last) {
    if (first < last) {
        std::stack<int> stk;
        int pivotPos = Partition(num, first, last);
        if (first < pivotPos - ) {
            stk.push(first);
            stk.push(pivotPos - );
        }
        if (last > pivotPos + ) {
            stk.push(pivotPos + );
            stk.push(last);
        }
        while (!stk.empty()) {
            int right = stk.top();
            stk.pop();
            int left = stk.top();
            stk.pop();
            pivotPos = Partition(num, left, right);
            if (left < pivotPos - ) {
                stk.push(left);
                stk.push(pivotPos - );
            }
            if (right > pivotPos + ) {
                stk.push(pivotPos + );
                stk.push(right);
            }
        }
    }
}
5. 简单选择排序
void SimpleSelectSort(std::vector<int>& num) {
    if (num.size() ==  || num.size() == ) return;
    for (int i = ; i < num.size(); ++i) {
        for (int j = i + ; j < num.size(); ++j) {
            if (num.at(j) < num.at(i)) {
                std::swap(num.at(i), num.at(j));
            }
        }
    }
}
6. 堆排序
// 堆调整,注意结点编号kth从1开始
void HeapAdjust(std::vector<int>& num, int kth, int vecSize) {
int left = * kth;
int right = * kth + ;
int largest = INT_MIN;
if (left <= vecSize && num.at(left - ) > num.at(kth - )) {
largest = left;
} else {
largest = kth;
} if (right <= vecSize && num.at(right - ) > num.at(largest - )) {
largest = right;
}
if (largest != kth) {
std::swap(num.at(kth - ), num.at(largest - ));
HeapAdjust(num, largest, vecSize);
}
} // 建堆
void BuildHeap(std::vector<int>& num) {
for (int i = num.size() / ; i >= ; --i) {
HeapAdjust(num, i + , num.size());
}
} // 堆排序
void HeapSort(std::vector<int>& num) {
BuildHeap(num);
int vecSize = num.size();
while (vecSize > ) {
std::swap(num.at(), num.at(vecSize - ));
--vecSize;
HeapAdjust(num, , vecSize);
}
}
7. 归并排序
void merge(std::vector<int>& num, int first, int mid, int last) {
    std::vector<int> tmp(last - first + , );
    int i = first;
    int j = mid + ;
    int idx = ;
    while (i <= mid && j <= last) {
        if (num.at(i) <= num.at(j)) {
            tmp.at(idx++) = num.at(i++);
        } else {
            tmp.at(idx++) = num.at(j++);
        }
    }
    while (i <= mid) {
        tmp.at(idx++) = num.at(i++);
    }
    while (j <= last) {
        tmp.at(idx++) = num.at(j++);
    }
    for (int i = first; i <= last; ++i) {
        num.at(i) = tmp.at(i - first);
    }
}
void MergeSort(std::vector<int>& num, int first, int last) {
    if (first < last) {
        int mid = first + (last -first) / ;
        MergeSort(num, first, mid);
        MergeSort(num, mid + , last);
        merge(num, first, mid, last);
    }
}
8. 计数排序
void CountSort(std::vector<int>& num) {
    if (num.size() ==  || num.size() == ) return;
    int minVal = *(std::min_element(num.begin(), num.end()));
    int maxVal = *(std::max_element(num.begin(), num.end()));
    int valRange = maxVal - minVal + ;
    std::vector<int> count(valRange, );
    for (int i = ; i < num.size(); ++i) {
        count.at(num.at(i) - minVal)++;
    }
    for (int i = ; i < count.size(); ++i) {
        count.at(i) = count.at(i) + count.at(i - );
    }
    std::vector<int> tmp(num);
    for (int i = tmp.size() - ; i >= ; --i) {
        int lessNum = count.at(tmp.at(i) - minVal);
        num.at(lessNum - ) = tmp.at(i);
        count.at(tmp.at(i) - minVal)--;
    }
}
小结:

我要好offer之 排序算法大总结的更多相关文章
- 剑指offer 查找和排序的基本操作:查找排序算法大集合
		重点 查找算法着重掌握:顺序查找.二分查找.哈希表查找.二叉排序树查找. 排序算法着重掌握:冒泡排序.插入排序.归并排序.快速排序. 顺序查找 算法说明 顺序查找适合于存储结构为顺序存储或链接存储的线 ... 
- 排序算法大汇总  Java实现
		一.插入类算法 排序算法的稳定性:两个大小相等的元素排序前后的相对位置不变.{31,32,2} 排序后{2,31,32},则称排序算法稳定 通用类: public class Common { pub ... 
- 我要好offer之 系统基础大总结
		1. APUE Unix环境高级编程 (1) Unix基础知识: 内核->系统调用->shell和库函数->应用软件 (2) 文件I/O:read函数返回值.进程的文件描述符表.文件 ... 
- 我要好offer之 概率题大总结
		1. 利用等概率Rand5生成等概率Rand3 Rand5生成等概率Rand3 这个题目可以扩展为:利用等概率RandM生成等概率RandN (M > N) 这里,我们首先明白一个简单的知识点: ... 
- 排序算法大荟萃——希尔(Shell)排序算法
		1.基本思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组.所有距离为d1的倍数的记录放在同一个组中.先再各族中进行直接插入排序,然后取第二个增量d2<d1重复上述的分组 ... 
- 我要好offer之 字符串相关大总结
		1. str*系列手写代码 a. 一定要注意末尾'\0'的处理,切记切记 b. 一定要对输入做有效性判断,多用断言就是了 int Strlen(const char* str) { assert(st ... 
- C语言8大经典排序算法(2)
		二.插入类排序 插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止. 插入排序一般意义上有两 ... 
- 一文搞定十大经典排序算法(Java实现)
		本文总结十大经典排序算法及变形,并提供Java实现. 参考文章: 十大经典排序算法总结(Java语言实现) 快速排序算法—左右指针法,挖坑法,前后指针法,递归和非递归 快速排序及优化(三路划分等) 一 ... 
- 十大经典排序算法总结(JavaScript描述)
		前言 读者自行尝试可以想看源码戳这,博主在github建了个库,读者可以Clone下来本地尝试.此博文配合源码体验更棒哦~~~ 个人博客:Damonare的个人博客 原文地址:十大经典算法总结 这世界 ... 
随机推荐
- 动态代理--Cglib
			JDK 的Proxy 实现,需要代理对象实现接口: package com.utils; import java.lang.reflect.InvocationHandler; import java ... 
- JDBC连接数据库报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. ......
			问题:Java程序使用JDBC连接MySQL数据库时,控制台报错如下: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' ... 
- 判断是否是同一人的方法——equals()?在Person类中提供一个比较的方法compare()返回boolean值?对象自己和自己比?
			判断是否是同一人的方法——equals() 不能直接用per1==per2,这不是对象内容的比较而是存放对象地址的值得比较 在Person类中提供一个比较的方法compare()返回boolean值 ... 
- 【android】【转发】Android中PX、DP、SP的区别
			转载 http://blog.csdn.net/donkor_/article/details/77680042 前言: 众所周知,Android厂商非常多,各种尺寸的android手机.平板层出不穷 ... 
- 【mysql】【转发】Cannot proceed because system tables used by Event Scheduler were found damaged at server start
			本地:mac 10.12.3 mysql 5.6 远程:linux 7.3 mysql 5.7.18. (远程数据库yum安装,又5.6升级到5.7) 步骤:从本地数据库导出数据到远 ... 
- python3 发邮件 smtplib & email 库
			嗨 实现了用163发送到qq的功能,遗留了两个问题: 1. 接收者list会报错:update:因为list[]会传递过去一个真的[]list,改成如下就可以了: before: maillist=[ ... 
- makedown语法
			文章转载至:https://blog.csdn.net/u014061630/article/details/81359144#1-%E5%BF%AB%E6%8D%B7%E9%94%AE 前言 写过博 ... 
- drf 频率组件 META字典详情
			drf频率组件 什么是频率 控制用户对某个url的请求频率,比如一分钟之内,只能访问三次 自定义频率规则 1.取出访问者ip 2.判断当前ip在不在访问字典中: 不在,则添加进去,返回True; 3. ... 
- 笔记-python-centos环境下安装配置
			笔记-python-centos环境下安装配置 1. 准备工作 环境准备 centos6.5 mini,已有python 2.6.6 下载源码包 Python官网下载Gzipped sour ... 
- 百度地图的API接口----多地址查询和经纬度
			最近看了百度地图的API的接口,正想自己做点小东西,主要是多地址查询和经纬度坐标跟踪, 下面的代码直接另存为html就可以了,目前测试Chrome和360浏览器可以正常使用. <!DOCTYPE ... 
