常見幾種排序演算法的C++描述
首先看一下幾種常見排序的特性
插入排序
void insertSort(vector<int> & arr)
{
int sz = arr.size();
int tmp;
for (int i = 1; i < sz; ++i){
tmp = arr[i];
int j;
for (j = i; j > 0 && tmp < arr[j - 1]; j--)
arr[j] = arr[j - 1];
arr[j] = tmp;
}
}
快速排序
//注意如果採取的是三數中值分割法的時候需要,將頭,中,尾的三個值中間的轉移到陣列的頭部。這樣來進行partition
void quickSort(vector<int> & arr, int start, int end)
{
if (start >= end)
return;
int pivot = getPartion(arr, start, end);
quickSort(arr, start, pivot - 1);
quickSort(arr, pivot + 1, end);
}
void bubbleSort(vector<int> & arr)
{
int sz = arr.size();
for (int i = sz - 1; i > 0; --i){
for (int j = 0; j < i; ++j){ //邊界需要注意一下
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j+1]);
}
}
}
希爾排序
void shellSort(vector<int> & arr)
{
int sz = arr.size();
for (int gap = sz / 2; gap > 0; gap /= 2){
int tmp;
for (int i = gap; i < sz; ++i){//每次和保證自己同樣的間隔組中資料是有序的,然後再使用插入排序的思想
tmp = arr[i];
int j;
for (j = i; j >= gap && tmp < arr[j - gap]; j -= gap){
arr[j] = arr[j - gap];
}
arr[j] = tmp;
}
}
}
堆排序
int up(int i){
return (i - 1) / 2; //堆節點從0開始計算
}
int down(int i){
return i * 2 + 1; //左節點
}
//新增資料用
void minHeapFixUp(vector<int> & arr, int i)//i代表插入的位置
{
int j = up(i);
int tmp = arr[i];
while (j >= 0 && i != 0){
if (arr[j] <= arr[i])
break; //停止調整
arr[i] = arr[j];
i = j;
j = up(i);
}
arr[i] = tmp;
}
//刪除資料用,實際上是通過刪除操作來調整堆
void minHeapFixDown(vector<int> & arr, int i, int n)
{
int tmp = arr[i];
int j = down(i);
while (j < n){
if (j + 1 < n && arr[j] > arr[j + 1])
j++;
if (tmp <= arr[j])
break;
arr[i] = arr[j];
i = j;
j = down(j);
}
arr[i] = tmp;
}
void makeHeap(vector<int> & arr)
{
int sz = arr.size();
//從sz/2 - 1開始建堆的目的是因為對於堆來說,有sz/2 + 1個節點是葉子節點,
//由於其左右不存在子節點,不需要向下調整,所以從非葉子節點開始向下調整
for (int i = sz / 2 - 1; i >= 0; --i){
minHeapFixDown(arr, i, sz);
}
}
void heapSort(vector<int> & arr)//最小堆得到降序排序
{
int sz = arr.size();
makeHeap(arr);
for (int i = sz - 1; i > 0; --i){
swap(arr[0], arr[i]); //得到最小的一個數
minHeapFixDown(arr, 0, i);
}
}
歸併排序
void merge(vector<int> & arr, vector<int> & copy, int start, int mid, int end)
{
int p = start, q = mid + 1, i = start;
while (p <= mid && q <= end){
if (arr[p] < arr[q])
copy[i++] = arr[p++];
else
copy[i++] = arr[q++];
}
while (p <= mid)
copy[i++] = arr[p++];
while (q <= end)
copy[i++] = arr[q++];
while (start <= end){
arr[start] = copy[start];
start++; //注意這裡一定要分開寫 而不要合在一起,容易加兩次出錯
}
}
void mergeSort(vector<int> & arr, vector<int> & copy, int start, int end)
{
if (start < end){
int mid = (start + end) >> 1;
mergeSort(arr, copy, start, mid);
mergeSort(arr, copy, mid + 1, end);
merge(arr, copy, start, mid, end);
}
}
void mergeSort(vector<int> & arr)
{
vector<int> copy(arr);
int sz = arr.size();
int mid = sz / 2;
mergeSort(arr, copy, 0, mid);
mergeSort(arr, copy, mid + 1, sz - 1);
merge(arr, copy, 0, mid, sz - 1);
}
直接選擇排序
void selectSort(vector<int> & vec){
int sz = vec.size();
int minPos;
for (int i = 0; i < sz - 1; ++i){
minPos = i;
for (int j = i + 1; j < sz; ++j){
if (vec[j] < vec[minPos])
minPos = j;
}
swap(vec[i], vec[minPos]);
}
}
基數排序
- 分別按照個位,十位,百位。。。來進行桶排序,得到最終結果就是正確的結果
public class RadixSort {
// 獲取x這個數的d位數上的數字
// 比如獲取123的1位數,結果返回3
public int getDigit(int x, int d) {
int a[] = {
1, 1, 10, 100
}; // 本例項中的最大數是百位數,所以只要到100就可以了
return ((x / a[d]) % 10);
}
public void radixSort(int[] list, int begin, int end, int digit) {
final int radix = 10; // 基數
int i = 0, j = 0;
int[] count = new int[radix]; // 存放各個桶的資料統計個數
int[] bucket = new int[end - begin + 1];
// 按照從低位到高位的順序執行排序過程
for (int d = 1; d <= digit; d++) {
// 置空各個桶的資料統計
for (i = 0; i < radix; i++) {
count[i] = 0;
}
// 統計各個桶將要裝入的資料個數
for (i = begin; i <= end; i++) {
j = getDigit(list[i], d);
count[j]++;
}
// count[i]表示第i個桶的右邊界索引
for (i = 1; i < radix; i++) {
count[i] = count[i] + count[i - 1];
}
// 將資料依次裝入桶中
// 這裡要從右向左掃描,保證排序穩定性
for (i = end; i >= begin; i--) {
j = getDigit(list[i], d); // 求出關鍵碼的第k位的數字, 例如:576的第3位是5
bucket[count[j] - 1] = list[i]; // 放入對應的桶中,count[j]-1是第j個桶的右邊界索引
count[j]--; // 對應桶的裝入資料索引減一
}
// 將已分配好的桶中資料再倒出來,此時已是對應當前位數有序的表
for (i = begin, j = 0; i <= end; i++, j++) {
list[i] = bucket[j];
}
}
}
public int[] sort(int[] list) {
radixSort(list, 0, list.length - 1, 3);
return list;
}
// 列印完整序列
public void printAll(int[] list) {
for (int value : list) {
System.out.print(value + "\t");
}
System.out.println();
}
public static void main(String[] args) {
int[] array = {
50, 123, 543, 187, 49, 30, 0, 2, 11, 100
};
RadixSort radix = new RadixSort();
System.out.print("排序前:\t\t");
radix.printAll(array);
radix.sort(array);
System.out.print("排序後:\t\t");
radix.printAll(array);
}
}
相關推薦
常見幾種排序演算法的C++描述
首先看一下幾種常見排序的特性 插入排序 void insertSort(vector<int> & arr) { int sz = arr.size();
常見的幾種排序演算法(java和C++版)(參考《演算法》)
博主這裡要講的幾種排序演算法包括(從難到易):1.氣泡排序(最low的演算法) 2.插入排序 3.希爾排序 4.歸併排序 5.快速排序 6.快速排序的三項切分 氣泡排序: (1)簡介:這是最原始,最簡單的排序,幾乎不需要額外的空間 (2)基本原理:通過迴圈將最大的元素移到
11. 常見的有哪幾種排序演算法,試比較其時間複雜度,以及是否穩定,及各自使用的情形
1、幾種常見排序演算法的時間複雜度 排序方法 平均情況 最好情況 最壞情況 直接插入排序 O(n2) O(n) O(n2) 起泡排序 O(n2) O(n) O(n2) 快速排序 O(nlog2n) O(nlog2n)
Java常見的幾種排序演算法-插入、選擇、冒泡、快排、堆排等
本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括:插入排序、選擇排序、氣泡排序、快速排序(重點)、堆排序、歸併排序等等。看下圖: 給定陣
常見的幾種排序演算法-插入、選擇、冒泡、快排、堆排等
作者:egg 郵箱:[email protected] 本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括
Java之常見的幾種排序演算法-插入、選擇、冒泡、快排、堆排等 .
本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括:插入排序、選擇排序、氣泡排序、快速排序(重點)、堆排序、歸併排序等等。看下圖: 給定陣
Java之常見的幾種排序演算法-插入、選擇、冒泡、快排、堆排等
Java面試寶典系列之基礎排序演算法 作者:egg 郵箱:[email protected] 本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自
Java 常見的幾種排序演算法-插入、選擇、冒泡、快排、堆排等
本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括:插入排序、選擇排序、氣泡排序、快速排序(重點)、堆排序、歸併排序等等。看下圖:
隨機生成100個數,利用幾種排序演算法對其實現排序(C++)
#include<iostream> #include<cstdlib> #include<ctime> using namespace std; //交換 template<class T> void Swap(T &a,T &b) {
C++ 幾種排序演算法詳解
排序的演算法有很多種,其關鍵在於根據待排序序列的特性選擇合適的排序方式。下面將介紹不同的排序方式。 基本排序演算法 基本排序演算法主要包括插入排序,快速排序,氣泡排序等三種排序方式,下面將對這三種排序演算法分別進行分析 插入排序 假定待排序陣列序列為:data[5,2
幾種排序演算法,記錄一下
個人也就會四種排序(bubble,select,insert,quick),哈哈,看官大人可能有點失望。自己也看過幾種,不過一直沒寫過其他的,就記錄下這四種吧。 程式碼均可直接通過編譯。各種版本實現都有出入,不過思想都是一樣。工作這麼久還沒有一次性完全寫正確過,功力還是差點。 #includ
5 種排序演算法--C語言連結串列
原始碼地址 GitHub:https://github.com/GYT0313/C-DataStructure/blob/master/sortIn5.c 包括: 氣泡排序 快速排序 選擇排序 插入排序 希爾排序 執行: 注意:
【python資料結構與演算法】幾種排序演算法:氣泡排序、快速排序
以下排序演算法,預設的排序結果是從小到大。 一.氣泡排序: 1.氣泡排序思想:越大的元素,就像越大的氣泡。最大的氣泡才能夠浮到最高的位置。 具體來說,即,氣泡排序有兩層迴圈,外層迴圈控制每一輪排序中操作元素的個數——氣泡排序每一輪都會找到遍歷到的元素的最大值,並把它放在最後,下一輪排序時
總結幾種排序演算法的Java實現
1、氣泡排序 氣泡排序是一種交換排序,它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。 Java程式碼: import java.util.Random; public class BubbleSort { /** * 改進的氣
幾種排序演算法
本文轉載自碼農網:http://www.codeceo.com/article/10-sort-algorithm-interview.html#0-tsina-1-10490-397232819ff9a47a7b7e80a40613cfe1 查詢和排
幾種排序演算法的Python形式
直接見程式碼吧,因為比較簡單 依次為 冒泡 選擇 快排 插入 歸併 堆排 桶排 class Sort: def bubble(self, nums): for i
自我整理:幾種排序演算法的理解
簡單來自己做個筆記,溫故一下排序方法。 1.直接排序 顧名思義,直接排,怎麼直接排,每次迴圈找出最下的扔到第一個,或者找到最大的扔到最後一個,剩下的數字,繼續迴圈找最小的往前扔,暴力排完。簡單粗暴,居家
【資料結構】十一種排序演算法C++實現
練習了十一種排序演算法的C++實現:以下依次為,冒泡、選擇、希爾、插入、二路歸併、快排、堆排序、計數排序、基數排序、桶排序,可建立sort.h和main.cpp將程式碼放入即可執行。如有錯誤,請指出更正,謝謝交流。 // sort.h # include <
幾種排序演算法java實現
沒有配圖,過幾天補上 package com.sort; public class Sort { /** * 插入排序 * 原理:往有序的子陣列選擇一個合適的位置插進去 * */ public void insertSort(int sort[
幾種排序演算法實現以及穩定性
穩定性演算法:氣泡排序、插入排序、歸併排序、基數排序 不穩定性演算法:選擇排序、快速排序、堆排序、希爾排序、桶排序 /** * * @author huangsen * 插入排序:一個有序陣列,一個無序陣列,將無序陣列插入到有序陣列中 * */ public