網站首頁 編程語言 正文
前言
本期為大家帶來的是常見排序算法中的歸并排序,博主在這里先分享歸并排序的遞歸算法,包您一看就會,快來試試吧~
?一、歸并排序
1.1 基本思想
歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法 (Divide and Conquer)的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序 列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。
1.2 算法思想
到這里,我們可以得到一條結論,兩個有序的子序列可以合成一個新的有序子序列,通過遞歸,我們兩個新的有序序列也可以組成新的有序數列,最終實現排序的目的。有些朋友就會問了,這個我懂,關鍵是咋實現有序數列,其實非常的簡單,分割遞歸至每個子序列只有一個元素時,是不是就有序啦,然后就可以合成有兩個元素有序的列表嘛,再合成4個,8個……
1.3 程序設計思想
定義一個tmp數組,可以是動態開辟的(malloc),用于臨時存放合并后的有序數據,定義_MergeSort()函數,用于分解,合并數據(遞歸實現),參數有,待處理數組,數據區間(數組下標),tmp數組。
- 判斷區間是否存在,區間不存在以及只有一個元素的情況結束程序。
- 分割區間:mid=(left+right)/2;遞歸左右區間,分割遞歸至每個子序列只有一個元素。
- 每兩個子序列一組,循環遍歷每一個元素,if比較兩個子序列各元素的大小,取大或取小,放入tmp數組,tmp[index++]=子序列++;直到有一個子序列遍歷完,循環結束。
- 循環判斷是子序列是否遍歷完畢,未遍歷完畢的子序列剩余元素直接給到tmp數組。將tmp數組的對應的元素拷貝回原數組(已有序)。
1.4 程序實現
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>//動態開辟空間的函數的頭文件
void _MergeSort(int *a,int left,int right,int *tmp)
{
//區間不存在以及只有一個元素的情況結束程序
if (left>=right)
{
return;
}
int mid = (left + right) / 2;
//假設[left,mid],[mid+1,right]有序,那么我們就可以歸并了
//遞歸使左右區間有序
//分割遞歸至每個子序列只有一個元素
_MergeSort(a,left,mid,tmp);
_MergeSort(a, mid+1,right, tmp);
//歸并
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = left;
while (begin1<=end1&&begin2<=end2)//有一個子序列遍歷完,循環結束
{
if (a[begin1] < a[begin2])//升序,取小
{
tmp[index++] = a[begin1++];
}
else
{
tmp[index++] = a[begin2++];
}
}
//判斷子序列是否遍歷完,未遍歷完畢的子序列剩余元素直接給到tmp數組
while (begin1 <= end1)
{
tmp[index++] = a[begin1++];
}
while (begin2<=end2)
{
tmp[index++] = a[begin2++];
}
//拷貝回去
for (int i=left;i<=right;++i)
{
a[i] = tmp[i];
}
}
//歸并排序
void MergeSort(int *a,int n)
{
int* tmp=(int*)malloc(sizeof(int)*n);//動態開辟與待排序數組大小相等的一片連續的空間
_MergeSort(a,0,n-1,tmp);//子函數實現歸并
free(tmp);//釋放動態開辟的空間
}
//打印
void Print(int* a, int n)
{
for (int i=0;i<n;++i)
{
printf("%d ",a[i]);
}
}
int main()
{
int a[] = {10,6,7,1,3,9,4,2};
MergeSort(a,sizeof(a)/sizeof(a[0]));
Print(a,sizeof(a)/sizeof(a[0]));
return 0;
}
1.5 歸并排序的特性總結
- 1. 歸并的缺點在于需要O(N)的空間復雜度,歸并排序的思考更多的是解決在磁盤中的外排序問 題。
- 2. 時間復雜度:O(N*logN)
- 3. 空間復雜度:O(N)
- 4. 穩定性:穩定
原文鏈接:https://blog.csdn.net/weixin_67603503/article/details/125718908
相關推薦
- 2022-10-19 React封裝彈出框組件的方法_React
- 2022-08-11 如何利用python繪制等高線圖_python
- 2022-11-22 Android?10?啟動分析之init語法詳解_Android
- 2022-11-26 docker安裝portainer方法詳細步驟_docker
- 2022-10-22 python?中的?super詳解_python
- 2023-03-04 Python使用yaml模塊操作YAML文檔的方法_python
- 2022-03-08 c++實現超簡單的貪吃蛇游戲實例介紹_C 語言
- 2022-05-29 ASP.NET?Core在WebApi項目中使用Cookie_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支