归并排序的个人学习记录

《原创博文,欢迎转载,欢迎交流学习》
归并排序真的挺令人痛苦的,也许是本人天资驽钝,在阅读了大量的解释,说明才有一点点的理解,在这里抛砖引玉,希望大家多多指点,也给刚接触此算法的初学者一点点的启发,如能对你有所帮助,对我则是莫大的鼓励。
好了,让我们回归正题:
1,什么是归并排序?
这个问题的答案,百度会告诉我们。归并排序,“归”可以理解为递归,但难点是“并“。
”并“即是‘合并’之意。连起来解释就是,”递分解,归合并“,意思是,在函数往下传递的时候,数组分解,在函数回归之时按顺序合并。
2.算法复杂度
简单点来理解下,是O=nlog2N,是比较优秀的排序算法,相对与冒泡、插入等n2的来说,要快很多倍,
举个例子,数据为10000个,没错是一万个,比较少的数据,
归并排序的次数为10000*log2 10000=132877,13万次多
再看下冒泡:
10000*10000=1亿次
这就是算法的魅力。
3,代码:
此处我使用C语言编写两种归并排序的算法:
第一种是大家非常常见的算法;
 C Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include 
#include  

void  merge( int  *a, int  left, int  right, int  *temp){
    
int  l=left;              //左边数组索引变量
     int  mid=(left+right)/ 2 ;    //数组中间值
     int  r=mid+ 1 ;             //右边数组索引变量
     int  i= 0 ;                 //temp[i],为插入temp的位置
     while (l<=mid && r<=right){   //初始循环条件,不确定左右哪个数组先完全进入temp
         if (a[l]<=a[r]){          //此处为升序,若为降序,修改符号即可
            temp[i++]=a[l++]; //当左边的值小时,把左边值插入到temp[i]中,并且i和l自增1
        } else {
            temp[i++]=a[r++];
//当右边的值小时,把右边的值插入到temp[i]中,并且i和r自增1
        }
    }
    
//运行至此,可以知道 l<=mid 和 r<=right 肯定有一个不符合了
       //  但我们不能确定是哪一个,所以我们采用一种“宁教我负天下人,休教天下人负我”的策略
         //也可以理解为‘宁可错杀一千,不可放过一个’

    
while (l<=mid){   //此处时:万一左边数据没排完,还剩下一些呢
        temp[i++]=a[l++];
    }
    
while (r<=right){   //此处时:万一右边还剩下一些宝贝呢,把他放进temp【】中吧
        temp[i++]=a[r++];
    }
    
//到这里,我们可以确定,数据已经完全进入temp了,但是我们要把数据移到a中
     for (l= 0 ;l//为甚要用i作为结束标志? 因为只有i可以确定我们到底给temp装了多少个数据,只有i才知道temp到底经历了些什么
        a[left+l]=temp[l];//此处意思为 数组a 从left 开始接受数据,直到temp的尽头
    }

}
void merge_sort(int *a,int left,int right,int *temp){
    
if(left
        
//****************递分解******
        int mid=(left+right)/2;//找到中间值
        merge_sort(a,left,mid,temp); //将左半边数组排好
        merge_sort(a,mid+1,right,temp);//将右边数组排好

        
//**************归合并**********
        merge(a,left,right,temp);//将两个排好序的数组合并
    }

}
void sort(int *a,int n){
    
int *temp=(int*)malloc(sizeof(int)*n);//用来存储合并的数组
    merge_sort(a,0,n-1,temp);
}

int main()
{

    
int n,*a,i;               //n 为读入一个数组长度,a为动态数组,i为循环数
    scanf("%d",&n);         //读取一个数字,作为数组长度
    a=(int*)malloc(sizeof(int)*n);//申请n个 int 空间
    for(i=0;i
        a[i]=(
int)(rand()%100);//给数组a 进行随机赋值[0,99]之间的整数
    }

    
//*排序吧,少年!
    sort(a,n);

    
//*输出吧,少年!
    for(i=0;i
        printf(
"%d\t",a[i]);
    }
    
//*是不是很厉害,少年!
    return 0;
}
 C Code 
第二种是比较拗口的,希望大家仔细写一遍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include  
#include  
void  merge_sort( int  *a, int  left, int  right, int  *temp){
    
if (left
        
//****************递分解
        merge_sort(a,left,mid,temp);  //将左半边数组排好
        merge_sort(a,mid+ 1 ,right,temp); //将右边数组排好

        
//**************归合并
         int  l=left;          //这里就不解释了
         int  r=mid+ 1 ;
        
int  i=left;
        
while (l<=mid || r<=right){   //这里用的是 或 ,意思是 左边和右边都必须出界才结束,就是说左右两边的数据必须全部进入
             if (l<=mid &&(r>right || a[l]//这个判断条件是最拗口的一个了;
                                                //这样理解:如果我们想把左边的数据放入temp 需要满足怎样的条件
                                                //显然:1.必须没有越界即 l<=mid
                                                //      2.要么右边越界(即右边数据全部进入temp,而左边还有剩余)即 r>right,要么左边的数据小于右边 a[l]
                temp[i++]=a[l++];

            }
else {
                temp[i++]=a[r++];
            }
        }
        
for (l=left;l
            a[l]=temp[l];
        }
    }
}
void sort(int *a,int n){
    
int *temp=(int*)malloc(sizeof(int)*n);//用来存储合并的数组
    merge_sort(a,0,n-1,temp);
}

int main()
{

    
int n,*a,i;               //n 为读入一个数组长度,a为动态数组,i为循环数
    scanf("%d",&n);         //读取一个数字,作为数组长度
    a=(int*)malloc(sizeof(int)*n);//申请n个 int 空间
    for(i=0;i
        a[i]=(
int)(rand()%100);//给数组a 进行随机赋值[0,99]之间的整数
    }

    
//*排序吧,少年!
    sort(a,n);

    
//*输出吧,少年!
    for(i=0;i
        printf(
"%d\t",a[i]);
    }
    
//*是不是很厉害,少年!
    return 0;
}

你可能感兴趣的:(数据结构与算法)