当前位置:网站首页>Merge sort
Merge sort
2022-07-05 05:08:00 【ximen502_】
The content and code of this article come from the data structure textbook .
Merge sort (Merging Sort) Is another kind of different sorting method ." Merger " The meaning of will is 2 Or 2 More than ordered tables are combined into 1 New ordered table . Whether it is sequential storage or linked list storage structure , All available O(m+n) In terms of time . The basic idea of merging is as follows :
Suppose the initial sequence contains n A record , We can view it as n Two ordered subsequences , The length of each subsequence is 1, And then they merge , obtain ⌈ n 2 ⌉ \lceil \frac{n}{2} \rceil ⌈2n⌉ A length of 2 or 1 An ordered subsequence of ; And then we merge ,… …, repeat , All the way to a length of zero n The ordered sequence of , This sorting method is called 2- Path merging and sorting . Here's the picture
2- The core operation in path merging sorting is to merge two adjacent ordered sequences in a one-dimensional array into an ordered sequence .
java Realization
void merge(int[] sr, int[] tr, int i, int m, int n) {
if (i == n) {
// Processing of the last element of the array
tr[i] = sr[i];
return;
}
int k = 0;
int j = 0;
// take SR[i..m] and SR[m+1..n] Merge into ordered TR[i..n]
for (j = m + 1, k = i; i <= m && j <= n; ++k) {
if (sr[i] <= sr[j]) // take SR From small to large TR
tr[k] = sr[i++];
else
tr[k] = sr[j++];
}
if (i <= m) {
for (int u = i, q = 0; u <= m; u++) {
// Put the rest SR[i...m] Copied to the TR
tr[k + q] = sr[u];
++q;
}
}
if (j <= n) {
for (int u = j, q = 0; u <= n; u++) {
// Put the rest SR[j...n] Copied to the TR
tr[k + q] = sr[u];
++q;
}
}
}
int[] mergSort(int[] arr) {
int[] sr = arr;
int[] tr = new int[arr.length];
int h = 1, len = arr.length;
// It takes several times to merge , With 2 Bottom ,len The logarithm of is rounded up .
int count = (int) Math.ceil(log(len, 2));
for (int x = 0; x < count; x++) {
// In each trip , The number of groups that need to be merged ,len/2h The decimal obtained is rounded up .
int ceil = (int) Math.ceil((float) len / (2 * h));
for (int y = 0; y < ceil; y++) {
int i = y * 2 * h;
int m = i + h - 1;
int n = m + h;
n = n >= len ? n - 1 : n;// Subscript processing of the last element of the array
merge(sr, tr, i, m, n);
}
// Save the result of one sort to the original array
for (int z = 0; z < tr.length; z++) {
arr[z] = tr[z];
}
// Subsequence length modification
h *= 2;
}
return tr;
}
/** * Logarithmic method , This method uses the bottom changing formula in logarithm in mathematics to realize . * because JDK There is no request 2 Method of logarithm of base . * @param value * @param base * @return */
double log(double value, double base) {
return Math.log(value) / Math.log(base);
}
@Test
public void fun1(){
int[] arr = new int[] {
49, 38, 65, 97, 76, 13, 27 };
int[] tr = mergSort(arr);
System.out.println(Arrays.toString(tr));
}
The operation of merging and sorting is , call ⌈ n 2 h ⌉ \lceil \frac{n}{2h} \rceil ⌈2hn⌉(n/2h The decimal result after is rounded up , Such as 2.01 Rounded up to 3) Sub algorithm merge take SR[1…n] The middle is adjacent to the front and back and the length is h h h The ordered segments of are merged in pairs , Get adjacent before and after 、 The length is 2 h 2h 2h Ordered segment of , And stored in TR[1…n] in , The whole merging and sorting needs to be done ⌈ log 2 n ⌉ \lceil \log_2n \rceil ⌈log2n⌉ Trip to . so , The realization of merging and sorting requires a number of auxiliary spaces such as records to be arranged , So it's Spatial complexity by O(n), Its Time complexity by O(nlogn).
And Quick sort and Heap sort comparison , The biggest feature of merging and sorting is , It is a stable sorting method . Looks like Java JDK in Collections.sort(List); The method is to merge and sort or an improved version .
this 2 Mathematical library functions for calculating logarithms and rounding up are used in both language versions , By Math Classes and math.h The header file provides .
When calculating logarithms, there is an implementation method of using the bottom exchange formula of logarithms , The original mathematical formula is as follows :
about a , c ∈ ( 0 , 1 ) ∪ ( 1 , + ∞ ) a,c\in(0,1) \cup (1,+\infin) a,c∈(0,1)∪(1,+∞) And b ∈ ( 0 , + ∞ ) b\in(0,+\infin) b∈(0,+∞), Yes
log a b = log c b log c a \log_ab=\frac{\log_cb}{\log_ca} logab=logcalogcb
Here is C/C++ Implementation version of .
/* * Merge sort * data structure (C Language version ) YanWeiMin Wei-min wu * */
#include<iostream>
#include<math.h>
using namespace std;
/** * Logarithmic method * @param value * @param base * @return */
double logPlus(double value, double base) {
return log(value) / log(base);
}
void merge(int sr[], int tr[], int i, int m, int n) {
if (i == n) {
// Processing of the last element of the array
tr[i] = sr[i];
return;
}
int k = 0;
int j = 0;
// System.out.println(i+","+m+","+n);
for (j = m + 1, k = i; i <= m && j <= n; ++k) {
if (sr[i] <= sr[j]) {
tr[k] = sr[i++];
} else {
tr[k] = sr[j++];
}
}
if (i <= m) {
// Put the rest SR[i...m] Copied to the TR
for (int u = i, q = 0; u <= m; u++) {
tr[k + q] = sr[u];
++q;
}
}
if (j <= n) {
// Put the rest SR[j...n] Copied to the TR
for (int u = j, q = 0; u <= n; u++) {
tr[k + q] = sr[u];
++q;
}
}
}
int* mergSort(int arr[], int arrLength) {
int* sr = arr;
int* tr = new int[arrLength];// Allocate memory for array pointers , Otherwise, a segment error will be reported, and the core has been dumped
int h = 1, len = arrLength;
// It takes several times to merge , With 2 Bottom ,len The logarithm of is rounded up .
int count = (int) ceil(logPlus(len, 2));
for (int x = 0; x < count; x++) {
// In each trip , The number of groups that need to be merged ,len/2h The decimal obtained is rounded up .
int _ceil = (int) ceil((float) len / (2 * h));
for (int y = 0; y < _ceil; y++) {
int i = y * 2 * h;
int m = i + h - 1;
int n = m + h;
n = n >= len ? n - 1 : n;// Subscript processing of the last element of the array
merge(sr, tr, i, m, n);
}
// Save the result of one sort to the original array
for (int z = 0; z < arrLength; z++) {
arr[z] = tr[z];
}
// Subsequence length modification
h *= 2;
}
return tr;
}
int main(int argc, char* argv[]) {
int arr[] = {
49, 38, 65, 97, 76, 13, 27 };
int* tr = mergSort(arr, 7);
for(int i=0;i<7;i++){
cout<<tr[i]<<" ";
}
cout<<endl;
return 0;
}
Finally, there is a version of recursive implementation
The original pseudo code is as follows :
void MSort(RcdType SR[], RcdType &TR1[], int s, int t){
// take SR[s..t] The order of merging is TR1[s..t].
if(s == t) TR1[s]=SR[s];
else{
m = (s+t)/2;
MSort(SR, TR2,s,m);
MSort(SR, TR2,m+1,t);
Merge(TR2, TR1, s, m, t);
}
}// MSort
void MergeSort(SqList &L){
// For the sequence table L Merge and sort
MSortt(L.r, L.r, 1, L.length);
}//MergeSort
The above pseudocode has never been converted successfully , So I rewritten a version . This pseudo code means to split the array until there is 1 Individual elements , Then continue to merge in pairs , Keep going forward and backward , Until the final array is ordered . This recursive process is like the preorder traversal of a binary tree , Finally, return to , Form an ordered array , However, it this TR1,TR2 I really don't know what to say .
Rewrite as follows :
void mergeV2(int[] sr, int[] tr, int i, int m, int n) {
int k = 0;
int j = 0;
// take SR[i..m] and SR[m+1..n] Merge into ordered TR[i..n]
for (j = m + 1, k = i; i <= m && j <= n; ++k) {
if (sr[i] <= sr[j]) // take SR From small to large TR
tr[k] = sr[i++];
else
tr[k] = sr[j++];
}
if (i <= m) {
for (int u = i, q = 0; u <= m; u++) {
// Put the rest SR[i...m] Copied to the TR
tr[k + q] = sr[u];
++q;
}
}
if (j <= n) {
for (int u = j, q = 0; u <= n; u++) {
// Put the rest SR[j...n] Copied to the TR
tr[k + q] = sr[u];
++q;
}
}
}
// Recursive implementation , complete . It is slightly different from pseudo code
void MSortV2(int[] sr, int[] tr1, int s, int t) {
if (s == t) {
tr1[s] = sr[t];
} else {
int m = (s + t) / 2;
MSortV2(sr, tr1, s, m);
MSortV2(sr, tr1, m + 1, t);
mergeV2(sr, tr1, s, m, t);
for (int i = s; i <= t; i++) {
sr[i] = tr1[i];
}
}
}
@Test
public void fun3() {
int[] arr = new int[] {
49, 38, 65, 97, 76, 13, 27 };
int[] tr1 = new int[7];
MSortV2(arr, tr1, 0, arr.length - 1);
System.out.println(Arrays.toString(tr1));
}
边栏推荐
猜你喜欢
Rip notes [rip message security authentication, increase of rip interface measurement]
AutoCAD - feature matching
【论文笔记】Multi-Goal Reinforcement Learning: Challenging Robotics Environments and Request for Research
Unity get component
C4D simple cloth (version above R21)
"Measuring curve length" of CAD dream drawing
用 Jmeter 工具做个小型压力测试
AutoCAD - window zoom
Chinese notes of unit particle system particle effect
Detailed introduction of OSPF header message
随机推荐
Applet live + e-commerce, if you want to be a new retail e-commerce, use it!
Ue4/ue5 illusory engine, material chapter, texture, compression and memory compression and memory
【Leetcode】1352. Product of the last K numbers
嵌入式数据库开发编程(六)——C API
3dsmax common commands
3dsmax scanning function point connection drawing connection line
cocos2dx_ Lua card flip
MySQL audit log Archive
Autocad-- dynamic zoom
Lua determines whether the current time is the time of the day
Unity parallax infinite scrolling background
Use assimp library to read MTL file data
Embedded database development programming (V) -- DQL
Use of snippets in vscode (code template)
2022/7/1學習總結
Unity find the coordinates of a point on the circle
cocos_ Lua listview loads too much data
mysql審計日志歸檔
django连接数据库报错,这是什么原因
UE4/UE5 虚幻引擎,材质篇(三),不同距离的材质优化